Metaclass confusion with properties
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
I'm using python 3.8 and mypy 0.740. The script below prints "21" and "42" when run, but fails to type check with mypy:
class meta (type):
pass
class value (metaclass=meta):
pass
class submeta (meta):
@property
def attr(cls) -> int:
return 42
class subvalue (metaclass=submeta):
@property
def attr(self) -> int:
return 21
o = subvalue()
a = o.attr
print(a)
a = subvalue.attr
print(a)
The mypy diagnostics say:
meta-test.py:24: error: Incompatible types in assignment (expression has type "Callable[[subvalue], int]", variable has type "int")
Found 1 error in 1 file (checked 1 source file)
The error is incorrect, "subvalue.attr" has type "int", as it resolves to the property defined on the metaclass, not to the property defined on the class.
This is fairly esoteric as written, but is the structure used by PyObjC to expose Objective-C classes. PyObjC uses metaclasses to expose class methods because ObjC classes can have instance- and class-methods with the same name.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic using the meta-test.py example described in the issue with Python 3.8 and mypy 0.740. Start by tracing how mypy resolves properties on subvalue versus its submeta metaclass. Done means subvalue.attr is inferred as int without the reported incompatible-assignment error, while instance access remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100