mypy returns "Incompatible types in assignment" with on_setattr=setters.convert
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- python
- Domain
- developer-experience
Research direction
Start by reproducing the report with /tmp/test_mypy_attrs.py and mypy, focusing on the attrs.setters.convert assignment in the Glyph example. Trace how the converter and generated setter are represented to mypy, then confirm that plain-dict assignment type-checks while runtime conversion to Lib still works.
Written by the indexing model from the issue text.
Description
Not sure if this is a mypy issue or attrs or both.
I have an attrs class that defines a field with a converter that coerces the input value to a custom dict subclass.
It works fine when creating a new object, I pass in a dict and the field gets converted to the my dict subclass. I think #710 is responsible for inferring __init__ annotations from the converters'.
Now I would like to do the same with on_setattr, by using attrs.setters.convert: i.e. I want to set the field to a plain dict and have it converted automatically using the field converter to my dict subclass.
This works fine at runtime, but when I run mypy on my code, it complains that Incompatible types in assignment (expression has type Dict[...], variable has type "...") when I do that.
Here's a made up example:
from __future__ import annotations
from typing import Any, Dict, Mapping, Union
from attr import define, field, setters
class Lib(Dict[str, Any]):
pass
def _convert_lib(v: Mapping[str, Any]) -> Lib:
return v if isinstance(v, Lib) else Lib(v)
@define(on_setattr=setters.convert)
class Glyph:
lib: Lib = field(factory=Lib, converter=_convert_lib)
g = Glyph({"foo": [1, 2, 3]})
assert isinstance(g.lib, Lib)
g.lib = {"bar": [4, 5, 6]}
assert isinstance(g.lib, Lib)
$ mypy /tmp/test_mypy_attrs.py
/tmp/test_mypy_attrs.py:23: error: Incompatible types in assignment (expression has type "Dict[str, List[int]]", variable has type "Lib")
Is there a way around this besides an ugly # type: ignore on every line I use the attrs generated setter-cum-converter?
thanks in advance
- Dominant language
- Python
- Stars
- 5.8k
- Forks
- 480
- Avg merge
- 2h 15m
- Merged PRs (30d)
- 2
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.
More from python-attrs/attrs
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
python-attrs/attrs#1620 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
python-attrs/attrs#1596 · 2 comments · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
python-attrs/attrs#1549 · 3 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 38/100
python-attrs/attrs#1543 · 2 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
python-attrs/attrs#1532 ·
All issues in python-attrs/attrs
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
zostera/django-bootstrap4#894 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
use-agent-os/agent-os#3276 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
NousResearch/hermes-agent#117848 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
zilliztech/memsearch#759 ·