Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider not applying PEP 604 by presence of __future__ #387

Closed
hannseman opened this issue Feb 1, 2021 · 6 comments
Closed

Consider not applying PEP 604 by presence of __future__ #387

hannseman opened this issue Feb 1, 2021 · 6 comments

Comments

@hannseman
Copy link
Contributor

Applying PEP 604 on non 3.10 code will crash on libraries depending on introspection of type hints using typing.get_type_hints. This should apply for libraries like https://github.com/samuelcolvin/pydantic and https://github.com/konradhalas/dacite.

Example:

>>> from __future__ import annotations
>>> import typing
>>> class Snake(typing.NamedTuple):
...     name: str | None
...
>>> typing.get_type_hints(Snake)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py", line 1410, in get_type_hints
    value = _eval_type(value, base_globals, localns)
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py", line 277, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py", line 533, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
class Snake(typing.NamedTuple):
    name: str | None

My proposal is to only rewrite to PEP 604 when the minimum version is 3.10.

@asottile
Copy link
Owner

asottile commented Feb 1, 2021

I'd rather use this in python3.7 so I'm gong to reject this proposal

@asottile asottile closed this as completed Feb 1, 2021
@antonagestam
Copy link

@asottile Would you consider enabling/disabling of this with a feature flag in non-3.10 Python? This will introduce breaking code changes for all essentially any runtime usage of type hints.

... and if not, would you consider a "documentation fix" saying e.g. "this project introduces changes that break runtime introspection of type hints"?

@asottile
Copy link
Owner

asottile commented Feb 1, 2021

runtime types should use Annotated anyway, I don't consider their current implementation valid

@antonagestam
Copy link

antonagestam commented Feb 1, 2021

@asottile So would you consider a patch that documents the breakage?

Also, this isn't in regard to runtime types that differ from static types. How do you propose using Annotated with Optional[int]? Are you saying one should use something like Annotated[Optional[int], "What here?"]?

Update:

To clarify, this code breaks by the recent changes:

from __future__ import annotations
from typing import Optional, get_type_hints


def foo() -> Optional[int]:
    ...


get_type_hints(foo)

I don't understand how Annotated could alleviate this, but I noticed using string syntax seems to guard the annotation from being broken, e.g def foo() -> "Optional[int]": .... I guess that would be a workaround.

@asottile
Copy link
Owner

asottile commented Feb 1, 2021

#389 probably does what you want

@antonagestam
Copy link

@asottile Hey, thanks for reconsidering and fixing! 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants