[Python-Dev] Re: SC 2020 recommendation for PEP 634

2020-12-08 Thread Antoine Pitrou
On Mon, 7 Dec 2020 11:29:55 -0800
Brett Cannon  wrote:
> After much deliberation, the 2020 SC will be making a recommendation to the
> 2021 SC to accept PEP 634 (although this was not a unanimous decision).
> This is in no way a binding recommendation to the 2021 SC (even if a
> majority of current council members get re-elected), but we felt we should
> pass on our thoughts to the next council as we have been discussing pattern
> matching for a few months at this point and we promised we would make some
> decision to the PEP authors.

Perhaps you could also post the thought process which leads to this
recommendation, so that the future SC has more input on the matter?

Regards

Antoine.

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/FTXGXG6UEULVIU56WAYLBEWMX6ZBFKXA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: SC 2020 recommendation for PEP 634

2020-12-08 Thread David Mertz
As a candidate for the new SC, if elected I would certainly find it more
useful to have more specific thoughts from the outgoing SC than simply "we
recommend." How divided was the vote? Who took the sides? What were the
major points of disagreement? That sort of thing.

On Tue, Dec 8, 2020 at 9:39 AM Antoine Pitrou  wrote:

> On Mon, 7 Dec 2020 11:29:55 -0800
> Brett Cannon  wrote:
> > After much deliberation, the 2020 SC will be making a recommendation to
> the
> > 2021 SC to accept PEP 634 (although this was not a unanimous decision).
> > This is in no way a binding recommendation to the 2021 SC (even if a
> > majority of current council members get re-elected), but we felt we
> should
> > pass on our thoughts to the next council as we have been discussing
> pattern
> > matching for a few months at this point and we promised we would make
> some
> > decision to the PEP authors.
>
> Perhaps you could also post the thought process which leads to this
> recommendation, so that the future SC has more input on the matter?
>
> Regards
>
> Antoine.
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/FTXGXG6UEULVIU56WAYLBEWMX6ZBFKXA/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/RBDVJINV5KVIWSGO57CR7ENN2OG2VE3F/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: SC 2020 recommendation for PEP 634

2020-12-08 Thread Paul Moore
On Tue, 8 Dec 2020 at 15:19, David Mertz  wrote:
>
> As a candidate for the new SC, if elected I would certainly find it more 
> useful to have more specific thoughts from the outgoing SC than simply "we 
> recommend." How divided was the vote? Who took the sides? What were the major 
> points of disagreement? That sort of thing.

My understanding was that the outgoing SC would fully brief the new
SC. The mail here is simply a summary view for the information of the
wider python-dev community.

Personally, I'm not sure how I feel about it. It's very much a good
thing in terms of transparency, something the SC seems to still be
trying to find the right balance on, but I feel that having seen this,
I'd be left with a lot of unanswered questions if the incoming SC ends
up rejecting the proposal, and therefore I don't really know how to
view the information with that context.

Paul
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/KA3MJOZIKMJ3P2UCAYOJEGJASNF72GD5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: SC 2020 recommendation for PEP 634

2020-12-08 Thread Carol Willing
On Tue, Dec 8, 2020 at 7:32 AM Paul Moore  wrote:

> On Tue, 8 Dec 2020 at 15:19, David Mertz  wrote:
> >
> > As a candidate for the new SC, if elected I would certainly find it more
> useful to have more specific thoughts from the outgoing SC than simply "we
> recommend." How divided was the vote? Who took the sides? What were the
> major points of disagreement? That sort of thing.
>
> My understanding was that the outgoing SC would fully brief the new
> SC. The mail here is simply a summary view for the information of the
> wider python-dev community.
>

Paul, this is a good summary of why the SC posted its recommendation for
the incoming SC.


> Personally, I'm not sure how I feel about it. It's very much a good
> thing in terms of transparency, something the SC seems to still be
> trying to find the right balance on, but I feel that having seen this,
> I'd be left with a lot of unanswered questions if the incoming SC ends
> up rejecting the proposal, and therefore I don't really know how to
> view the information with that context.
>

