Ryan Sobol <he...@ryansobol.com> added the comment:

It's worth pointing out that a similar error is produced for a 
forward-referenced return type of a registered method, but only for python3.9. 
For example:

from __future__ import annotations
from functools import singledispatchmethod


class Integer:
    def __init__(self, value: int):
        self.value = value

    def __str__(self) -> str:
        return str(self.value)

    @singledispatchmethod
    def add(self, other: object) -> Integer:
        raise NotImplementedError(f"Unsupported type {type(other)}")

    @add.register
    def _(self, other: int) -> "Integer":
        return Integer(self.value + other)


print(Integer(2).add(40))

This code runs without error in python3.8, and I am using this technique in 
code running in a production environment.

$ python3.8 --version
Python 3.8.6
$ python3.8 integer.py
42

However, this code throws a NameError in python3.9.

$ python3.9 --version
Python 3.9.0
$ python3.9 integer.py
Traceback (most recent call last):
  File "/Users/ryansobol/Downloads/integer.py", line 5, in <module>
    class Integer:
  File "/Users/ryansobol/Downloads/integer.py", line 17, in Integer
    def _(self, other: int) -> "Integer":
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/functools.py",
 line 909, in register
    return self.dispatcher.register(cls, func=method)
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/functools.py",
 line 860, in register
    argname, cls = next(iter(get_type_hints(func).items()))
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py",
 line 1386, in get_type_hints
    value = _eval_type(value, globalns, localns)
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py",
 line 254, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py",
 line 497, in _evaluate
    self.__forward_value__ = _eval_type(
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py",
 line 254, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File 
"/usr/local/Cellar/python@3.9/3.9.0_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py",
 line 493, in _evaluate
    eval(self.__forward_code__, globalns, localns),
  File "<string>", line 1, in <module>
NameError: name 'Integer' is not defined

I know that some may see this issue as a feature request for 3.10+. However, 
for me, it is a bug preventing my code from migrating to 3.9.

----------
nosy: +ryansobol

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41987>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to