Dataclass doesn't match a protocol if a field is Callable (expected settable variable, got read-only attribute)
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 55/100
Rechercherichtung
Beginne in subtypes.py bei get_member_flags() und vergleiche die Behandlung von v.is_property mit dem von plugins/dataclasses.py:_propertize_callables() gesetzten Zustand v.is_settable_property. Verwende die Reproduktion des Issues mit mypy 1.13.0, um das Verhalten zu überprüfen, und bestätige anschließend, dass die Dataclass mit einem Callable-Feld ohne den gemeldeten Zuweisungsfehler zum Protokoll passt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Bug Report
A dataclass containing a Callable field doesn't match the protocol. On the other hand if the field is defined using a callback protocol (another protocol with __call__) or the class is not a dataclass, no error is reported.
test.py:26: error: Incompatible types in assignment (expression has type "FooDC", variable has type "FooProto") [assignment]
test.py:26: note: Protocol member FooProto.f expected settable variable, got read-only attribute
The mypy's subtypes.py:get_member_flags() function contains:
if v.is_property:
return {IS_VAR}
which doesn't take the v.is_settable_property into account while it is set for Callables in plugins/dataclasses.py:_propertize_callables().
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=5c77ed1a30b03cba5cf0ba8e710a4214
import typing
import collections.abc
import dataclasses
CAC = collections.abc.Callable[..., None]
class FooProto(typing.Protocol):
f: CAC
class Foo:
f: CAC
def __init__(self, f: CAC):
self.f = f
@dataclasses.dataclass(frozen=False)
class FooDC:
f: CAC
foo: FooProto = Foo(lambda: None)
# only foo_dc fails:
# test.py:23: error: Incompatible types in assignment (expression has type "FooDC", variable has type "FooProto") [assignment]
# test.py:23: note: Protocol member FooProto.f expected settable variable, got read-only attribute
foo_dc: FooProto = FooDC(lambda: None)
class CallbackProto(typing.Protocol):
def __call__(self, *args, **kwargs) -> None: ...
class FooProtoCallback(typing.Protocol):
f: CallbackProto
class FooCallback:
f: CallbackProto
def __init__(self, f: CAC):
self.f = f
@dataclasses.dataclass(frozen=False)
class FooDCCallback:
f: CallbackProto
foo_callback: FooProtoCallback = FooCallback(lambda: None)
foo_dc_callback: FooProtoCallback = FooDCCallback(lambda: None)
Expected Behavior
I expect a dataclass with a Callable to match the protocol.
Actual Behavior
The dataclass doesn't match the protocol.
Your Environment
- Mypy version used: 1.13.0
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.11.2
- Vorherrschende Sprache
- Python
- Sterne
- 20.6k
- Forks
- 3.3k
- Ø Merge
- 1 T. 18 Std.
- Gemergte PRs (30 T.)
- 54
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus python/mypy
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
-
documentation
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
-
bug topic-configuration topic-error-reporting
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
bancolombia/sentinel#23 ·
-
test md OffenCI
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100
langchain-ai/deepagents#6450 ·
-
bug client
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 88/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 74/100