That's a fair point. We expect to do a hand-off meeting with the new SC to
discuss. Although personally I would like to see a pattern matching
solution, we didn't have consensus within the existing SC for many of the
reasons already discussed in other posts. We felt it was best to give the
new SC an opportunity to make the decision.




> Paul
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/KA3MJOZIKMJ3P2UCAYOJEGJASNF72GD5/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/EBS45757GOISQO6S7JY47F35WJUPQDOF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] macOS issues with 3.8.7rc1

2020-12-08 Thread Gregory Szorc
Regarding the 3.8.7rc1 release, I wanted to raise some issues regarding
macOS.

Without the changes from https://github.com/python/cpython/pull/22855
backported, attempting to build a portable binary on macOS 11 (e.g. by
setting `MACOSX_DEPLOYMENT_TARGET=10.9`) results in a myriad of `warning:
'XXX' is only available on macOS 10.13 or newer
[-Wunguarded-availability-new]` warnings during the build. This warning
could be innocuous if there is run-time probing in place (the symbols in
question are weakly linked, which is good). But if I'm reading the code
correctly, run-time probing was introduced by commits like eee543722 and
isn't present in 3.8.7rc1.

I don't have a machine with older macOS sitting around to test, but I'm
fairly certain the lack of these patches means binaries built on macOS 11
will blow up at run-time when run on older macOS versions.

These same patches also taught CPython to build and run properly on Apple
ARM hardware. I suspect some people will care about these being backported
to 3.8.

I suspect people in the Python application packaging/distribution space
will be significantly affected by this (I know I am with PyOxidizer). Is it
worth making the backport of these patches a 3.8.7 release blocker or a
trigger for a special 3.8.8 release shortly thereafter?

Gregory
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/WX262O2BT2OCTOO5AGBP6JGUODLRV55D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] __future__ annotations loses closure scope

2020-12-08 Thread Paul Bryan
It appears that when from future import __annotations__, a type hint
annotation derived from a closure loses scope.

Simplistic example:

Python 3.9.0 (default, Oct  7 2020, 23:09:01) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def make_a_class(data_type):
... class Foo:
... def put_data(self, data: data_type):
... self.data = data
... return Foo
... 
>>> import typing
>>> foo = make_a_class(str)()
>>> typing.get_type_hints(foo.put_data)
{'data': }
>>> 

If I add a single import to the top, it breaks:

Python 3.9.0 (default, Oct  7 2020, 23:09:01) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import annotations  # added this line
>>> def make_a_class(data_type):
... class Foo:
... def put_data(self, data: data_type):
... self.data = data
... return Foo
... 
>>> import typing
>>> foo = make_a_class(str)()
>>> typing.get_type_hints(foo.put_data)
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
value = _eval_type(value, globalns, localns)
  File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
eval(self.__forward_code__, globalns, localns),
  File "", line 1, in 
NameError: name 'data_type' is not defined
>>> 

I don't see how I can supply the closure scope as localns to
get_type_hints. Any suggestions? Is constructing a (dynamically-type-
annotated) class in a function like this an anti-pattern?

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/5RK6VXF263F5I4CU7FUMOGOYN2UQG73Q/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Guido van Rossum
Yeah, static type checkers won't like it regardless.

On Tue, Dec 8, 2020 at 6:39 PM Paul Bryan  wrote:

