Skip to content

[ty] Fix subtyping/assignability for @property protocol members#19936

Draft
AlexWaygood wants to merge 35 commits intomainfrom
alex/protocol-property-check-2
Draft

[ty] Fix subtyping/assignability for @property protocol members#19936
AlexWaygood wants to merge 35 commits intomainfrom
alex/protocol-property-check-2

Conversation

@AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Aug 16, 2025

Summary

Fixes astral-sh/ty#1379, fixes astral-sh/ty#1380

Test Plan

mtshiba and others added 20 commits June 30, 2025 01:06
Collect multiple `AttributeAssignmentResult` errors into `AttributeAssignmentResults`.
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Aug 16, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Aug 16, 2025

Diagnostic diff on typing conformance tests

Changes were detected when running ty on typing conformance tests
--- old-output.txt	2025-08-29 14:03:08.443922231 +0000
+++ new-output.txt	2025-08-29 14:03:11.072926350 +0000
@@ -210,8 +210,8 @@
 dataclasses_final.py:36:1: error[invalid-assignment] Cannot assign to final attribute `final_with_default` on type `D`
 dataclasses_final.py:37:1: error[invalid-assignment] Cannot assign to final attribute `final_no_default` on type `<class 'D'>`
 dataclasses_final.py:38:1: error[invalid-assignment] Cannot assign to final attribute `final_with_default` on type `<class 'D'>`
-dataclasses_frozen.py:16:1: error[invalid-assignment] Property `a` defined in `DC1` is read-only
-dataclasses_frozen.py:17:1: error[invalid-assignment] Property `b` defined in `DC1` is read-only
+dataclasses_frozen.py:16:1: error[invalid-assignment] Attribute `a` on object of type `DC1` is read-only
+dataclasses_frozen.py:17:1: error[invalid-assignment] Attribute `b` on object of type `DC1` is read-only
 dataclasses_kwonly.py:23:11: error[too-many-positional-arguments] Too many positional arguments: expected 1, got 2
 dataclasses_kwonly.py:38:11: error[too-many-positional-arguments] Too many positional arguments: expected 1, got 2
 dataclasses_kwonly.py:53:11: error[too-many-positional-arguments] Too many positional arguments: expected 1, got 2
@@ -253,23 +253,23 @@
 dataclasses_transform_converter.py:108:5: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 1, got 6
 dataclasses_transform_converter.py:109:5: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 1, got 6
 dataclasses_transform_converter.py:112:11: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 1, got 6
-dataclasses_transform_converter.py:114:1: error[invalid-assignment] Object of type `Literal["f1"]` is not assignable to attribute `field0` of type `int`
-dataclasses_transform_converter.py:115:1: error[invalid-assignment] Object of type `Literal["f6"]` is not assignable to attribute `field3` of type `ConverterClass`
-dataclasses_transform_converter.py:116:1: error[invalid-assignment] Object of type `Literal[b"f6"]` is not assignable to attribute `field3` of type `ConverterClass`
-dataclasses_transform_converter.py:119:1: error[invalid-assignment] Object of type `Literal[1]` is not assignable to attribute `field3` of type `ConverterClass`
+dataclasses_transform_converter.py:114:1: error[invalid-assignment] Object of type `Literal["f1"]` is not assignable to attribute `field0` on type `int`
+dataclasses_transform_converter.py:115:1: error[invalid-assignment] Object of type `Literal["f6"]` is not assignable to attribute `field3` on type `ConverterClass`
+dataclasses_transform_converter.py:116:1: error[invalid-assignment] Object of type `Literal[b"f6"]` is not assignable to attribute `field3` on type `ConverterClass`
+dataclasses_transform_converter.py:119:1: error[invalid-assignment] Object of type `Literal[1]` is not assignable to attribute `field3` on type `ConverterClass`
 dataclasses_transform_converter.py:121:11: error[too-many-positional-arguments] Too many positional arguments to bound method `__init__`: expected 1, got 7
 dataclasses_transform_converter.py:130:31: error[invalid-argument-type] Argument to function `model_field` is incorrect: Expected `(Literal[1], /) -> Unknown`, found `def converter_simple(s: str) -> int`
 dataclasses_transform_field.py:49:43: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `(...) -> @Todo(unsupported type[X] special form)`
 dataclasses_transform_field.py:75:16: error[too-many-positional-arguments] Too many positional arguments: expected 0, got 1
 dataclasses_transform_func.py:53:8: error[missing-argument] No arguments provided for required parameters `id`, `name`
 dataclasses_transform_func.py:53:18: error[too-many-positional-arguments] Too many positional arguments: expected 0, got 2
-dataclasses_transform_func.py:57:1: error[invalid-assignment] Object of type `Literal[3]` is not assignable to attribute `name` of type `str`
+dataclasses_transform_func.py:57:1: error[invalid-assignment] Object of type `Literal[3]` is not assignable to attribute `name` on type `str`
 dataclasses_transform_func.py:61:6: error[unsupported-operator] Operator `<` is not supported for types `Customer1` and `Customer1`
 dataclasses_transform_func.py:65:36: error[unknown-argument] Argument `salary` does not match any known parameter
 dataclasses_transform_func.py:71:8: error[missing-argument] No arguments provided for required parameters `id`, `name`
 dataclasses_transform_func.py:71:18: error[too-many-positional-arguments] Too many positional arguments: expected 0, got 2
 dataclasses_transform_func.py:77:36: error[invalid-return-type] Function always implicitly returns `None`, which is not assignable to return type `T@create_model_frozen`
-dataclasses_transform_func.py:97:1: error[invalid-assignment] Property `id` defined in `Customer3` is read-only
+dataclasses_transform_func.py:97:1: error[invalid-assignment] Attribute `id` on object of type `Customer3` is read-only
 dataclasses_transform_meta.py:60:36: error[unknown-argument] Argument `other_name` does not match any known parameter
 dataclasses_transform_meta.py:73:6: error[unsupported-operator] Operator `<` is not supported for types `Customer1` and `Customer1`
 dataclasses_transform_meta.py:79:6: error[unsupported-operator] Operator `<` is not supported for types `Customer2` and `Customer2`
@@ -429,8 +429,8 @@
 generics_self_advanced.py:44:9: error[type-assertion-failure] Argument does not have asserted type `typing.Self`
 generics_self_advanced.py:45:9: error[type-assertion-failure] Argument does not have asserted type `typing.Self`
 generics_self_attributes.py:26:33: error[invalid-argument-type] Argument is incorrect: Expected `typing.Self | None`, found `LinkedList[int]`
-generics_self_attributes.py:29:5: error[invalid-assignment] Object of type `OrdinalLinkedList` is not assignable to attribute `next` of type `typing.Self | None`
-generics_self_attributes.py:32:5: error[invalid-assignment] Object of type `LinkedList[int]` is not assignable to attribute `next` of type `typing.Self | None`
+generics_self_attributes.py:29:5: error[invalid-assignment] Object of type `OrdinalLinkedList` is not assignable to attribute `next` on type `typing.Self | None`
+generics_self_attributes.py:32:5: error[invalid-assignment] Object of type `LinkedList[int]` is not assignable to attribute `next` on type `typing.Self | None`
 generics_self_basic.py:14:9: error[type-assertion-failure] Argument does not have asserted type `Self@set_scale`
 generics_self_basic.py:20:16: error[invalid-return-type] Return type does not match returned value: expected `Self@method2`, found `Shape`
 generics_self_basic.py:33:16: error[invalid-return-type] Return type does not match returned value: expected `Self@cls_method2`, found `Shape`
@@ -670,7 +670,7 @@
 namedtuples_type_compat.py:23:1: error[invalid-assignment] Object of type `Point` is not assignable to `tuple[int, str, str]`
 namedtuples_usage.py:34:7: error[index-out-of-bounds] Index 3 is out of bounds for tuple `Point` with length 3
 namedtuples_usage.py:35:7: error[index-out-of-bounds] Index -4 is out of bounds for tuple `Point` with length 3
-namedtuples_usage.py:40:1: error[invalid-assignment] Cannot assign to read-only property `x` on object of type `Point`
+namedtuples_usage.py:40:1: error[invalid-assignment] Attribute `x` on object of type `Point` is read-only
 namedtuples_usage.py:41:1: error[invalid-assignment] Cannot assign to object of type `Point` with no `__setitem__` method
 namedtuples_usage.py:52:1: error[invalid-assignment] Too many values to unpack: Expected 2
 namedtuples_usage.py:53:1: error[invalid-assignment] Not enough values to unpack: Expected 4
@@ -729,13 +729,22 @@
 overloads_evaluation.py:322:5: error[type-assertion-failure] Argument does not have asserted type `list[int]`
 protocols_class_objects.py:58:1: error[invalid-assignment] Object of type `<class 'ConcreteA'>` is not assignable to `ProtoA1`
 protocols_class_objects.py:59:1: error[invalid-assignment] Object of type `<class 'ConcreteA'>` is not assignable to `ProtoA2`
+protocols_class_objects.py:74:1: error[invalid-assignment] Object of type `<class 'ConcreteB'>` is not assignable to `ProtoB1`
+protocols_class_objects.py:104:1: error[invalid-assignment] Object of type `<class 'ConcreteC1'>` is not assignable to `ProtoC1`
+protocols_class_objects.py:106:1: error[invalid-assignment] Object of type `<class 'ConcreteC2'>` is not assignable to `ProtoC1`
 protocols_definition.py:114:1: error[invalid-assignment] Object of type `Concrete2_Bad1` is not assignable to `Template2`
 protocols_definition.py:115:1: error[invalid-assignment] Object of type `Concrete2_Bad2` is not assignable to `Template2`
 protocols_definition.py:116:1: error[invalid-assignment] Object of type `Concrete2_Bad3` is not assignable to `Template2`
 protocols_definition.py:156:1: error[invalid-assignment] Object of type `Concrete3_Bad1` is not assignable to `Template3`
+protocols_definition.py:157:1: error[invalid-assignment] Object of type `Concrete3_Bad2` is not assignable to `Template3`
+protocols_definition.py:158:1: error[invalid-assignment] Object of type `Concrete3_Bad3` is not assignable to `Template3`
 protocols_definition.py:159:1: error[invalid-assignment] Object of type `Concrete3_Bad4` is not assignable to `Template3`
 protocols_definition.py:160:1: error[invalid-assignment] Object of type `Concrete3_Bad5` is not assignable to `Template3`
+protocols_definition.py:218:1: error[invalid-assignment] Object of type `Concrete4_Bad1` is not assignable to `Template4`
 protocols_definition.py:219:1: error[invalid-assignment] Object of type `Concrete4_Bad2` is not assignable to `Template4`
+protocols_definition.py:339:1: error[invalid-assignment] Object of type `Concrete6_Bad1` is not assignable to `Template6`
+protocols_definition.py:340:1: error[invalid-assignment] Object of type `Concrete6_Bad2` is not assignable to `Template6`
+protocols_definition.py:341:1: error[invalid-assignment] Object of type `Concrete6_Bad3` is not assignable to `Template6`
 protocols_merging.py:52:1: error[invalid-assignment] Object of type `SCConcrete2` is not assignable to `SizedAndClosable1`
 protocols_merging.py:53:1: error[invalid-assignment] Object of type `SCConcrete2` is not assignable to `SizedAndClosable2`
 protocols_merging.py:54:1: error[invalid-assignment] Object of type `SCConcrete2` is not assignable to `SizedAndClosable3`
@@ -859,5 +868,5 @@
 typeddicts_usage.py:28:1: error[missing-typed-dict-key] Missing required key 'name' in TypedDict `Movie` constructor
 typeddicts_usage.py:28:18: error[invalid-key] Invalid key access on TypedDict `Movie`: Unknown key "title"
 typeddicts_usage.py:40:24: error[invalid-type-form] The special form `typing.TypedDict` is not allowed in type expressions. Did you mean to use a concrete TypedDict or `collections.abc.Mapping[str, object]` instead?
-Found 860 diagnostics
+Found 869 diagnostics
 WARN A fatal error occurred while checking some files. Not all project files were analyzed. See the diagnostics list above for details.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 16, 2025

mypy_primer results

Changes were detected when running on open source projects
attrs (https://github.com/python-attrs/attrs)
- tests/dataclass_transform_example.py:32:1: error[invalid-assignment] Property `a` defined in `Frozen` is read-only
+ tests/dataclass_transform_example.py:32:1: error[invalid-assignment] Attribute `a` on object of type `Frozen` is read-only
- tests/test_next_gen.py:71:13: error[invalid-assignment] Object of type `Literal["1"]` is not assignable to attribute `x` of type `int`
+ tests/test_next_gen.py:71:13: error[invalid-assignment] Object of type `Literal["1"]` is not assignable to attribute `x` on type `int`
- tests/test_next_gen.py:219:13: error[invalid-assignment] Property `x` defined in `F` is read-only
+ tests/test_next_gen.py:219:13: error[invalid-assignment] Attribute `x` on object of type `F` is read-only
- tests/test_next_gen.py:258:13: error[invalid-assignment] Property `a` defined in `A` is read-only
+ tests/test_next_gen.py:258:13: error[invalid-assignment] Attribute `a` on object of type `A` is read-only
- tests/test_next_gen.py:261:13: error[invalid-assignment] Property `a` defined in `B` is read-only
+ tests/test_next_gen.py:261:13: error[invalid-assignment] Attribute `a` on object of type `B` is read-only
- tests/test_next_gen.py:264:13: error[invalid-assignment] Property `b` defined in `B` is read-only
+ tests/test_next_gen.py:264:13: error[invalid-assignment] Attribute `b` on object of type `B` is read-only
- tests/test_next_gen.py:267:13: error[invalid-assignment] Property `c` defined in `C` is read-only
+ tests/test_next_gen.py:267:13: error[invalid-assignment] Attribute `c` on object of type `C` is read-only
- tests/test_next_gen.py:387:9: error[invalid-assignment] Object of type `Literal["11"]` is not assignable to attribute `x` of type `int`
+ tests/test_next_gen.py:387:9: error[invalid-assignment] Object of type `Literal["11"]` is not assignable to attribute `x` on type `int`
- tests/test_next_gen.py:393:13: error[invalid-assignment] Object of type `Literal["9"]` is not assignable to attribute `x` of type `int`
+ tests/test_next_gen.py:393:13: error[invalid-assignment] Object of type `Literal["9"]` is not assignable to attribute `x` on type `int`

python-htmlgen (https://github.com/srittau/python-htmlgen)
- test_htmlgen/form.py:51:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `autocomplete` of type `Autocomplete | None`
+ test_htmlgen/form.py:51:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `autocomplete` on type `Autocomplete | None`
- test_htmlgen/video.py:38:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `preload` of type `Preload | None`
+ test_htmlgen/video.py:38:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `preload` on type `Preload | None`

comtypes (https://github.com/enthought/comtypes)
- comtypes/client/_code_cache.py:121:13: error[invalid-assignment] Object of type `ModuleType` is not assignable to attribute `gen` of type `<module 'comtypes.gen'>`
+ comtypes/client/_code_cache.py:121:13: error[invalid-assignment] Object of type `ModuleType` is not assignable to attribute `gen` on type `<module 'comtypes.gen'>`

rich (https://github.com/Textualize/rich)
- tests/test_pretty.py:184:5: error[invalid-assignment] Object of type `ExampleDataclass` is not assignable to attribute `bar` of type `str`
+ tests/test_pretty.py:184:5: error[invalid-assignment] Object of type `ExampleDataclass` is not assignable to attribute `bar` on type `str`

trio (https://github.com/python-trio/trio)
- src/trio/_util.py:221:17: error[invalid-assignment] Cannot assign to read-only property `__name__` on object of type `<Protocol with members '__name__'>`
+ src/trio/_util.py:221:17: error[invalid-assignment] Attribute `__name__` on object of type `<Protocol with members '__name__'>` is read-only

paasta (https://github.com/yelp/paasta)
- paasta_tools/api/api.py:252:9: error[invalid-assignment] Object of type `str | None` is not assignable to attribute `cluster` of type `str`
+ paasta_tools/api/api.py:252:9: error[invalid-assignment] Object of type `str | None` is not assignable to attribute `cluster` on type `str`
- paasta_tools/cli/cmds/mark_for_deployment.py:1925:21: error[invalid-assignment] Object of type `None` is not assignable to attribute `waiting_on` of type `Mapping[str, Collection[str]]`
+ paasta_tools/cli/cmds/mark_for_deployment.py:1925:21: error[invalid-assignment] Object of type `None` is not assignable to attribute `waiting_on` on type `Mapping[str, Collection[str]]`

pydantic (https://github.com/pydantic/pydantic)
- pydantic/_internal/_mock_val_ser.py:137:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `validator` of type `SchemaValidator | PluggableSchemaValidator`
+ pydantic/_internal/_mock_val_ser.py:137:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `validator` on type `SchemaValidator | PluggableSchemaValidator`
- pydantic/_internal/_mock_val_ser.py:143:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `serializer` of type `SchemaSerializer`
+ pydantic/_internal/_mock_val_ser.py:143:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `serializer` on type `SchemaSerializer`
- pydantic/_internal/_mock_val_ser.py:176:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `__pydantic_validator__` of type `SchemaValidator | PluggableSchemaValidator`
+ pydantic/_internal/_mock_val_ser.py:176:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `__pydantic_validator__` on type `SchemaValidator | PluggableSchemaValidator`
- pydantic/_internal/_mock_val_ser.py:182:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `__pydantic_serializer__` of type `SchemaSerializer`
+ pydantic/_internal/_mock_val_ser.py:182:5: error[invalid-assignment] Object of type `MockValSer[Unknown]` is not assignable to attribute `__pydantic_serializer__` on type `SchemaSerializer`

jinja (https://github.com/pallets/jinja)
- tests/test_bytecode_cache.py:52:9: error[invalid-assignment] Object of type `Literal["code"]` is not assignable to attribute `code` of type `CodeType | None`
+ tests/test_bytecode_cache.py:52:9: error[invalid-assignment] Object of type `Literal["code"]` is not assignable to attribute `code` on type `CodeType | None`
- tests/test_bytecode_cache.py:66:9: error[invalid-assignment] Object of type `Literal["code"]` is not assignable to attribute `code` of type `CodeType | None`
+ tests/test_bytecode_cache.py:66:9: error[invalid-assignment] Object of type `Literal["code"]` is not assignable to attribute `code` on type `CodeType | None`

optuna (https://github.com/optuna/optuna)
- optuna/_gp/search_space.py:181:37: error[invalid-argument-type] Argument to function `_round_one_normalized_param` is incorrect: Expected `_ScaleType`, found `Unknown | ndarray[Unknown, Unknown]`
+ optuna/_gp/search_space.py:181:37: error[invalid-argument-type] Argument to function `_round_one_normalized_param` is incorrect: Expected `_ScaleType`, found `Unknown | ndarray[Unknown, <class 'signedinteger[_64Bit]'>]`
- tests/gp_tests/test_search_space.py:108:13: error[invalid-argument-type] Argument to function `_unnormalize_one_param` is incorrect: Expected `_ScaleType`, found `Unknown | ndarray[Unknown, Unknown]`
+ tests/gp_tests/test_search_space.py:108:13: error[invalid-argument-type] Argument to function `_unnormalize_one_param` is incorrect: Expected `_ScaleType`, found `Unknown | ndarray[Unknown, <class 'signedinteger[_64Bit]'>]`

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
+ src/hydra_zen/structured_configs/_type_guards.py:80:32: error[invalid-argument-type] Argument to function `_get_target` is incorrect: Expected `HasTarget`, found `<class 'Just'>`
- Found 567 diagnostics
+ Found 568 diagnostics

cloud-init (https://github.com/canonical/cloud-init)
- conftest.py:208:5: error[invalid-assignment] Object of type `def my_system_info() -> Unknown` is not assignable to attribute `system_info` of type `_lru_cache_wrapper[Unknown]`
+ conftest.py:208:5: error[invalid-assignment] Object of type `def my_system_info() -> Unknown` is not assignable to attribute `system_info` on type `_lru_cache_wrapper[Unknown]`
- tests/unittests/sources/test_init.py:759:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `network_json` of type `str | None`
+ tests/unittests/sources/test_init.py:759:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `network_json` on type `str | None`
- tests/unittests/sources/test_init.py:778:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `network_json` of type `str | None`
+ tests/unittests/sources/test_init.py:778:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `network_json` on type `str | None`

asynq (https://github.com/quora/asynq)
- asynq/debug.py:324:5: error[invalid-assignment] Object of type `Unknown | None` is not assignable to attribute `excepthook` of type `(type[BaseException], BaseException, TracebackType | None, /) -> Any`
+ asynq/debug.py:324:5: error[invalid-assignment] Object of type `Unknown | None` is not assignable to attribute `excepthook` on type `(type[BaseException], BaseException, TracebackType | None, /) -> Any`

pylox (https://github.com/sco1/pylox)
- pylox/builtins/py_builtins.py:21:5: error[invalid-assignment] Object of type `deque[Unknown]` is not assignable to attribute `fields` of type `dict[Unknown, Unknown]`
+ pylox/builtins/py_builtins.py:21:5: error[invalid-assignment] Object of type `deque[Unknown]` is not assignable to attribute `fields` on type `dict[Unknown, Unknown]`
- pylox/containers/array.py:133:9: error[invalid-assignment] Object of type `deque[Unknown]` is not assignable to attribute `fields` of type `dict[Unknown, Unknown]`
+ pylox/containers/array.py:133:9: error[invalid-assignment] Object of type `deque[Unknown]` is not assignable to attribute `fields` on type `dict[Unknown, Unknown]`

mkdocs (https://github.com/mkdocs/mkdocs)
- mkdocs/tests/structure/page_tests.py:66:9: error[invalid-assignment] Object of type `Literal["foo"]` is not assignable to attribute `parent` of type `Section | None`
+ mkdocs/tests/structure/page_tests.py:66:9: error[invalid-assignment] Object of type `Literal["foo"]` is not assignable to attribute `parent` on type `Section | None`
- mkdocs/tests/structure/page_tests.py:138:9: error[invalid-assignment] Object of type `Literal["foo"]` is not assignable to attribute `parent` of type `Section | None`
+ mkdocs/tests/structure/page_tests.py:138:9: error[invalid-assignment] Object of type `Literal["foo"]` is not assignable to attribute `parent` on type `Section | None`

werkzeug (https://github.com/pallets/werkzeug)
- src/werkzeug/utils.py:512:9: error[invalid-assignment] Object of type `(int & ~((...) -> object)) | (((str | None, /) -> int | None) & ~((...) -> object)) | (@Todo(Type::Intersection.call()) & ~None)` is not assignable to attribute `max_age` of type `int | None`
+ src/werkzeug/utils.py:512:9: error[invalid-assignment] Object of type `(int & ~((...) -> object)) | (((str | None, /) -> int | None) & ~((...) -> object)) | (@Todo(Type::Intersection.call()) & ~None)` is not assignable to attribute `max_age` on type `int | None`
- tests/test_datastructures.py:1009:9: error[invalid-assignment] Object of type `Literal[False]` is not assignable to attribute `no_cache` of type `str | Literal[True] | None`
+ tests/test_datastructures.py:1009:9: error[invalid-assignment] Object of type `Literal[False]` is not assignable to attribute `no_cache` on type `str | Literal[True] | None`
- tests/test_http.py:141:9: error[invalid-assignment] Object of type `float` is not assignable to attribute `max_age` of type `int | None`
+ tests/test_http.py:141:9: error[invalid-assignment] Object of type `float` is not assignable to attribute `max_age` on type `int | None`
- tests/test_http.py:144:9: error[invalid-assignment] Object of type `float` is not assignable to attribute `s_maxage` of type `int | None`
+ tests/test_http.py:144:9: error[invalid-assignment] Object of type `float` is not assignable to attribute `s_maxage` on type `int | None`
- tests/test_security.py:66:5: error[invalid-assignment] Object of type `Literal["*"]` is not assignable to attribute `_os_alt_seps` of type `list[str]`
+ tests/test_security.py:66:5: error[invalid-assignment] Object of type `Literal["*"]` is not assignable to attribute `_os_alt_seps` on type `list[str]`

schema_salad (https://github.com/common-workflow-language/schema_salad)
- schema_salad/tests/test_ref_resolver.py:132:9: error[invalid-assignment] Object of type `Literal["linux2"]` is not assignable to attribute `platform` of type `Literal["linux"]`
+ schema_salad/tests/test_ref_resolver.py:132:9: error[invalid-assignment] Object of type `Literal["linux2"]` is not assignable to attribute `platform` on type `Literal["linux"]`

freqtrade (https://github.com/freqtrade/freqtrade)
- freqtrade/optimize/analysis/lookahead.py:127:9: error[invalid-assignment] Object of type `dict[str, DataFrame]` is not assignable to attribute `data` of type `DataFrame`
+ freqtrade/optimize/analysis/lookahead.py:127:9: error[invalid-assignment] Object of type `dict[str, DataFrame]` is not assignable to attribute `data` on type `DataFrame`
- freqtrade/optimize/analysis/recursive.py:151:9: error[invalid-assignment] Object of type `dict[str, DataFrame]` is not assignable to attribute `data` of type `DataFrame`
+ freqtrade/optimize/analysis/recursive.py:151:9: error[invalid-assignment] Object of type `dict[str, DataFrame]` is not assignable to attribute `data` on type `DataFrame`

dragonchain (https://github.com/dragonchain/dragonchain)
- dragonchain/lib/interfaces/storage_utest.py:43:9: error[invalid-assignment] Object of type `MagicMock` is not assignable to attribute `storage` of type `<module 'dragonchain.lib.interfaces.aws.s3'> | <module 'dragonchain.lib.interfaces.local.disk'>`
+ dragonchain/lib/interfaces/storage_utest.py:43:9: error[invalid-assignment] Object of type `MagicMock` is not assignable to attribute `storage` on type `<module 'dragonchain.lib.interfaces.aws.s3'> | <module 'dragonchain.lib.interfaces.local.disk'>`

urllib3 (https://github.com/urllib3/urllib3)
- src/urllib3/util/ssl_.py:301:9: error[invalid-assignment] Object of type `int | (Unknown & ~None)` is not assignable to attribute `minimum_version` of type `TLSVersion`
+ src/urllib3/util/ssl_.py:301:9: error[invalid-assignment] Object of type `int | (Unknown & ~None)` is not assignable to attribute `minimum_version` on type `TLSVersion`
- src/urllib3/util/ssl_.py:306:9: error[invalid-assignment] Object of type `int | (Unknown & ~None)` is not assignable to attribute `maximum_version` of type `TLSVersion`
+ src/urllib3/util/ssl_.py:306:9: error[invalid-assignment] Object of type `int | (Unknown & ~None)` is not assignable to attribute `maximum_version` on type `TLSVersion`
- src/urllib3/util/ssl_.py:356:9: error[invalid-assignment] Object of type `int` is not assignable to attribute `verify_mode` of type `VerifyMode`
+ src/urllib3/util/ssl_.py:356:9: error[invalid-assignment] Object of type `int` is not assignable to attribute `verify_mode` on type `VerifyMode`
- src/urllib3/util/ssl_.py:360:9: error[invalid-assignment] Object of type `int` is not assignable to attribute `verify_mode` of type `VerifyMode`
+ src/urllib3/util/ssl_.py:360:9: error[invalid-assignment] Object of type `int` is not assignable to attribute `verify_mode` on type `VerifyMode`
- test/conftest.py:387:13: error[invalid-assignment] Object of type `None | <class 'HTTPConnection'>` is not assignable to attribute `ConnectionCls` of type `type[@Todo(type[T] for protocols)]`
+ test/conftest.py:387:13: error[invalid-assignment] Object of type `None | <class 'HTTPConnection'>` is not assignable to attribute `ConnectionCls` on type `type[@Todo(type[T] for protocols)]`

bokeh (https://github.com/bokeh/bokeh)
- src/bokeh/server/contexts.py:233:13: error[invalid-assignment] Object of type `ReferenceType[BokehSessionContext]` is not assignable to attribute `_session_context` of type `ReferenceType[SessionContext] | None`
+ src/bokeh/server/contexts.py:233:13: error[invalid-assignment] Object of type `ReferenceType[BokehSessionContext]` is not assignable to attribute `_session_context` on type `ReferenceType[SessionContext] | None`

mitmproxy (https://github.com/mitmproxy/mitmproxy)
- examples/addons/contentview-interactive.py:20:18: error[invalid-argument-type] Argument to function `add` is incorrect: Expected `Contentview`, found `<class 'InteractiveSwapCase'>`
- examples/addons/contentview.py:15:18: error[invalid-argument-type] Argument to function `add` is incorrect: Expected `Contentview`, found `<class 'SwapCase'>`
- examples/contrib/search.py:58:17: error[invalid-assignment] Object of type `Literal[False]` is not assignable to attribute `marked` of type `str`
+ examples/contrib/search.py:58:17: error[invalid-assignment] Object of type `Literal[False]` is not assignable to attribute `marked` on type `str`
- examples/contrib/webscanner_helper/test_watchdog.py:56:9: error[invalid-assignment] Object of type `Literal["Test Error"]` is not assignable to attribute `error` of type `Error | None`
+ examples/contrib/webscanner_helper/test_watchdog.py:56:9: error[invalid-assignment] Object of type `Literal["Test Error"]` is not assignable to attribute `error` on type `Error | None`
- test/mitmproxy/addons/test_clientplayback.py:182:5: error[invalid-assignment] Object of type `None` is not assignable to attribute `request` of type `Request`
+ test/mitmproxy/addons/test_clientplayback.py:182:5: error[invalid-assignment] Object of type `None` is not assignable to attribute `request` on type `Request`
- test/mitmproxy/addons/test_proxyauth.py:243:13: error[invalid-assignment] Object of type `Literal[True]` is not assignable to attribute `is_replay` of type `str | None`
+ test/mitmproxy/addons/test_proxyauth.py:243:13: error[invalid-assignment] Object of type `Literal[True]` is not assignable to attribute `is_replay` on type `str | None`
- test/mitmproxy/contentviews/test__registry.py:67:23: error[invalid-argument-type] Argument to bound method `register` is incorrect: Expected `Contentview`, found `<class 'ExampleContentview'>`
- test/mitmproxy/proxy/layers/http/test_http3.py:564:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `stream` of type `((bytes, /) -> Iterable[bytes]) | bool`
+ test/mitmproxy/proxy/layers/http/test_http3.py:564:9: error[invalid-assignment] Object of type `str` is not assignable to attribute `stream` on type `((bytes, /) -> Iterable[bytes]) | bool`
- test/mitmproxy/test_flow.py:39:9: error[invalid-assignment] Object of type `Literal[True]` is not assignable to attribute `marked` of type `str`
+ test/mitmproxy/test_flow.py:39:9: error[invalid-assignment] Object of type `Literal[True]` is not assignable to attribute `marked` on type `str`
- Found 1825 diagnostics
+ Found 1822 diagnostics

scrapy (https://github.com/scrapy/scrapy)
- tests/test_downloadermiddleware_httpproxy.py:29:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `environ` of type `_Environ[str]`
+ tests/test_downloadermiddleware_httpproxy.py:29:9: error[invalid-assignment] Object of type `dict[@Todo(dict literal key type), @Todo(dict literal value type)]` is not assignable to attribute `environ` on type `_Environ[str]`

PyGithub (https://github.com/PyGithub/PyGithub)
- github/GithubObject.py:309:45: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- github/GithubObject.py:316:44: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- github/GithubObject.py:376:44: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- github/GithubObject.py:390:44: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- github/GithubObject.py:402:44: warning[unused-ignore-comment] Unused blanket `type: ignore` directive
- Found 311 diagnostics
+ Found 306 diagnostics

sphinx (https://github.com/sphinx-doc/sphinx)
- sphinx/transforms/i18n.py:88:9: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_source` of type `str`
+ sphinx/transforms/i18n.py:88:9: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_source` on type `str`
- sphinx/transforms/i18n.py:88:30: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_line` of type `str`
+ sphinx/transforms/i18n.py:88:30: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_line` on type `str`
- sphinx/util/docutils.py:891:9: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_source` of type `str`
+ sphinx/util/docutils.py:891:9: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_source` on type `str`
- sphinx/util/docutils.py:891:35: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_line` of type `str`
+ sphinx/util/docutils.py:891:35: error[invalid-assignment] Object of type `None` is not assignable to attribute `current_line` on type `str`

meson (https://github.com/mesonbuild/meson)
- run_project_tests.py:557:5: error[invalid-assignment] Object of type `PerMachine[None]` is not assignable to attribute `class_cmakeinfo` of type `PerMachine[CMakeInfo | None]`
+ run_project_tests.py:557:5: error[invalid-assignment] Object of type `PerMachine[None]` is not assignable to attribute `class_cmakeinfo` on type `PerMachine[CMakeInfo | None]`
- run_project_tests.py:558:5: error[invalid-assignment] Object of type `PerMachine[bool]` is not assignable to attribute `class_impl` of type `PerMachine[Literal[False] | PkgConfigInterface | None]`
+ run_project_tests.py:558:5: error[invalid-assignment] Object of type `PerMachine[bool]` is not assignable to attribute `class_impl` on type `PerMachine[Literal[False] | PkgConfigInterface | None]`
- run_project_tests.py:559:5: error[invalid-assignment] Object of type `PerMachine[bool]` is not assignable to attribute `class_cli_impl` of type `PerMachine[Literal[False] | PkgConfigCLI | None]`
+ run_project_tests.py:559:5: error[invalid-assignment] Object of type `PerMachine[bool]` is not assignable to attribute `class_cli_impl` on type `PerMachine[Literal[False] | PkgConfigCLI | None]`
- run_project_tests.py:560:5: error[invalid-assignment] Object of type `PerMachine[None]` is not assignable to attribute `pkg_bin_per_machine` of type `PerMachine[ExternalProgram | None]`
+ run_project_tests.py:560:5: error[invalid-assignment] Object of type `PerMachine[None]` is not assignable to attribute `pkg_bin_per_machine` on type `PerMachine[ExternalProgram | None]`
- run_tests.py:141:5: error[invalid-assignment] Object of type `None` is not assignable to attribute `cross_file` of type `list[str]`
+ run_tests.py:141:5: error[invalid-assignment] Object of type `None` is not assignable to attribute `cross_file` on type `list[str]`
- unittests/internaltests.py:461:9: error[invalid-assignment] Object of type `tuple[str]` is not assignable to attribute `cross_file` of type `list[str]`
+ unittests/internaltests.py:461:9: error[invalid-assignment] Object of type `tuple[str]` is not assignable to attribute `cross_file` on type `list[str]`
- unittests/internaltests.py:476:9: error[invalid-assignment] Object of type `tuple[str]` is not assignable to attribute `cross_file` of type `list[str]`
+ unittests/internaltests.py:476:9: error[invalid-assignment] Object of type `tuple[str]` is not assignable to attribute `cross_file` on type `list[str]`

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/api/deployments.py:247:13: error[invalid-assignment] Object of type `None` is not assignable to attribute `schedules` of type `list[DeploymentScheduleUpdate]`
+ src/prefect/server/api/deployments.py:247:13: error[invalid-assignment] Object of type `None` is not assignable to attribute `schedules` on type `list[DeploymentScheduleUpdate]`

rotki (https://github.com/rotki/rotki)
- rotkehlchen/tests/fixtures/messages.py:65:9: error[invalid-assignment] Object of type `MockRotkiNotifier` is not assignable to attribute `rotki_notifier` of type `RotkiNotifier | None`
+ rotkehlchen/tests/fixtures/messages.py:65:9: error[invalid-assignment] Object of type `MockRotkiNotifier` is not assignable to attribute `rotki_notifier` on type `RotkiNotifier | None`
- rotkehlchen/tests/fixtures/messages.py:73:9: error[invalid-assignment] Object of type `MockRotkiNotifier` is not assignable to attribute `rotki_notifier` of type `RotkiNotifier | None`
+ rotkehlchen/tests/fixtures/messages.py:73:9: error[invalid-assignment] Object of type `MockRotkiNotifier` is not assignable to attribute `rotki_notifier` on type `RotkiNotifier | None`

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ddtrace/settings/errortracking.py:44:5: error[invalid-assignment] Object of type `Unknown | EnvVariable[list[@Todo(list literal element type)]]` is not assignable to attribute `_configured_modules` of type `list[str]`
+ ddtrace/settings/errortracking.py:44:5: error[invalid-assignment] Object of type `Unknown | EnvVariable[list[@Todo(list literal element type)]]` is not assignable to attribute `_configured_modules` on type `list[str]`
- tests/smoke_test.py:58:13: error[invalid-assignment] Object of type `dict[str, str]` is not assignable to attribute `environ` of type `_Environ[str]`
+ tests/smoke_test.py:58:13: error[invalid-assignment] Object of type `dict[str, str]` is not assignable to attribute `environ` on type `_Environ[str]`

zulip (https://github.com/zulip/zulip)
- zerver/decorator.py:886:17: error[invalid-assignment] Object of type `QueryDict` is not assignable to attribute `POST` of type `_ImmutableQueryDict`
+ zerver/decorator.py:886:17: error[invalid-assignment] Object of type `QueryDict` is not assignable to attribute `POST` on type `_ImmutableQueryDict`

manticore (https://github.com/trailofbits/manticore)
- tests/native/test_memory.py:1875:9: error[invalid-assignment] Object of type `MagicMock` is not assignable to attribute `sys` of type `<module 'sys'>`
+ tests/native/test_memory.py:1875:9: error[invalid-assignment] Object of type `MagicMock` is not assignable to attribute `sys` on type `<module 'sys'>`

sympy (https://github.com/sympy/sympy)
- sympy/physics/biomechanics/tests/test_curve.py:1683:13: error[invalid-assignment] Property `tendon_force_length` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1683:13: error[invalid-assignment] Attribute `tendon_force_length` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1685:13: error[invalid-assignment] Property `tendon_force_length_inverse` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1685:13: error[invalid-assignment] Attribute `tendon_force_length_inverse` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1687:13: error[invalid-assignment] Property `fiber_force_length_passive` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1687:13: error[invalid-assignment] Attribute `fiber_force_length_passive` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1689:13: error[invalid-assignment] Property `fiber_force_length_passive_inverse` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1689:13: error[invalid-assignment] Attribute `fiber_force_length_passive_inverse` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1691:13: error[invalid-assignment] Property `fiber_force_length_active` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1691:13: error[invalid-assignment] Attribute `fiber_force_length_active` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1693:13: error[invalid-assignment] Property `fiber_force_velocity` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1693:13: error[invalid-assignment] Attribute `fiber_force_velocity` on object of type `CharacteristicCurveCollection` is read-only
- sympy/physics/biomechanics/tests/test_curve.py:1695:13: error[invalid-assignment] Property `fiber_force_velocity_inverse` defined in `CharacteristicCurveCollection` is read-only
+ sympy/physics/biomechanics/tests/test_curve.py:1695:13: error[invalid-assignment] Attribute `fiber_force_velocity_inverse` on object of type `CharacteristicCurveCollection` is read-only

scipy (https://github.com/scipy/scipy)
- scipy/stats/_mstats_extras.py:88:13: error[invalid-assignment] Cannot assign to read-only property `flat` on object of type `ndarray[tuple[int, int], Unknown]`: Attempted assignment to `ndarray[tuple[int, int], Unknown].flat` here
+ scipy/stats/_mstats_extras.py:88:13: error[invalid-assignment] Cannot assign to read-only property `flat` on object of type `ndarray[tuple[int, int], <class 'float64'>]`: Attempted assignment to `ndarray[tuple[int, int], <class 'float64'>].flat` here
- scipy/stats/_mstats_extras.py:181:13: error[invalid-assignment] Cannot assign to read-only property `flat` on object of type `ndarray[tuple[int], Unknown]`: Attempted assignment to `ndarray[tuple[int], Unknown].flat` here
+ scipy/stats/_mstats_extras.py:181:13: error[invalid-assignment] Cannot assign to read-only property `flat` on object of type `ndarray[tuple[int], <class 'float64'>]`: Attempted assignment to `ndarray[tuple[int], <class 'float64'>].flat` here
No memory usage changes detected ✅

@github-actions
Copy link
Contributor

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-argument-type 1 161 2
invalid-assignment 4 23 64
invalid-return-type 1 8 1
unused-ignore-comment 4 2 0
missing-argument 0 2 0
unresolved-attribute 0 2 0
invalid-parameter-default 0 0 1
Total 10 198 68

Full report with detailed diff

@AlexWaygood AlexWaygood force-pushed the alex/protocol-property-check-2 branch from b620d8c to 1c2af48 Compare August 19, 2025 15:48
@codspeed-hq
Copy link

codspeed-hq bot commented Aug 27, 2025

CodSpeed Performance Report

Merging #19936 will not alter performance

Comparing alex/protocol-property-check-2 (f57ea60) with main (c2d7c67)

Summary

✅ 9 untouched

@AlexWaygood AlexWaygood force-pushed the alex/protocol-property-check-2 branch from 6f2904b to 7068132 Compare August 27, 2025 18:09
@AlexWaygood AlexWaygood force-pushed the alex/protocol-property-check-2 branch from 7068132 to 971156a Compare August 27, 2025 18:17
@AlexWaygood AlexWaygood force-pushed the alex/protocol-property-check-2 branch from d3c8776 to 7b9f9eb Compare August 27, 2025 19:05
@AlexWaygood AlexWaygood force-pushed the alex/protocol-property-check-2 branch from 7b9f9eb to d10ea72 Compare August 27, 2025 19:09
@AlexWaygood AlexWaygood changed the title alex/protocol property check 2 [ty] Fix subtyping/assignability for @property protocol members Sep 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support ClassVar protocol members Properly support @property members on protocols

2 participants