dict literals inferred like immutable Mapping
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
dict literal behaves as though it is inferred to be (immutable) Mapping
To Reproduce
class OrmBase:
pass
class Orm1(OrmBase):
pass
class Orm1Prime(OrmBase):
pass
class Orm2(OrmBase):
pass
class Orm2Prime(OrmBase):
pass
def func(orm: Union[Orm1, Orm2]):
orm_mapper = {
Orm1: Orm1Prime,
Orm2: Orm2Prime,
}
mapped: Union[Type[Orm1Prime], Type[Orm2Prime]] = orm_mapper[orm.__class__]
# Incompatible types in assignment (expression has type "Type[OrmBase]",
# variable has type "Union[Type[Orm1Prime], Type[Orm2Prime]]") [E]
return mapped
Expected Behavior
dict is a MutableMapping, which is invariant with respect to value types. The Union on mapped should be acceptable here. (Pyright has no issue with this.)
Actual Behavior
The Union is rejected, apparently because the parent class is expected (see the error message above).
Adding a plain dict annotation resolves the error:
orm_mapper: dict = { ...
I believe this resolves the error by telling Mypy that this is a MutableMapping with invariant VT and not a Mapping with covariant VT_co. typing's definitions of both
Your Environment
- Mypy version used: 0.910
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files):
[mypy]
plugins = sqlalchemy.ext.mypy.plugin
ignore_missing_imports = True
[mypy-sqlalchemy.*]
- Python version used: 3.9.6
- Operating system and version: Fedora 34 (Workstation)
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 by running the supplied reproduction with mypy 0.910 and compare the inferred type of the unannotated dict literal with the explicitly annotated version. Trace the dict-literal inference path and verify that the assignment accepts the expected union without weakening type safety; the issue is resolved when the reproduction passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100