Erronous 'Incompatible type' when using descriptor in metaclass
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
When using descriptors in a metaclass, mypy will errounously throw 'Incompatible types in assignment' when accessing the described attribute in the derived class.
To Reproduce
` from typing import Generic, TypeVar, Any
from dataclasses import dataclass
@dataclass
class DUT:
Description: str = ""
ProductNumber: int = 0
T = TypeVar('T')
class DataDescriptor(Generic[T]):
def __init__(self, value: T) -> None:
self.value = value
def __set_name__(self, owner: Any, name: str) -> None:
self.name = name
def __get__(self, instance: Any, cls: Any) -> T:
return self.value
def __set__(self, obj: Any, value: T) -> None:
self.value = value
class DataModelMeta(type):
current_dut = DataDescriptor(DUT())
class DataModel(object, metaclass=DataModelMeta):
pass
dut: DUT = DUT("hello", 1234)
reveal_type(DataModel.current_dut)
reveal_type(dut)
DataModel.current_dut = dut`
# main.py:32: note: Revealed type is 'main.DUT*'
# main.py:33: note: Revealed type is 'main.DUT'
# main.py:34: error: Incompatible types in assignment (expression has type "DUT", variable has type "DataDescriptor[DUT]")
# Found 1 error in 1 file (checked 1 source file)
Expected Behavior
Assignment to DataModel.current_dut should expect the DUT type. mypy was able to infer this, as shown by reveal_type(DataModel.current_dut).
Actual Behavior
mypy throws an 'Incompatible type' error at the assignment
Your Environment
- Mypy version used: 0.790
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files): None - Python version used: 3.8.6:db45529
- Operating system and version: Windows 7
This can also be reproduced on the latest Python / mypy at https://mypy-play.net
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
Start with the provided descriptor and metaclass reproducer, running mypy with the shown Python example and checking its handling of descriptor assignment through a metaclass. Done means DataModel.current_dut = dut is accepted while reveal_type(DataModel.current_dut) remains DUT.
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
- Mostly clear
- Newbie friendliness
- 35/100