> It appears that when from future import __annotations__, a type hint
> annotation derived from a closure loses scope.
>
> Simplistic example:
>
> Python 3.9.0 (default, Oct  7 2020, 23:09:01)
>
> [GCC 10.2.0] on linux
>
> Type "help", "copyright", "credits" or "license" for more information.
>
> >>> def make_a_class(data_type):
>
> ... class Foo:
>
> ... def put_data(self, data: data_type):
>
> ... self.data = data
>
> ... return Foo
>
> ...
>
> >>> import typing
>
> >>> foo = make_a_class(str)()
>
> >>> typing.get_type_hints(foo.put_data)
>
> {'data': }
>
> >>>
>
>
> If I add a single import to the top, it breaks:
>
> Python 3.9.0 (default, Oct  7 2020, 23:09:01)
>
> [GCC 10.2.0] on linux
>
> Type "help", "copyright", "credits" or "license" for more information.
>
> *>>> from __future__ import annotations  # added this line*
>
> >>> def make_a_class(data_type):
>
> ... class Foo:
>
> ... def put_data(self, data: data_type):
>
> ... self.data = data
>
> ... return Foo
>
> ...
>
> >>> import typing
>
> >>> foo = make_a_class(str)()
>
> >>> typing.get_type_hints(foo.put_data)
>
> Traceback (most recent call last):
>
>   File "", line 1, in 
>
>   File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
>
> value = _eval_type(value, globalns, localns)
>
>   File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
>
> return t._evaluate(globalns, localns, recursive_guard)
>
>   File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
>
> eval(self.__forward_code__, globalns, localns),
>
>   File "", line 1, in 
>
> NameError: name 'data_type' is not defined
>
> >>>
>
>
> I don't see how I can supply the closure scope as localns to
> get_type_hints. Any suggestions? Is constructing a
> (dynamically-type-annotated) class in a function like this an anti-pattern?
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/5RK6VXF263F5I4CU7FUMOGOYN2UQG73Q/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/NRH4HBD36WDIP4WR2L4TLTOYMQL2NUFV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Paul Bryan
Let's try an example that static type checkers should have no problem
with:

Python 3.9.0 (default, Oct  7 2020, 23:09:01) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import annotations
>>> 
>>> def make_a_class():
... class A:
... def get_b(self) -> B:
... return B()
... class B:
... def get_a(self) -> A:
... return A()
... return A
... 
>>> A = make_a_class()
>>> a = A()
>>> 
>>> import typing
>>> typing.get_type_hints(a.get_b)
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
value = _eval_type(value, globalns, localns)
  File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
eval(self.__forward_code__, globalns, localns),
  File "", line 1, in 
NameError: name 'B' is not defined
>>> 



On Tue, 2020-12-08 at 18:48 -0800, Guido van Rossum wrote:
> Yeah, static type checkers won't like it regardless.
> 
> On Tue, Dec 8, 2020 at 6:39 PM Paul Bryan  wrote:
> > It appears that when from future import __annotations__, a type
> > hint annotation derived from a closure loses scope.
> > 
> > Simplistic example:
> > 
> > Python 3.9.0 (default, Oct 7 2020, 23:09:01) 
> > [GCC 10.2.0] on linux
> > Type "help", "copyright", "credits" or "license" for more
> > information.
> > >>> def make_a_class(data_type):
> > ... class Foo:
> > ... def put_data(self, data: data_type):
> > ... self.data = data
> > ... return Foo
> > ... 
> > >>> import typing
> > >>> foo = make_a_class(str)()
> > >>> typing.get_type_hints(foo.put_data)
> > {'data': }
> > >>> 
> > 
> > 
> > If I add a single import to the top, it breaks:
> > 
> > Python 3.9.0 (default, Oct 7 2020, 23:09:01) 
> > [GCC 10.2.0] on linux
> > Type "help", "copyright", "credits" or "license" for more
> > information.
> > >>> from __future__ import annotations # added this line
> > >>> def make_a_class(data_type):
> > ... class Foo:
> > ... def put_data(self, data: data_type):
> > ... self.data = data
> > ... return Foo
> > ... 
> > >>> import typing
> > >>> foo = make_a_class(str)()
> > >>> typing.get_type_hints(foo.put_data)
> > Traceback (most recent call last):
> > File "", line 1, in 
> > File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
> > value = _eval_type(value, globalns, localns)
> > File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
> > return t._evaluate(globalns, localns, recursive_guard)
> > File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
> > eval(self.__forward_code__, globalns, localns),
> > File "", line 1, in 
> > NameError: name 'data_type' is not defined
> > >>> 
> > 
> > 
> > I don't see how I can supply the closure scope as localns to
> > get_type_hints. Any suggestions? Is constructing a (dynamically-
> > type-annotated) class in a function like this an anti-pattern?
> > 
> > ___
> > Python-Dev mailing list -- python-dev@python.org
> > To unsubscribe send an email to python-dev-le...@python.org
> > https://mail.python.org/mailman3/lists/python-dev.python.org/
> > Message archived at
> >
> https://mail.python.org/archives/list/python-dev@python.org/message/5RK6VXF263F5I4CU7FUMOGOYN2UQG73Q/
> > Code of Conduct: http://python.org/psf/codeofconduct/
> 
> 
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/NRH4HBD36WDIP4WR2L4TLTOYMQL2NUFV/
> Code of Conduct: http://python.org/psf/codeofconduct/

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/6P5GFROAVAYXU3DTELZRHHRCDRYUEWCG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Gregory P. Smith
What is the utility of a type annotation when the thing it refers to cannot
exist?

