Description
Bug report
Bug description:
using a conditional in a class definition like if TYPE_CHECKING
where TYPE_CHECKING
is False, or any kind of false conditional, seems to be ignored when types are evaluated under non-future annotations mode:
class MyClass:
somevalue: str
if False:
someothervalue: int
assert MyClass.__annotations__ == {"somevalue": str}, f"MyClass.__annotations__ == {MyClass.__annotations__}"
this seems to be something that might have been done with some intention, which is extremely troubling as this would be a huge showstopper for SQLAlchemy if these conditionals are no longer honored at runtime. A similar example
from typing import TYPE_CHECKING
if TYPE_CHECKING:
# is not evaluated under any python at runtime
from some_module import SpecialType
class MyClass:
somevalue: str
if TYPE_CHECKING:
# **is** evaluated under python 3.14.0a5, fails
someothervalue: SpecialType
assert MyClass.__annotations__ == {"somevalue": str}, f"MyClass.__annotations__ == {MyClass.__annotations__}"
calling upon __annotations__
seems to be the trigger that makes the above fail:
Traceback (most recent call last):
File "/home/classic/dev/sqlalchemy/test4.py", line 14, in <module>
assert MyClass.__annotations__ == {"somevalue": str}, f"MyClass.__annotations__ == {MyClass.__annotations__}"
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/classic/dev/sqlalchemy/test4.py", line 12, in __annotate__
someothervalue: SpecialType
^^^^^^^^^^^
NameError: name 'SpecialType' is not defined
however this appears to be some very strange quantum-physics type of evaluation that isn't actually running Python fully; below, the "someothervalue" type is evaluted, but not the value function assigned!
from typing import TYPE_CHECKING
def do_my_thing() -> int:
print("HEY!")
assert False
return 3 + 4
class MyClass:
somevalue: str
if TYPE_CHECKING:
someothervalue: int = do_my_thing()
assert MyClass.__annotations__ == {"somevalue": str}, f"MyClass.__annotations__ == {MyClass.__annotations__}"
This is an enormous and strange behavioral change that is really going to make things extremely difficult for SQLAlchemy, starting with we will have to rewrite thousands (OK, it turned out to be "dozens") of lines of test suite code into a much bigger exploded form and also a lot of end-user use cases we've defined using TYPE_CHECKING blocks aren't going to work anymore, it's not clear how much further this change will go.
I suppose if the whole thing boils down to what __annotations__
does, and we can call upon something like __annotations_but_not_false_blocks__
, that could save us, but overall I'm really hoping this is just a bad dream that we can wake up from.
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status