Skip to content

[ty] Reimplement equivalence as mutual redundancy#23428

Merged
AlexWaygood merged 38 commits intomainfrom
alex-carl/die-normalization
Feb 25, 2026
Merged

[ty] Reimplement equivalence as mutual redundancy#23428
AlexWaygood merged 38 commits intomainfrom
alex-carl/die-normalization

Conversation

@AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Feb 19, 2026

Summary

Equivalence is now implemented via "mutual redundancy"* rather than a custom deeply recursive query. This change:

  • Fixes many previously failing TODO tests
  • Removes ~1,800 lines of code on net
  • Breaks the requirement of our equivalence implementation that all unions and intersections must be aggressively simplified. This opens the door to experimenting with looser union/intersection simplification in the future, which may be necessary in some situations for deterministic behaviour.
  • Gives self.is_equivalent_to(db, other) the same performance characteristics as self.is_subtype_of(db, other) && other.is_subtype_of(db, self), removing a major footgun from the codebase

(*Well, in actual fact, we introduce yet another TypeRelation variant to achieve this rather than reusing the existing Redundancy variant. I've called it "PureRedundancy" currently, but the name can be bikeshedded. It works exactly the same way as Redundancy, except that it makes sure that Literal[False] is always equivalent to Literal[False], whereas Literal[False] is not always redundant with Literal[False] if the first Literal[False] is promotable and the second is not.)

Test Plan

  • Mdtests updated and extended.
  • Ran QUICKCHECK_TESTS=1000000 cargo test --profile=profiling -p ty_python_semantic -- --ignored types::property_tests::stable locally

Co-authored-by: Carl Meyer [email protected]

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Feb 19, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 19, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 19, 2026

mypy_primer results

Changes were detected when running on open source projects
spack (https://github.com/spack/spack)
- lib/spack/spack/detection/path.py:169:33: error[invalid-argument-type] Argument to function `dedupe_paths` is incorrect: Expected `list[str]`, found `Unknown | list[int | str | bytes | ... omitted 3 union elements]`
+ lib/spack/spack/detection/path.py:169:33: error[invalid-argument-type] Argument to function `dedupe_paths` is incorrect: Expected `list[str]`, found `Unknown | list[str | bytes | PathLike[str] | ... omitted 3 union elements]`

pip (https://github.com/pypa/pip)
- src/pip/_internal/req/req_uninstall.py:132:42: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Unknown | Sized`
+ src/pip/_internal/req/req_uninstall.py:132:42: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Sized | Unknown`
- src/pip/_internal/req/req_uninstall.py:133:40: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Unknown | Sized`
+ src/pip/_internal/req/req_uninstall.py:133:40: error[invalid-argument-type] Argument to function `norm_join` is incorrect: Expected `str`, found `Sized | Unknown`
- src/pip/_internal/req/req_uninstall.py:139:27: error[unsupported-operator] Operator `+` is not supported between objects of type `Unknown | Sized` and `LiteralString`
+ src/pip/_internal/req/req_uninstall.py:139:27: error[unsupported-operator] Operator `+` is not supported between objects of type `Sized | Unknown` and `LiteralString`

graphql-core (https://github.com/graphql-python/graphql-core)
- src/graphql/execution/execute.py:1607:23: warning[redundant-cast] Value is already of type `Awaitable[ExecutionResult]`
- src/graphql/execution/execute.py:2280:27: warning[redundant-cast] Value is already of type `Awaitable[ExecutionResult]`
- src/graphql/execution/execute.py:2440:41: warning[redundant-cast] Value is already of type `Awaitable[bool]`
- src/graphql/graphql.py:108:22: warning[redundant-cast] Value is already of type `Awaitable[ExecutionResult]`
- src/graphql/pyutils/async_reduce.py:47:42: warning[redundant-cast] Value is already of type `Awaitable[U@async_reduce]`
- Found 641 diagnostics
+ Found 636 diagnostics

pytest (https://github.com/pytest-dev/pytest)
- src/_pytest/fixtures.py:787:45: error[unresolved-attribute] Object of type `((...) -> object) | ((...) -> Generator[object, None, None])` has no attribute `__name__`
+ src/_pytest/fixtures.py:787:45: error[unresolved-attribute] Object of type `(...) -> object` has no attribute `__name__`

rich (https://github.com/Textualize/rich)
- tests/test_tools.py:17:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, str | Unknown]]`
+ tests/test_tools.py:17:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, Unknown | str]]`
- tests/test_tools.py:18:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, str | Unknown]]`
+ tests/test_tools.py:18:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, Unknown | str]]`
- tests/test_tools.py:19:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, str | Unknown]]`
+ tests/test_tools.py:19:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, Unknown | str]]`
- tests/test_tools.py:20:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, str | Unknown]]`
+ tests/test_tools.py:20:17: error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `Iterable[tuple[bool, Unknown | str]]`

