You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mypyc: Cls.__dict__ is mappingproxy, not dict #14056
It looks mypy's type inference works fine and it's mypyc (maybe) bug
Maybe it's connected to builtins vars signature -- vars by the signature should return dict
But it's false, vars may return mappingproxy:
>>> class Foo:
...
>>> Foo.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None})
>>> vars(Foo)
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None})
>>>
@AlexWaygood I didn't find docs how to install latest typeshed and my try to install it directly into venv from git failed. Is there any way to update typeshed to test new behavior?
In general you can get mypy to use the latest typeshed using the --custom-typeshed-dir command-line argument: clone typeshed, then use that option to point to your local clone of typeshed. I've never done any hacking on mypyc so I'm not sure if the option works the same way with mypyc, but it certainly doesn't reject the argument if you pass it on the command line.
Unfortunately if I do mypyc mypyc_weird.py --custom-typeshed-dir <path-to-my-typeshed-clone>, the compiled module still raises the same exception when I import it. Which is sort of expected -- my PR to typeshed improved the stub for vars(), but didn't alter the stub for type.__dict__ in any way (since that's already correct over at typeshed). EDIT: However, it does look like my typeshed PR fixed the version where you use vars() instead of accessing __dict__ directly! So that's nice.
It looks like the issue with cls.__dict__ is ultimately a mypy/mypyc bug rather than a typeshed bug.
It's a mypy bug rather than a mypyc bug, and it stems from a more general bug where mypy misunderstands how attribute access on class objects should be understood when metaclasses are involved. Here's a minimal repro:
classMeta(type):
bar: strclassFoo(metaclass=Meta):
bar: intreveal_type(Foo().bar) # Revealed type is int (correct!)reveal_type(Foo.bar) # Revealed type is int, but should be str
If this bug is fixed, mypy will correctly infer from typeshed's stub for builtins.type that the __dict__ of a class object is of type types.MappingProxyType, which will solve the mypyc issue.
Activity
AlexWaygood commentedon Nov 10, 2022
Currently the stub for
vars()in typeshed is this:Maybe it should be this:
Or this:
However, that doesn't explain why mypyc seems to think that
cls.__dict__should be of typedict. Typeshed correctly already hastype.__dict__as being of typetypes.MappingProxyType: https://github.com/python/typeshed/blob/7b3fff714a48f0413141ba10344f9473e3ec4a18/stdlib/builtins.pyi#L149AlexWaygood commentedon Nov 10, 2022
python/typeshed#9146 has just been merged, which improves the signature for
vars().kai3341 commentedon Nov 10, 2022
@AlexWaygood I didn't find docs how to install latest typeshed and my try to install it directly into venv from git failed. Is there any way to update typeshed to test new behavior?
AlexWaygood commentedon Nov 10, 2022
In general you can get mypy to use the latest typeshed using the
--custom-typeshed-dircommand-line argument: clone typeshed, then use that option to point to your local clone of typeshed. I've never done any hacking on mypyc so I'm not sure if the option works the same way with mypyc, but it certainly doesn't reject the argument if you pass it on the command line.Unfortunately if I do
mypyc mypyc_weird.py --custom-typeshed-dir <path-to-my-typeshed-clone>, the compiled module still raises the same exception when I import it. Which is sort of expected -- my PR to typeshed improved the stub forvars(), but didn't alter the stub fortype.__dict__in any way (since that's already correct over at typeshed). EDIT: However, it does look like my typeshed PR fixed the version where you usevars()instead of accessing__dict__directly! So that's nice.It looks like the issue with
cls.__dict__is ultimately a mypy/mypyc bug rather than a typeshed bug.AlexWaygood commentedon Mar 13, 2023
It's a mypy bug rather than a mypyc bug, and it stems from a more general bug where mypy misunderstands how attribute access on class objects should be understood when metaclasses are involved. Here's a minimal repro:
https://mypy-play.net/?mypy=latest&python=3.11&gist=011c7d73769c1d028b4d4bfa8a30155d
If this bug is fixed, mypy will correctly infer from typeshed's stub for
builtins.typethat the__dict__of a class object is of typetypes.MappingProxyType, which will solve the mypyc issue.JelleZijlstra commentedon Mar 13, 2023
Fixing that bug may be quite disruptive; I expect we'll have to get much stricter in typeshed about adding
ClassVarannotations.AlexWaygood commentedon Mar 13, 2023
I'd like to have a go, anyway, and see what mypy_primer says. I have some ideas :)
JukkaL commentedon Mar 15, 2023
(I created a new label for mypy issues that are known to cause issues for mypyc users.)
Improve handling of attribute access on class objects (#14988)