Deferred annotation lookups are intended to be something that analysis time
can make sense of but can always have no useful meaning at runtime.

No nesting required:

```
from __future__ import annotations
Class X:
  ...

def foo(hi: X):
  ...

del X
```

Now try analyzing foo at runtime...  I assume "Boom" with that NameError
again?  (*On a phone, can't try it now)*

I believe this isn't a problem get_type_hints() can ever solve.

Code that does this isn't what I'd call "reasonably" structured for use
with type hints.

If anything, type checkers should try to warn about it?

-gps

On Tue, Dec 8, 2020, 7:03 PM Paul Bryan  wrote:

> Let's try an example that static type checkers should have no problem with:
>
> Python 3.9.0 (default, Oct  7 2020, 23:09:01)
>
> [GCC 10.2.0] on linux
>
> Type "help", "copyright", "credits" or "license" for more information.
>
> >>> from __future__ import annotations
>
> >>>
>
> >>> def make_a_class():
>
> ... class A:
>
> ... def get_b(self) -> B:
>
> ... return B()
>
> ... class B:
>
> ... def get_a(self) -> A:
>
> ... return A()
>
> ... return A
>
> ...
>
> >>> A = make_a_class()
>
> >>> a = A()
>
> >>>
>
> >>> import typing
>
> >>> typing.get_type_hints(a.get_b)
>
> Traceback (most recent call last):
>
>   File "", line 1, in 
>
>   File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
>
> value = _eval_type(value, globalns, localns)
>
>   File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
>
> return t._evaluate(globalns, localns, recursive_guard)
>
>   File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
>
> eval(self.__forward_code__, globalns, localns),
>
>   File "", line 1, in 
>
> NameError: name 'B' is not defined
>
> >>>
>
>
>
>
> On Tue, 2020-12-08 at 18:48 -0800, Guido van Rossum wrote:
>
> Yeah, static type checkers won't like it regardless.
>
> On Tue, Dec 8, 2020 at 6:39 PM Paul Bryan  wrote:
>
> It appears that when from future import __annotations__, a type hint
> annotation derived from a closure loses scope.
>
> Simplistic example:
>
> Python 3.9.0 (default, Oct  7 2020, 23:09:01)
>
> [GCC 10.2.0] on linux
>
> Type "help", "copyright", "credits" or "license" for more information.
>
> >>> def make_a_class(data_type):
>
> ... class Foo:
>
> ... def put_data(self, data: data_type):
>
> ... self.data = data
>
> ... return Foo
>
> ...
>
> >>> import typing
>
> >>> foo = make_a_class(str)()
>
> >>> typing.get_type_hints(foo.put_data)
>
> {'data': }
>
> >>>
>
>
> If I add a single import to the top, it breaks:
>
> Python 3.9.0 (default, Oct  7 2020, 23:09:01)
>
> [GCC 10.2.0] on linux
>
> Type "help", "copyright", "credits" or "license" for more information.
>
> *>>> from __future__ import annotations  # added this line*
>
> >>> def make_a_class(data_type):
>
> ... class Foo:
>
> ... def put_data(self, data: data_type):
>
> ... self.data = data
>
> ... return Foo
>
> ...
>
> >>> import typing
>
> >>> foo = make_a_class(str)()
>
> >>> typing.get_type_hints(foo.put_data)
>
> Traceback (most recent call last):
>
>   File "", line 1, in 
>
>   File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
>
> value = _eval_type(value, globalns, localns)
>
>   File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
>
> return t._evaluate(globalns, localns, recursive_guard)
>
>   File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
>
> eval(self.__forward_code__, globalns, localns),
>
>   File "", line 1, in 
>
> NameError: name 'data_type' is not defined
>
> >>>
>
>
> I don't see how I can supply the closure scope as localns to
> get_type_hints. Any suggestions? Is constructing a
> (dynamically-type-annotated) class in a function like this an anti-pattern?
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/5RK6VXF263F5I4CU7FUMOGOYN2UQG73Q/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/NRH4HBD36WDIP4WR2L4TLTOYMQL2NUFV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived a

[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Paul Bryan
Yep, your example, *boom*.

My use case is to for type annotations to resolve type encoders,
decoders and validators at runtime.

Without __future__, type annotations specified in closure scope are
correctly attached to class variables, function parameters and return
types. Because they're in scope at the time they're evaluated.

__future__ annotations breaks because the hint is not evaluated until
get_type_hints is called, which is too late; the scope is lost.

Instead of just storing an annotation as a string, how about storing an
object containing the string, plus the local scope? Then get_type_hint
could be made to successfully resolve it.


On Tue, 2020-12-08 at 20:44 -0800, Gregory P. Smith wrote:
> What is the utility of a type annotation when the thing it refers to
> cannot exist?
> 
> Deferred annotation lookups are intended to be something that
> analysis time can make sense of but can always have no useful meaning
> at runtime.
> 
> No nesting required:
> 
> ```
> from __future__ import annotations
> Class X:
>   ...
> 
> def foo(hi: X):
>   ...
> 
> del X
> ```
> 
> Now try analyzing foo at runtime...  I assume "Boom" with that
> NameError again?  (On a phone, can't try it now)
> 
> I believe this isn't a problem get_type_hints() can ever solve.
> 
> Code that does this isn't what I'd call "reasonably" structured for
> use with type hints. 
> 
> If anything, type checkers should try to warn about it?
> 
> -gps
> 
> On Tue, Dec 8, 2020, 7:03 PM Paul Bryan  wrote:
> > Let's try an example that static type checkers should have no
> > problem with:
> > 
> > Python 3.9.0 (default, Oct 7 2020, 23:09:01) 
> > [GCC 10.2.0] on linux
> > Type "help", "copyright", "credits" or "license" for more
> > information.
> > >>> from __future__ import annotations
> > >>> 
> > >>> def make_a_class():
> > ... class A:
> > ... def get_b(self) -> B:
> > ... return B()
> > ... class B:
> > ... def get_a(self) -> A:
> > ... return A()
> > ... return A
> > ... 
> > >>> A = make_a_class()
> > >>> a = A()
> > >>> 
> > >>> import typing
> > >>> typing.get_type_hints(a.get_b)
> > Traceback (most recent call last):
> > File "", line 1, in 
> > File "/usr/lib/python3.9/typing.py", line 1386, in get_type_hints
> > value = _eval_type(value, globalns, localns)
> > File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
> > return t._evaluate(globalns, localns, recursive_guard)
> > File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
> > eval(self.__forward_code__, globalns, localns),
> > File "", line 1, in 
> > NameError: name 'B' is not defined
> > >>> 
> > 
> > 
> > 
> > 
> > On Tue, 2020-12-08 at 18:48 -0800, Guido van Rossum wrote:
> > > Yeah, static type checkers won't like it regardless.
> > > 
> > > On Tue, Dec 8, 2020 at 6:39 PM Paul Bryan 
> > > wrote:
> > > > It appears that when from future import __annotations__, a type
> > > > hint annotation derived from a closure loses scope.
> > > > 
> > > > Simplistic example:
> > > > 
> > > > Python 3.9.0 (default, Oct 7 2020, 23:09:01) 
> > > > [GCC 10.2.0] on linux
> > > > Type "help", "copyright", "credits" or "license" for more
> > > > information.
> > > > >>> def make_a_class(data_type):
> > > > ... class Foo:
> > > > ... def put_data(self, data: data_type):
> > > > ... self.data = data
> > > > ... return Foo
> > > > ... 
> > > > >>> import typing
> > > > >>> foo = make_a_class(str)()
> > > > >>> typing.get_type_hints(foo.put_data)
> > > > {'data': }
> > > > >>> 
> > > > 
> > > > 
> > > > If I add a single import to the top, it breaks:
> > > > 
> > > > Python 3.9.0 (default, Oct 7 2020, 23:09:01) 
> > > > [GCC 10.2.0] on linux
> > > > Type "help", "copyright", "credits" or "license" for more
> > > > information.
> > > > >>> from __future__ import annotations # added this line
> > > > >>> def make_a_class(data_type):
> > > > ... class Foo:
> > > > ... def put_data(self, data: data_type):
> > > > ... self.data = data
> > > > ... return Foo
> > > > ... 
> > > > >>> import typing
> > > > >>> foo = make_a_class(str)()
> > > > >>> typing.get_type_hints(foo.put_data)
> > > > Traceback (most recent call last):
> > > > File "", line 1, in 
> > > > File "/usr/lib/python3.9/typing.py", line 1386, in
> > > > get_type_hints
> > > > value = _eval_type(value, globalns, localns)
> > > > File "/usr/lib/python3.9/typing.py", line 254, in _eval_type
> > > > return t._evaluate(globalns, localns, recursive_guard)
> > > > File "/usr/lib/python3.9/typing.py", line 493, in _evaluate
> > > > eval(self.__forward_code__, globalns, localns),
> > > > File "", line 1, in 
> > > > NameError: name 'data_type' is not defined
> > > > >>> 
> > > > 
> > > > 
> > > > I don't see how I can supply the closure scope as localns to
> > > > get_type_hints. Any suggestions? Is constructing a
> > > > (dynamically-type-annotated) class in a function like this an
> > > > anti-pattern?
> > > > 
> > > > ___
> > > > Python-Dev mailing list -- python-dev@python.org
> 

[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Guido van Rossum
On Tue, Dec 8, 2020 at 8:58 PM Paul Bryan  wrote:

> My use case is to for type annotations to resolve type encoders, decoders
> and validators at runtime.
>

What is the reason you can't insist that the annotations be globals or at
least accessible from there (e.g. class attributes)? If the reason is that
they're dynamically computed, maybe you can dynamically compute the
annotation (effectively overruling the "future" semantics)?
`__annotations__` is a mutable attribute so there's nothing to stop you
from writing e.g.

def make_foo(symbol):
def foo(arg: symbol): ...
foo.__annotations__['arg'] = symbol  # Or you could do e.g. this in a
decorator
return foo


> Without __future__, type annotations specified in closure scope are
> correctly attached to class variables, function parameters and return
> types. Because they're in scope at the time they're evaluated.
>
> __future__ annotations breaks because the hint is not evaluated until
> get_type_hints is called, which is too late; the scope is lost.
>
> Instead of just storing an annotation as a string, how about storing an
> object containing the string, plus the local scope? Then get_type_hint
> could be made to successfully resolve it.
>

That would be a problem because it would keep everything in the local scope
alive forever (since perhaps the annotation is never used).

There may be a reason why my suggestion won't work either. If that's so,
please show a realistic example that captures the essence of your problem,
so we won't keep going back and forth attacking each other's toy examples.

Also please understand that this behavior is prescribed by an accepted PEP
and has been around since 3.7, so the bar to change this is very high.
(It's not the default behavior until 3.10 though, so theoretically there
might be a little bit more wiggle room for that. So far you haven't shown
sufficient evidence to consider that though.)

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/DMHM5BTBITZK26NJ2SZOOCYYK7AFWXFC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Paul Bryan
Rereading PEP 563, I'm clearly railing against it. I believe I can work
with __annotations__ as you suggest assuming the contract going forward
is for get_type_hints to return annotations verbatim if they're not
strings or ForwardRefs (the current implementation).

Thank you and Gregory for your time.


On Tue, 2020-12-08 at 21:49 -0800, Guido van Rossum wrote:
> On Tue, Dec 8, 2020 at 8:58 PM Paul Bryan  wrote:
> > My use case is to for type annotations to resolve type encoders,
> > decoders and validators at runtime.
> > 
> 
> 
> What is the reason you can't insist that the annotations be globals
> or at least accessible from there (e.g. class attributes)? If the
> reason is that they're dynamically computed, maybe you can
> dynamically compute the annotation (effectively overruling the
> "future" semantics)? `__annotations__` is a mutable attribute so
> there's nothing to stop you from writing e.g.
> 
> def make_foo(symbol):
>     def foo(arg: symbol): ...
>     foo.__annotations__['arg'] = symbol  # Or you could do e.g. this
> in a decorator
>     return foo
>  
> > Without __future__, type annotations specified in closure scope are
> > correctly attached to class variables, function parameters and
> > return types. Because they're in scope at the time they're
> > evaluated.
> > 
> > __future__ annotations breaks because the hint is not evaluated
> > until get_type_hints is called, which is too late; the scope is
> > lost.
> > 
> > Instead of just storing an annotation as a string, how about
> > storing an object containing the string, plus the local scope? Then
> > get_type_hint could be made to successfully resolve it.
> > 
> 
> 
> That would be a problem because it would keep everything in the local
> scope alive forever (since perhaps the annotation is never used).
> 
> There may be a reason why my suggestion won't work either. If that's
> so, please show a realistic example that captures the essence of your
> problem, so we won't keep going back and forth attacking each other's
> toy examples.
> 
> Also please understand that this behavior is prescribed by an
> accepted PEP and has been around since 3.7, so the bar to change this
> is very high. (It's not the default behavior until 3.10 though, so
> theoretically there might be a little bit more wiggle room for that.
> So far you haven't shown sufficient evidence to consider that
> though.)
> 
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/DMHM5BTBITZK26NJ2SZOOCYYK7AFWXFC/
> Code of Conduct: http://python.org/psf/codeofconduct/

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/KXMVS4EE4JHW6GPMECNN3Q4ZKJJCNQEH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: __future__ annotations loses closure scope

2020-12-08 Thread Guido van Rossum
Great. If you’d like to add something to the docs for get_type_hints()
about this behavior please submit a PR — I don’t see a reason this would
suddenly change but it’s better to make sure.

On Tue, Dec 8, 2020 at 22:29 Paul Bryan  wrote:

> Rereading PEP 563, I'm clearly railing against it. I believe I can work
> with __annotations__ as you suggest assuming the contract going forward
> is for get_type_hints to return annotations verbatim if they're not
> strings or ForwardRefs (the current implementation).
>
> Thank you and Gregory for your time.
>
>
> On Tue, 2020-12-08 at 21:49 -0800, Guido van Rossum wrote:
>
> On Tue, Dec 8, 2020 at 8:58 PM Paul Bryan  wrote:
>
> My use case is to for type annotations to resolve type encoders, decoders
> and validators at runtime.
>
>
> What is the reason you can't insist that the annotations be globals or at
> least accessible from there (e.g. class attributes)? If the reason is that
> they're dynamically computed, maybe you can dynamically compute the
> annotation (effectively overruling the "future" semantics)?
> `__annotations__` is a mutable attribute so there's nothing to stop you
> from writing e.g.
>
> def make_foo(symbol):
> def foo(arg: symbol): ...
> foo.__annotations__['arg'] = symbol  # Or you could do e.g. this in a
> decorator
> return foo
>
>
> Without __future__, type annotations specified in closure scope are
> correctly attached to class variables, function parameters and return
> types. Because they're in scope at the time they're evaluated.
>
> __future__ annotations breaks because the hint is not evaluated until
> get_type_hints is called, which is too late; the scope is lost.
>
> Instead of just storing an annotation as a string, how about storing an
> object containing the string, plus the local scope? Then get_type_hint
> could be made to successfully resolve it.
>
>
> That would be a problem because it would keep everything in the local
> scope alive forever (since perhaps the annotation is never used).
>
> There may be a reason why my suggestion won't work either. If that's so,
> please show a realistic example that captures the essence of your problem,
> so we won't keep going back and forth attacking each other's toy examples.
>
> Also please understand that this behavior is prescribed by an accepted PEP
> and has been around since 3.7, so the bar to change this is very high.
> (It's not the default behavior until 3.10 though, so theoretically there
> might be a little bit more wiggle room for that. So far you haven't shown
> sufficient evidence to consider that though.)
>
> ___
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/DMHM5BTBITZK26NJ2SZOOCYYK7AFWXFC/
>
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> --
--Guido (mobile)
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/K6YY6LLMMV5KB4YUQME2CDGAHEIG6XF6/
Code of Conduct: http://python.org/psf/codeofconduct/