nox (https://github.com/wntrblm/nox)
- nox/registry.py:91:16: error[invalid-return-type] Return type does not match returned value: expected `Func | ((((...) -> Any) | Func, /) -> Func)`, found `partial[Func | ((((...) -> Any) | Func, /) -> Func)]`
+ nox/registry.py:91:16: error[invalid-return-type] Return type does not match returned value: expected `Func | (((...) -> Any, /) -> Func)`, found `partial[Func | (((...) -> Any, /) -> Func)]`

mitmproxy (https://github.com/mitmproxy/mitmproxy)
- test/mitmproxy/proxy/test_server.py:62:13: error[invalid-assignment] Object of type `def _kill(d: ServerConnectionHookData) -> None` is not assignable to attribute `side_effect` on type `Mock | ((...) -> Unknown)`
- test/mitmproxy/proxy/test_server.py:68:12: error[unresolved-attribute] Attribute `call_args` is not defined on `(...) -> Unknown` in union `Mock | ((...) -> Unknown)`
+ test/mitmproxy/proxy/test_server.py:62:13: error[unresolved-attribute] Unresolved attribute `side_effect` on type `(...) -> Unknown`
+ test/mitmproxy/proxy/test_server.py:68:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `call_args`
- test/mitmproxy/proxy/test_server.py:70:12: error[unresolved-attribute] Attribute `called` is not defined on `(...) -> Unknown` in union `Mock | ((...) -> Unknown)`
+ test/mitmproxy/proxy/test_server.py:70:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `called`
- test/mitmproxy/proxy/test_server.py:71:12: error[unresolved-attribute] Attribute `called` is not defined on `(...) -> Unknown` in union `Mock | ((...) -> Unknown)`
+ test/mitmproxy/proxy/test_server.py:71:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `called`
- test/mitmproxy/proxy/test_server.py:73:12: error[unresolved-attribute] Attribute `called` is not defined on `(...) -> Unknown` in union `Mock | ((...) -> Unknown)`
+ test/mitmproxy/proxy/test_server.py:73:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `called`

antidote (https://github.com/Finistere/antidote)
- src/antidote/core/_raw/wrapper.py:102:13: error[unresolved-attribute] Attribute `__get__` is not defined on `(...) -> object` in union `((...) -> object) | ((...) -> object)`
+ src/antidote/core/_raw/wrapper.py:102:13: error[unresolved-attribute] Object of type `(...) -> object` has no attribute `__get__`
- src/antidote/core/_raw/wrapper.py:136:13: error[unresolved-attribute] Attribute `__get__` is not defined on `(...) -> Awaitable[object]` in union `((...) -> Awaitable[object]) | ((...) -> Awaitable[object])`
+ src/antidote/core/_raw/wrapper.py:136:13: error[unresolved-attribute] Object of type `(...) -> Awaitable[object]` has no attribute `__get__`

artigraph (https://github.com/artigraph/artigraph)
- tests/arti/types/test_types.py:100:51: error[invalid-argument-type] Argument is incorrect: Expected `frozenset[Any]`, found `frozenset[float | Unknown | int] | list[Unknown | int | float] | tuple[float | Unknown | int, ...]`
+ tests/arti/types/test_types.py:100:51: error[invalid-argument-type] Argument is incorrect: Expected `frozenset[Any]`, found `frozenset[float | Unknown | int] | list[int | Unknown | float] | tuple[float | Unknown | int, ...]`

xarray (https://github.com/pydata/xarray)
- xarray/tests/test_plot.py:1316:53: error[unresolved-attribute] Attribute `__name__` is not defined on `(...) -> Unknown` in union `((...) -> Unknown) | staticmethod[(...), Unknown]`
- xarray/tests/test_plot.py:1336:12: error[unresolved-attribute] Attribute `__name__` is not defined on `(...) -> Unknown` in union `((...) -> Unknown) | staticmethod[(...), Unknown]`
- xarray/tests/test_plot.py:1343:12: error[unresolved-attribute] Attribute `__name__` is not defined on `(...) -> Unknown` in union `((...) -> Unknown) | staticmethod[(...), Unknown]`
+ xarray/tests/test_plot.py:1316:53: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `__name__`
+ xarray/tests/test_plot.py:1336:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `__name__`
+ xarray/tests/test_plot.py:1343:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `__name__`
- xarray/tests/test_plot.py:1421:12: error[unresolved-attribute] Attribute `__name__` is not defined on `(...) -> Unknown` in union `((...) -> Unknown) | staticmethod[(...), Unknown]`
+ xarray/tests/test_plot.py:1421:12: error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `__name__`

openlibrary (https://github.com/internetarchive/openlibrary)
- openlibrary/catalog/utils/__init__.py:132:17: error[unresolved-attribute] Attribute `search` is not defined on `str` in union `Unknown | str`
+ openlibrary/catalog/utils/__init__.py:132:17: error[unresolved-attribute] Attribute `search` is not defined on `str` in union `str | Unknown`

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
- tests/annotations/declarations.py:929:5: error[type-assertion-failure] Type `StdBuilds[Unknown]` does not match asserted type `StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:929:5: error[type-assertion-failure] Type `StdBuilds[Unknown]` does not match asserted type `StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:934:5: error[type-assertion-failure] Type `StdBuilds[Unknown]` does not match asserted type `StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:934:5: error[type-assertion-failure] Type `StdBuilds[Unknown]` does not match asserted type `StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:940:5: error[type-assertion-failure] Type `PBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:940:5: error[type-assertion-failure] Type `PBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:944:5: error[type-assertion-failure] Type `PBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:944:5: error[type-assertion-failure] Type `PBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:945:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `PBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:945:5: error[type-assertion-failure] Type `Unknown` does not match asserted type `PBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:951:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 20 union elements] | StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:951:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 19 union elements] | StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:956:5: error[type-assertion-failure] Type `PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 20 union elements] | StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:956:5: error[type-assertion-failure] Type `PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 19 union elements] | StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:961:5: error[type-assertion-failure] Type `PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 20 union elements] | StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:961:5: error[type-assertion-failure] Type `PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `PBuilds[int | None | float | ... omitted 19 union elements] | StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:969:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 20 union elements] | PBuilds[int | None | float | ... omitted 20 union elements] | StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:969:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 19 union elements] | PBuilds[int | None | float | ... omitted 19 union elements] | StdBuilds[int | None | float | ... omitted 19 union elements]`
- tests/annotations/declarations.py:980:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 20 union elements] | PBuilds[int | None | float | ... omitted 20 union elements] | StdBuilds[int | None | float | ... omitted 20 union elements]`
+ tests/annotations/declarations.py:980:5: error[type-assertion-failure] Type `FullBuilds[Unknown] | PBuilds[Unknown] | StdBuilds[Unknown]` does not match asserted type `FullBuilds[int | None | float | ... omitted 19 union elements] | PBuilds[int | None | float | ... omitted 19 union elements] | StdBuilds[int | None | float | ... omitted 19 union elements]`

prefect (https://github.com/PrefectHQ/prefect)
+ src/integrations/prefect-ray/tests/test_task_runners.py:342:23: error[invalid-await] `State[CoroutineType[Any, Any, Unknown]]` is not awaitable
- src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `Unknown | Coroutine[Any, Any, Unknown]`
+ src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler] | Coroutine[Any, Any, T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]]`
- Found 5777 diagnostics
+ Found 5778 diagnostics

altair (https://github.com/vega/altair)
- altair/utils/schemapi.py:509:12: error[invalid-return-type] Return type does not match returned value: expected `list[Any]`, found `object`
- Found 1082 diagnostics
+ Found 1081 diagnostics

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- scripts/freshvenvs.py:343:69: error[invalid-argument-type] Argument to function `_versions_fully_cover_bounds` is incorrect: Expected `list[str]`, found `list[Unknown | Version] & ~AlwaysFalsy`
+ scripts/freshvenvs.py:343:69: error[invalid-argument-type] Argument to function `_versions_fully_cover_bounds` is incorrect: Expected `list[str]`, found `list[Version | Unknown] & ~AlwaysFalsy`
- tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:31:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `MethodType | FunctionType | CodeType | ... omitted 6 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
+ tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:31:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `((...) -> Any) | CodeType | str | ... omitted 3 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
- tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:60:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `MethodType | FunctionType | CodeType | ... omitted 6 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
+ tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:60:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `((...) -> Any) | CodeType | str | ... omitted 3 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
- tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:89:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `MethodType | FunctionType | CodeType | ... omitted 6 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
+ tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:89:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `((...) -> Any) | CodeType | str | ... omitted 3 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app_main_patched'>`
- tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:119:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `MethodType | FunctionType | CodeType | ... omitted 6 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app'>`
+ tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:119:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `((...) -> Any) | CodeType | str | ... omitted 3 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.app'>`
- tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:149:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `MethodType | FunctionType | CodeType | ... omitted 6 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.views'>`
+ tests/appsec/integrations/flask_tests/test_iast_flask_entrypoint_iast_patches.py:149:17: error[invalid-argument-type] Argument to function `dis` is incorrect: Expected `((...) -> Any) | CodeType | str | ... omitted 3 union elements`, found `<module 'tests.appsec.iast.fixtures.entrypoint.views'>`
- tests/tracer/test_span.py:193:29: error[invalid-argument-type] Argument to bound method `set_metric` is incorrect: Expected `int | float`, found `int | Unknown | None | ... omitted 6 union elements`
+ tests/tracer/test_span.py:193:29: error[invalid-argument-type] Argument to bound method `set_metric` is incorrect: Expected `int | float`, found `int | float | complex | ... omitted 6 union elements`

manticore (https://github.com/trailofbits/manticore)
- manticore/core/smtlib/visitors.py:641:58: error[unsupported-operator] Operator `-` is not supported between objects of type `None | Unknown` and `None | Unknown`
+ manticore/core/smtlib/visitors.py:641:58: error[unsupported-operator] Operator `-` is not supported between two objects of type `None | Unknown`

ibis (https://github.com/ibis-project/ibis)
- ibis/selectors.py:333:16: error[invalid-return-type] Return type does not match returned value: expected `frozenset[str]`, found `frozenset[str | Buffer | Unknown]`
+ ibis/selectors.py:333:16: error[invalid-return-type] Return type does not match returned value: expected `frozenset[str]`, found `frozenset[Unknown | str | Buffer]`
- ibis/selectors.py:428:13: error[invalid-assignment] Object of type `frozenset[str | Unknown]` is not assignable to `tuple[str | Column, ...]`
+ ibis/selectors.py:428:13: error[invalid-assignment] Object of type `frozenset[Unknown | str]` is not assignable to `tuple[str | Column, ...]`

bokeh (https://github.com/bokeh/bokeh)
- src/bokeh/layouts.py:670:21: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[L@_parse_children_arg]`, found `tuple[L@_parse_children_arg | list[L@_parse_children_arg], ...]`
+ src/bokeh/layouts.py:670:16: error[invalid-return-type] Return type does not match returned value: expected `list[L@_parse_children_arg]`, found `list[L@_parse_children_arg | list[L@_parse_children_arg]]`

sympy (https://github.com/sympy/sympy)
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
- sympy/algebras/tests/test_quaternion.py:76:10: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/algebras/tests/test_quaternion.py:76:10: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/algebras/tests/test_quaternion.py:423:33: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/codegen/tests/test_matrix_nodes.py:28:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/diffgeom/diffgeom.py:507:24: error[unsupported-operator] Operator `<=` is not supported between objects of type `Unknown | int | list[Unknown]` and `Unknown | int | list[Unknown]`
+ sympy/diffgeom/diffgeom.py:507:24: error[unsupported-operator] Operator `<=` is not supported between two objects of type `Unknown | int | list[Unknown]`
- sympy/functions/combinatorial/factorials.py:967:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
+ sympy/functions/combinatorial/factorials.py:967:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:968:29: error[unresolved-attribute] Attribute `is_nonnegative` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:968:47: error[unresolved-attribute] Attribute `is_integer` is not defined on `int`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:969:12: error[unresolved-attribute] Attribute `is_zero` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:972:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:972:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:975:12: error[unresolved-attribute] Attribute `is_integer` is not defined on `int`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:976:16: error[unresolved-attribute] Attribute `is_negative` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:978:18: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:984:14: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:986:26: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:986:26: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
- sympy/functions/combinatorial/factorials.py:986:40: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:986:40: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
- sympy/functions/combinatorial/factorials.py:986:53: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
+ sympy/functions/combinatorial/factorials.py:986:53: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
- sympy/geometry/point.py:1296:25: error[unresolved-attribute] Attribute `tolist` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/geometry/point.py:1296:25: error[unresolved-attribute] Attribute `tolist` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/geometry/polygon.py:1501:12: error[unresolved-attribute] Attribute `is_Number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/geometry/polygon.py:1502:20: error[invalid-argument-type] Argument to function `as_int` is incorrect: Expected `SupportsIndex`, found `Basic`
+ sympy/geometry/polygon.py:1502:20: error[invalid-argument-type] Argument to function `as_int` is incorrect: Expected `SupportsIndex`, found `Basic | int | float | complex | Any`
- sympy/geometry/polygon.py:1503:16: error[unsupported-operator] Operator `<` is not supported between objects of type `Basic` and `Literal[3]`
+ sympy/geometry/polygon.py:1503:16: error[unsupported-operator] Operator `<` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[3]`
+ sympy/geometry/polygon.py:1510:40: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/integrals/tests/test_heurisch.py:390:17: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/integrals/tests/test_heurisch.py:391:26: error[not-subscriptable] Cannot subscript object of type `Expr` with no `__getitem__` method
+ sympy/matrices/decompositions.py:1321:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/decompositions.py:1336:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/decompositions.py:1321:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/decompositions.py:1334:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
- sympy/matrices/decompositions.py:1336:16: error[unresolved-attribute] Attribute `diagonalize` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/decompositions.py:1348:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
- sympy/matrices/decompositions.py:1350:12: error[invalid-return-type] Return type does not match returned value: expected `tuple[Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition]`, found `tuple[Unknown | MatrixBase, MatrixBase, MatrixBase | Unknown]`
+ sympy/matrices/decompositions.py:1350:12: error[invalid-return-type] Return type does not match returned value: expected `tuple[Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition, Tmat@_singular_value_decomposition]`, found `tuple[MatrixBase | Expr | Unknown, MatrixBase, MatrixBase | Expr | Unknown]`
- sympy/matrices/eigen.py:328:22: error[invalid-argument-type] Argument to bound method `_as_type` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown`
- sympy/matrices/eigen.py:1202:37: error[unresolved-attribute] Object of type `T2'return@call_highest_priority | T1'return@call_highest_priority` has no attribute `pow`
- sympy/matrices/expressions/hadamard.py:82:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Basic`
+ sympy/matrices/expressions/hadamard.py:82:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `int | Any | Basic | float | complex`
- sympy/matrices/expressions/kronecker.py:110:16: error[unresolved-attribute] Object of type `Basic` has no attribute `is_Identity`
- sympy/matrices/expressions/kronecker.py:111:33: error[unresolved-attribute] Object of type `Basic` has no attribute `rows`
+ sympy/matrices/expressions/kronecker.py:110:16: error[unresolved-attribute] Attribute `is_Identity` is not defined on `int`, `Basic`, `float`, `complex` in union `int | Any | Basic | float | complex`
+ sympy/matrices/expressions/kronecker.py:111:33: error[unresolved-attribute] Attribute `rows` is not defined on `int`, `Basic`, `float`, `complex` in union `int | Any | Basic | float | complex`
- sympy/matrices/expressions/matadd.py:61:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Unknown | Basic`
+ sympy/matrices/expressions/matadd.py:61:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Unknown | int | Basic | float | complex`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:13: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:33: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:53: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:460:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_derivatives.py:552:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matadd.py:37:12: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase` and `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_matmul.py:159:68: error[unresolved-attribute] Attribute `as_explicit` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/expressions/tests/test_permutation.py:28:12: error[unresolved-attribute] Attribute `as_explicit` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matmul.py:159:68: error[unresolved-attribute] Attribute `as_explicit` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matpow.py:124:46: error[unsupported-operator] Operator `**` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Literal[2]`
- sympy/matrices/expressions/tests/test_matpow.py:125:47: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/expressions/tests/test_permutation.py:28:12: error[unresolved-attribute] Attribute `as_explicit` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/inverse.py:384:11: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase`
- sympy/matrices/inverse.py:392:11: error[unsupported-operator] Unary operator `-` is not supported for object of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/inverse.py:393:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MatrixBase | Expr`
- sympy/matrices/inverse.py:393:22: error[unsupported-operator] Unary operator `-` is not supported for object of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/matrixbase.py:979:18: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@_eval_wilkinson`
- sympy/matrices/matrixbase.py:2955:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T2'return@call_highest_priority` and `Self@_eval_pow_by_cayley`
- sympy/matrices/matrixbase.py:2955:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T1'return@call_highest_priority` and `Self@_eval_pow_by_cayley`
- sympy/matrices/matrixbase.py:2957:16: error[invalid-return-type] Return type does not match returned value: expected `Self@_eval_pow_by_cayley`, found `Self@_eval_pow_by_cayley | T2'return@call_highest_priority | T1'return@call_highest_priority | Unknown`
- sympy/matrices/matrixbase.py:3046:5: error[invalid-argument-type] Argument is incorrect: Expected `(T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr, T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr, /) -> T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`, found `Overload[[Self](self, other: Self) -> Self, (self, other: MatrixBase) -> MatrixBase, (self, other: Expr) -> MatrixBase]`
+ sympy/matrices/matrixbase.py:3046:5: error[invalid-argument-type] Argument is incorrect: Expected `(MatrixBase, MatrixBase | Expr, /) -> MatrixBase | Expr`, found `Overload[[Self](self, other: Self) -> Self, (self, other: MatrixBase) -> MatrixBase, (self, other: Expr) -> MatrixBase]`
- sympy/matrices/matrixbase.py:3256:16: error[invalid-return-type] Return type does not match returned value: expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/matrixbase.py:3256:29: error[invalid-argument-type] Argument is incorrect: Expected `T2'return@call_highest_priority | T1'return@call_highest_priority`, found `MatrixBase`
- sympy/matrices/matrixbase.py:3310:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase`
- sympy/matrices/matrixbase.py:3314:16: error[invalid-return-type] Return type does not match returned value: expected `Tmat@__sub__`, found `MatrixBase`
- sympy/matrices/matrixbase.py:3944:39: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/matrixbase.py:3944:39: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/matrixbase.py:4386:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@add`
- sympy/matrices/matrixbase.py:4640:16: error[invalid-return-type] Return type does not match returned value: expected `Self@D`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/matrixbase.py:4640:16: error[invalid-return-type] Return type does not match returned value: expected `Self@D`, found `MatrixBase | Expr`
- sympy/matrices/matrixbase.py:4748:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/matrixbase.py:4748:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/matrixbase.py:4922:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T2'return@call_highest_priority` and `Self@analytic_func`
- sympy/matrices/matrixbase.py:4922:13: error[unsupported-operator] Operator `*=` is not supported between objects of type `T1'return@call_highest_priority` and `Self@analytic_func`
- sympy/matrices/matrixbase.py:4923:16: error[invalid-return-type] Return type does not match returned value: expected `Self@analytic_func`, found `Self@analytic_func | T2'return@call_highest_priority | T1'return@call_highest_priority | Unknown`
- sympy/matrices/matrixbase.py:5073:28: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Self@log`
- sympy/matrices/matrixbase.py:5076:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Self@log`
+ sympy/matrices/matrixbase.py:5073:28: error[invalid-argument-type] Argument is incorrect: Expected `Self@log`, found `MatrixBase | Expr | Unknown`
+ sympy/matrices/matrixbase.py:5078:16: error[invalid-return-type] Return type does not match returned value: expected `Self@log`, found `MatrixBase | Expr | Unknown`
- sympy/matrices/repmatrix.py:321:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `Self@_eval_is_symmetric`
- sympy/matrices/solvers.py:637:27: error[invalid-argument-type] Argument to bound method `vstack` is incorrect: Argument type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown` does not satisfy upper bound `MatrixBase` of type variable `Self`
- sympy/matrices/solvers.py:637:27: error[invalid-argument-type] Argument to bound method `vstack` is incorrect: Expected `Tmat@_gauss_jordan_solve`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Unknown`
- sympy/matrices/solvers.py:741:12: error[invalid-return-type] Return type does not match returned value: expected `Tmat@_pinv_solve`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/solvers.py:976:16: error[unresolved-attribute] Attribute `solve` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/solvers.py:976:16: error[unresolved-attribute] Attribute `solve` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Argument type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` does not satisfy upper bound `MatrixBase` of type variable `Self`
+ sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Argument type `MatrixBase | Expr` does not satisfy upper bound `MatrixBase` of type variable `Self`
- sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/solvers.py:976:30: error[invalid-argument-type] Argument to bound method `solve` is incorrect: Expected `MatrixBase`, found `MatrixBase | Expr`
- sympy/matrices/sparse.py:418:16: error[unresolved-attribute] Attribute `inv` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/sparse.py:418:16: error[unresolved-attribute] Attribute `inv` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_commonmatrix.py:1250:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_decompositions.py:24:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:24:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:33:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:33:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:43:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:43:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:52:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:52:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:58:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:58:12: error[unresolved-attribute] Attribute `permute_rows` is not defined on `Expr` in union `MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:78:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:85:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:91:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:104:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:111:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:124:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:132:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:132:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:289:10: error[unresolved-attribute] Attribute `applyfunc` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:289:10: error[unresolved-attribute] Attribute `applyfunc` is not defined on `Expr` in union `MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:394:16: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_decompositions.py:395:16: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:291:13: error[unsupported-operator] Operator `-` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:346:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:349:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:356:23: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:394:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:395:25: error[unsupported-operator] Operator `*` is not supported between objects of type `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_decompositions.py:396:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:396:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:397:16: error[unresolved-attribute] Attribute `H` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority`, `Expr` in union `Unknown | T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_decompositions.py:397:16: error[unresolved-attribute] Attribute `H` is not defined on `Expr` in union `Unknown | MatrixBase | Expr`
- sympy/matrices/tests/test_decompositions.py:440:22: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:440:13: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:452:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:452:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:465:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:465:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:476:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:476:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_decompositions.py:489:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_decompositions.py:489:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_eigen.py:478:12: error[no-matching-overload] No overload of function `simplify` matches arguments
+ sympy/matrices/tests/test_eigen.py:493:12: error[unresolved-attribute] Attribute `applyfunc` is not defined on `Expr` in union `MatrixBase | Expr | Unknown`
- sympy/matrices/tests/test_eigen.py:258:16: error[unresolved-attribute] Attribute `n` is not defined on `T2'return@call_highest_priority`, `T1'return@call_highest_priority` in union `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
- sympy/matrices/tests/test_eigen.py:307:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:308:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:323:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:324:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:365:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:366:14: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:381:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `ImmutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:382:15: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:406:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:478:21: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:493:13: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_eigen.py:794:19: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_immutable.py:106:23: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:122:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:124:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:142:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:202:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:202:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:203:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:203:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:204:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:204:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:205:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:205:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:206:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:206:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:207:12: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:207:12: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:214:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:214:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:215:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:215:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:216:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:216:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:217:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:217:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:218:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:218:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:219:16: error[not-subscriptable] Cannot subscript object of type `T2'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:219:16: error[not-subscriptable] Cannot subscript object of type `T1'return@call_highest_priority` with no `__getitem__` method
- sympy/matrices/tests/test_matrices.py:222:40: error[invalid-argument-type] Argument to bound method `multiply_elementwise` is incorrect: Expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr`
+ sympy/matrices/tests/test_matrices.py:222:40: error[invalid-argument-type] Argument to bound method `multiply_elementwise` is incorrect: Expected `MatrixBase`, found `MatrixBase | Expr`
- sympy/matrices/tests/test_matrices.py:395:16: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
+ sympy/matrices/tests/test_matrices.py:1740:12: error[no-matching-overload] No overload of function `simplify` matches arguments
- sympy/matrices/tests/test_matrices.py:1582:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1588:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1595:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1600:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1608:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr` and `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:1617:12: error[unsupported-operator] Operator `*` is not supported between objects of type `T2'return@call_highest_priority | T1'return@call_highest_priority | MatrixBase | Expr

... (truncated 521 lines) ...

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 19, 2026

Memory usage report

Summary

Project Old New Diff Outcome
flake8 49.62MB 49.57MB -0.11% (56.43kB) ⬇️
trio 121.52MB 121.47MB -0.05% (57.94kB) ⬇️
sphinx 274.06MB 273.81MB -0.09% (263.26kB) ⬇️
prefect 711.96MB 710.27MB -0.24% (1.70MB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
CallableType 179.37kB 168.54kB -6.04% (10.83kB) ⬇️
is_redundant_with_impl 158.98kB 149.98kB -5.66% (9.00kB) ⬇️
is_redundant_with_impl::interned_arguments 166.20kB 157.95kB -4.96% (8.25kB) ⬇️
IntersectionType 90.02kB 82.97kB -7.84% (7.05kB) ⬇️
ProtocolInterface 29.90kB 24.53kB -17.96% (5.37kB) ⬇️
infer_definition_types 1.89MB 1.89MB -0.23% (4.42kB) ⬇️
GenericContext 48.26kB 44.57kB -7.65% (3.69kB) ⬇️
FunctionType 441.53kB 438.95kB -0.58% (2.58kB) ⬇️
BoundTypeVarInstance 47.11kB 45.00kB -4.48% (2.11kB) ⬇️
cached_protocol_interface 47.71kB 46.02kB -3.54% (1.69kB) ⬇️
is_equivalent_to_object_inner 28.51kB 26.91kB -5.59% (1.59kB) ⬇️
UnionType 112.44kB 111.16kB -1.14% (1.28kB) ⬇️
TypeVarInstance 20.72kB 19.59kB -5.43% (1.12kB) ⬇️
FunctionType<'db>::signature_ 361.72kB 360.65kB -0.29% (1.07kB) ⬇️
Type<'db>::try_call_dunder_get_ 375.11kB 376.16kB +0.28% (1.06kB) ⬇️
... 43 more

trio

Name Old New Diff Outcome
CallableType 595.85kB 577.57kB -3.07% (18.28kB) ⬇️
infer_definition_types 7.61MB 7.59MB -0.22% (17.32kB) ⬇️
ProtocolInterface 85.94kB 75.10kB -12.62% (10.84kB) ⬇️
GenericContext 132.70kB 126.41kB -4.74% (6.29kB) ⬇️
BoundTypeVarInstance 167.34kB 163.90kB -2.06% (3.45kB) ⬇️
Type<'db>::try_call_dunder_get_ 1.38MB 1.38MB +0.24% (3.40kB) ⬇️
FunctionType 1.51MB 1.50MB -0.15% (2.30kB) ⬇️
is_equivalent_to_object_inner 70.72kB 68.73kB -2.82% (1.99kB) ⬇️
Type<'db>::class_member_with_policy_ 1.98MB 1.98MB +0.09% (1.80kB) ⬇️
infer_scope_types_impl 4.79MB 4.79MB -0.04% (1.75kB) ⬇️
all_narrowing_constraints_for_expression 481.69kB 480.11kB -0.33% (1.58kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 889.48kB 890.80kB +0.15% (1.33kB) ⬇️
TypeVarInstance 63.94kB 62.62kB -2.05% (1.31kB) ⬇️
FunctionType<'db>::signature_ 1.07MB 1.07MB -0.11% (1.24kB) ⬇️
cached_protocol_interface 135.94kB 134.96kB -0.72% (996.00B) ⬇️
... 30 more

sphinx

Name Old New Diff Outcome
infer_expression_types_impl 22.04MB 21.97MB -0.29% (65.86kB) ⬇️
infer_definition_types 24.35MB 24.30MB -0.19% (47.74kB) ⬇️
CallableType 1.12MB 1.09MB -2.91% (33.47kB) ⬇️
ProtocolInterface 140.94kB 115.66kB -17.94% (25.28kB) ⬇️
infer_scope_types_impl 15.65MB 15.63MB -0.16% (25.17kB) ⬇️
is_redundant_with_impl 1.86MB 1.85MB -0.62% (11.77kB) ⬇️
is_redundant_with_impl::interned_arguments 2.15MB 2.14MB -0.50% (11.00kB) ⬇️
FunctionType 3.16MB 3.16MB -0.27% (8.91kB) ⬇️
Type<'db>::try_call_dunder_get_ 4.95MB 4.96MB +0.12% (6.00kB) ⬇️
GenericContext 145.77kB 139.89kB -4.03% (5.88kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 2.17MB 2.17MB +0.21% (4.65kB) ⬇️
cached_protocol_interface 206.87kB 202.24kB -2.24% (4.63kB) ⬇️
is_equivalent_to_object_inner 123.17kB 118.64kB -3.68% (4.54kB) ⬇️
UnionType 1.31MB 1.30MB -0.33% (4.44kB) ⬇️
FunctionType<'db>::signature_ 2.30MB 2.29MB -0.18% (4.32kB) ⬇️
... 37 more

prefect

Name Old New Diff Outcome
infer_definition_types 86.41MB 85.96MB -0.52% (459.83kB) ⬇️
infer_expression_types_impl 60.42MB 59.98MB -0.73% (451.77kB) ⬇️
infer_expression_type_impl 14.98MB 14.71MB -1.81% (277.21kB) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 9.93MB 9.79MB -1.40% (142.49kB) ⬇️
Type<'db>::member_lookup_with_policy_ 15.26MB 15.16MB -0.63% (98.11kB) ⬇️
infer_scope_types_impl 51.40MB 51.33MB -0.14% (74.48kB) ⬇️
all_narrowing_constraints_for_expression 5.57MB 5.52MB -0.98% (55.91kB) ⬇️
Type<'db>::class_member_with_policy_ 16.88MB 16.84MB -0.28% (49.15kB) ⬇️
ProtocolInterface 257.78kB 219.93kB -14.68% (37.85kB) ⬇️
CallableType 1.94MB 1.91MB -1.81% (36.07kB) ⬇️
all_negative_narrowing_constraints_for_expression 2.30MB 2.28MB -0.90% (21.22kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 6.07MB 6.09MB +0.34% (20.88kB) ⬇️
is_redundant_with_impl 5.61MB 5.60MB -0.21% (11.82kB) ⬇️
is_redundant_with_impl::interned_arguments 5.58MB 5.57MB -0.20% (11.26kB) ⬇️
Type<'db>::try_call_dunder_get_ 10.14MB 10.15MB +0.09% (9.50kB) ⬇️
... 38 more

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 19, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
unresolved-attribute 1 0 17
type-assertion-failure 0 0 10
invalid-argument-type 0 0 7
redundant-cast 0 5 0
unsupported-operator 0 0 4
invalid-return-type 0 1 1
invalid-assignment 0 1 0
invalid-await 1 0 0
missing-argument 0 1 0
Total 2 8 39

Full report with detailed diff (timing results)

@AlexWaygood AlexWaygood force-pushed the alex-carl/die-normalization branch from 6b1a08e to 04aa5cc Compare February 19, 2026 21:01
@AlexWaygood
Copy link
Member Author

AlexWaygood commented Feb 19, 2026

Overall the ecosystem results look great:

AlexWaygood and others added 4 commits February 20, 2026 15:02
Move the detailed docstring from `Redundancy` to `PureRedundancy` (the
"pure" mathematical version used for type equivalence), reorder so
`PureRedundancy` comes first, and add a new docstring to `Redundancy`
explaining how it differs as a practical adaptation for union
simplification.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We deleted the tests from here because it's harder to construct the synthesized variants directly without .normalize(). And it doesn't seem important to directly test something if the behaviour can't be captured in an mdtest.

@AlexWaygood AlexWaygood force-pushed the alex-carl/die-normalization branch from 099517d to 65e5cc2 Compare February 20, 2026 22:22
@AlexWaygood

This comment was marked as resolved.

Comment on lines -828 to -839
// `Generator` special case: Prior to 3.13, the `_ReturnT_co` type didn't appear in any
// methods (except `__iter__`, but that returns the self type recursively, so it can't rule
// out equivalence). We don't want generators with different return types to be equivalent
// to each other. In this case we compare the `ClassType`s nominally.
if let Protocol::FromClass(self_class) = self.inner
&& let Protocol::FromClass(other_class) = other.inner
&& self_class.known(db) == Some(KnownClass::Generator)
&& other_class.known(db) == Some(KnownClass::Generator)
&& Program::get(db).python_version(db) < PythonVersion::PY313
{
return (*self_class).is_equivalent_to_impl(db, *other_class, inferable, visitor);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the code from #23386 can now be removed, but the fix that PR also applied to Type::satisfies_protocol is untouched by this PR

@AlexWaygood AlexWaygood marked this pull request as ready for review February 24, 2026 12:54
Comment on lines -1801 to -1804
pub(crate) fn normalized(self, db: &'db dyn Db) -> Self {
self.normalized_impl(db, &NormalizedVisitor::default())
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me so happy 😭

self,
db: &'db dyn Db,
other: Type<'db>,
inferable: InferableTypeVars<'_, 'db>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this parameter is probably supported by the ecosystem results, but I think it is a subtle change in semantics and we might want to keep it for now, since the caller might have a particular "inferable typevar" set in mind that the equivalence check should take into account.

(Eventually the goal is that all of the type relations will use constraint sets to record information about typevars. has_relation_to_impl still currently performs some checks directly, and in different ways depending on whether a typevar is inferable or not. The goal is for has_relation_to_impl to always return a constraint set, which doesn't care about whether a typevar is inferable or not; and then for things like is_assignable_to to call satisfied_by_all_typevars instead of is_always_satisfied. And at that point, all of these methods will drop this parameter. But right now, I think it's best for them all to be consistent with each other in terms of still taking the parameter in.)

Copy link
Member Author

@AlexWaygood AlexWaygood Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this parameter was necessary to avoid a big regression in our inference of urllib.parse.urlunparse() in this PR, which showed up in the ecosystem results on early versions of this PR. All of the new regression tests in crates/ty_python_semantic/resources/mdtest/call/overloads.md on this PR branch only pass because this parameter has been removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can restore the parameter and just pass in InferrableTypeVars::None to all callsites, if you prefer. But that felt a little silly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me, based on my analysis of the modified callsites, that Alex is right that we currently never check type equivalence in a context in which we should be inferring typevars at all (modulo the AlwaysTruthy/AlwaysFalsy case I commented on, where I don't think we should be checking equivalence anyway).

And this intuitively makes sense to me as well -- generally typevar inference should be happening in assignability checks, not equivalence checks. So it seems reasonable to me to just eliminate this parameter. But definitely interested if you think I'm missing something, @dcreager .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That convinces me! And this formulation will still be correct in the future world where we're not passing this parameter around at all.

.when_equivalent_to(
db,
current_parameter_type,
overload.inferable_typevars,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, for instance — with this change we're now ignoring that some of the typevars in the overload are inferable and some aren't, and are now treating all typevars as non-inferable. Is that correct? (I'm not sure!)

Copy link
Contributor

@carljm carljm Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm convinced by the added test ("Unknown argument with TypeVar overload") that this is a correct change. This equivalence check is not part of typevar inference from arguments (which is where we need to treat some typevars as inferable), it's an "internal" part of the overload algorithm, comparing overload parameter types for equivalence with other overload parameter types, in order to determine which overloads are capable of distinguishing based on an argument. This check should treat all parameter types (including typevars) as non-inferable and equivalent only to themselves.

@carljm carljm self-assigned this Feb 24, 2026
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome!

.when_equivalent_to(
db,
current_parameter_type,
overload.inferable_typevars,
Copy link
Contributor

@carljm carljm Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm convinced by the added test ("Unknown argument with TypeVar overload") that this is a correct change. This equivalence check is not part of typevar inference from arguments (which is where we need to treat some typevars as inferable), it's an "internal" part of the overload algorithm, comparing overload parameter types for equivalence with other overload parameter types, in order to determine which overloads are capable of distinguishing based on an argument. This check should treat all parameter types (including typevars) as non-inferable and equivalent only to themselves.

overload.inferable_typevars,
)
.is_always_satisfied(db)
.is_equivalent_to(db, first_overload_return_type)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rationale here is the same as above. This equivalence check is an "internal" check simply to decide whether two overloads return the same type or not, it's not part of generic inference from arguments. So we should not be inferring types for any typevars as part of this check, we should consider typevar returns equivalent only to themselves.

self,
db: &'db dyn Db,
other: Type<'db>,
inferable: InferableTypeVars<'_, 'db>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me, based on my analysis of the modified callsites, that Alex is right that we currently never check type equivalence in a context in which we should be inferring typevars at all (modulo the AlwaysTruthy/AlwaysFalsy case I commented on, where I don't think we should be checking equivalence anyway).

And this intuitively makes sense to me as well -- generally typevar inference should be happening in assignability checks, not equivalence checks. So it seems reasonable to me to just eliminate this parameter. But definitely interested if you think I'm missing something, @dcreager .

@AlexWaygood
Copy link
Member Author

AlexWaygood commented Feb 25, 2026

After rebasing on top of 1e33c4e, more changes unexpectedly started showing up in the ecosystem report: 5 redundant-cast diagnostics going away on graphql. The root cause turned out to be that the fix that 1e33c4e applied for equivalence only worked for top-level equivalence checks -- it didn't work when Generator was found in nested contexts inside a type, such as the return type of Awaitable.__await__:

@runtime_checkable
class Awaitable(Protocol[_T_co]):
@abstractmethod
def __await__(self) -> Generator[Any, Any, _T_co]: ...

That meant that this assertion failed on main, when it should pass:

from ty_extensions import static_assert, is_equivalent_to
from typing import Awaitable

static_assert(not is_equivalent_to(Awaitable[str], Awaitable[int]))

which then meant that we were inaccurately reporting a bunch of cast(Awaitable[Foo], whatever) calls in the graphql library as redundant.

But the fix that 1e33c4e applied for Type::has_relation_to does work when Generator is found in nested contexts, and with this PR, our equivalence implementation just delegates to our redundancy implementation, which uses Type::has_relation_to. So this PR accidentally generalises the fix added in 1e33c4e to work in more contexts than it did before.

A regression test has been added in fa0a563!

@AlexWaygood AlexWaygood requested a review from carljm February 25, 2026 17:34
@AlexWaygood
Copy link
Member Author

Re-requesting review just to be safe! Ready for another look.

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this PR so much. Great work tracking down the ecosystem changes and adding appropriate regression tests!

This looks good to me. I'd prefer if @dcreager could take a look and see if our conclusions about the inferrable typevars thing make sense to him, before we land.

Copy link
Member

@dcreager dcreager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to the inferable typevar parameter changes, thank you for looking into that and coming up with nice tests exercising it!

self,
db: &'db dyn Db,
other: Type<'db>,
inferable: InferableTypeVars<'_, 'db>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That convinces me! And this formulation will still be correct in the future world where we're not passing this parameter around at all.

relation_visitor,
disjointness_visitor,
)
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this formulation works even in the presence of typevars. It will return the typevar solutions that cause the redundancy check to succeed in both directions.

@AlexWaygood
Copy link
Member Author

Thanks both for the reviews!! Let's go 😃 🚀

@AlexWaygood AlexWaygood enabled auto-merge (squash) February 25, 2026 23:02
@charliermarsh
Copy link
Member

Let's go

@AlexWaygood AlexWaygood merged commit 09de8ef into main Feb 25, 2026
49 checks passed
@AlexWaygood AlexWaygood deleted the alex-carl/die-normalization branch February 25, 2026 23:05
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.

4 participants