[Python-Dev] Postponed annotations break inspection of dataclasses

2018-09-22 Thread David Hagen
The new postponed annotations have an unexpected interaction with
dataclasses. Namely, you cannot get the type hints of any of the data
classes methods.

For example, I have some code that inspects the type parameters of a
class's `__init__` method. (The real use case is to provide a default
serializer for the class, but that is not important here.)

```
from dataclasses import dataclass
from typing import get_type_hints

class Foo:
pass

@dataclass
class Bar:
foo: Foo

print(get_type_hints(Bar.__init__))
```

In Python 3.6 and 3.7, this does what is expected; it prints `{'foo':
, 'return': }`.

However, if in Python 3.7, I add `from __future__ import annotations`, then
this fails with an error:

```
NameError: name 'Foo' is not defined
```

I know why this is happening. The `__init__` method is defined in the
`dataclasses` module which does not have the `Foo` object in its
environment, and the `Foo` annotation is being passed to `dataclass` and
attached to `__init__` as the string `"Foo"` rather than as the original
object `Foo`, but `get_type_hints` for the new annotations only does a name
lookup in the module where `__init__` is defined not where the annotation
is defined.

I know that the use of lambdas to implement PEP 563 was rejected for
performance reasons. I could be wrong, but I think this was motivated by
variable annotations because the lambda would have to be constructed each
time the function body ran. I was wondering if I could motivate storing the
annotations as lambdas in class bodies and function signatures, in which
the environment is already being captured and is code that usually only
runs once.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Postponed annotations break inspection of dataclasses

2018-09-23 Thread David Hagen
On Sat, Sep 22, 2018 at 3:11 PM Guido van Rossum  wrote:
> Still, I wonder if there's a tweak possible of the globals and locals
used when exec()'ing the function definitions in dataclasses.py, so that
get_type_hints() gets the right globals for this use case.

On Sat, Sep 22, 2018 at 4:38 PM Yury Selivanov 
wrote:
> If it's possible to fix exec() to accept any Mapping (not just dicts),
> then we can create a proxy mapping for "Dataclass.__init__.__module__"
> module and everything would work as expected.

Another possible solution is that `__annotations__` are *permitted* to be
lambdas, but not created as such by default, and `get_type_hints` is aware
of this. Operations that are known to break type hints (such as when data
classes copy the type hints from the class body to the `__init__` method)
could covert the type hint from a string to a lambda before moving it. It
does not even have to be a lambda; an instance of some `TypeHint` class,
which stores the string and pointers to the original `globals` and `locals`
(or just the original object whose `globals` and `locals` are relevant),
but that's essentially what a lambda is anyway.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Postponed annotations break inspection of dataclasses

2018-09-23 Thread David Hagen
On Sat, Sep 22, 2018 at 12:41 PM Guido van Rossum 
wrote:
> Probably a bugs.python.org issue is a better place to dive into the
details than python-dev.

Issue tracker issue created: https://bugs.python.org/issue34776
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com