Class __annotations__ has wrong values if class attr has the same name as it's provided type annotation
Bug report
class Example1:
str: str = 'text'
Example1.__annotations__
>>> {'str': 'text'}
class Example2:
attr1: str = 'text'
int: int = 5
str: str = 'some str'
attr2: int = 150
Example2.__annotations__
{'attr1': <class 'str'>, 'int': 5, 'str': 'some str', 'attr2': 5}
I understand that using such names for attributes is not the best idea, but still the behavior with rewrites is strange. It is also strange that I did not found anything similar in existing issues, because I have been observed that behavior for a long time..
Environment
- CPython versions tested on: 3.8.10, 3.9.13, 3.10.4, 3.11.0
- OS: Windows 10 x64
Cc. @larryhastings — may be of interest
In my opinion it works as it should. Regular scoping rules are applied here:
class Example1:
str: str = 'text'
Sequence:
- We define
strname inExample1scope - It shadows
strfrombuiltins -
strnow has'text'value
This is a known thing, there are two solutions:
import builtins
class Some:
str: builtins.str = 'a'
_str = str
class Other:
str: _str = 'b'
I think we can reference this in the docs 🤔
I don’t know how to react - on the one hand, yes, it seems quite logical, and producing crutches is not the best idea for fixing such things.. On the other hand, I consider this mechanism to be some internal logic.. Won’t this be a problem later?
I don't think that this is somehow different from regular builtin shadowing, like str = ''
Others might have different opinions, so let's wait for their feedback :)
This is the expected behavior. You are overwriting builtin objects within the scope of the Example classes. And this doesn't impact str and int outside the context of those classes.
As mentioned several times in this issue, Python is behaving as expected here. Python's behavior isn't going to change, as there's no bug.