Skip to content

[ty] Promote None to None | Unknown in invariant contexts#23790

Merged
AlexWaygood merged 3 commits intomainfrom
alex/promote-none
Mar 11, 2026
Merged

[ty] Promote None to None | Unknown in invariant contexts#23790
AlexWaygood merged 3 commits intomainfrom
alex/promote-none

Conversation

@AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Mar 7, 2026

Summary

You basically never want a type checker to infer a variable as having type list[None], dict[None, <value type>], dict[None, <value type>] or similar. There's no earthly reason why anybody would ever create a list or dictionary that is only ever intended to have None elements in it. The same principle applies for any singleton values that are commonly used as sentinels in Python code. Without an explicit type annotation, we can't say for sure what type the user wants us to infer [None] or [...] as, but we can be very confident that they almost certainly don't want us to infer list[None] or list[EllipsisType].

This PR therefore adds a new type promotion that turns None into None | Unknown in the context of unannotated invariant generic specializations. If the user really did want list[None] to be inferred, they can still get that result by adding an explicit type annotation.

A new method, Type::promote_singletons() has been added to achieve this: unlike other type promotions, we don't want to arbitrarily recurse into unions, etc. [42, None] should still be inferred as list[int | None] rather than list[int | None | Unknown]; we only want situations such as [None] to be inferred differently.

In the future, we can add a strict mode that allows users to opt out of this promotion, with us instead rejecting their code and demanding they add a type annotation to clarify their intentions. For now, though, I'd prefer to avoid false positives in this common case where we can be very confident that the unpromoted type is not what the user intended.

Ecosystem impact

We see lots of false positives going away, mostly of the form:

mylist = [None, None, None]

if whatever():
    mylist[0] = 42

Many of these will be fixed by astral-sh/ty#1473, but far from all of them. For example, we also see things like this in the ecosystem, which won't be helped by any amount of bidirectional inference:

class Foo:
    def __init__(self):
        self.mylist = [None, None, None]

    def method(self):
        self.mylist[0] = 42

Test Plan

Mdtests added.

Closes astral-sh/ty#2972

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

astral-sh-bot bot commented Mar 7, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 85.29%. The percentage of expected errors that received a diagnostic held steady at 78.13%. The number of fully passing files held steady at 64/132.

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 7, 2026

Memory usage report

Summary

Project Old New Diff Outcome
prefect 704.37MB 704.46MB +0.01% (92.20kB)
sphinx 265.18MB 265.22MB +0.02% (43.70kB)
trio 117.80MB 117.80MB +0.00% (2.39kB)
flake8 47.90MB 47.91MB +0.00% (1.66kB)

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
Type<'db>::apply_specialization_ 3.59MB 3.61MB +0.32% (11.86kB)
infer_expression_types_impl 60.70MB 60.71MB +0.01% (7.88kB)
infer_definition_types 88.78MB 88.79MB +0.01% (7.44kB)
StaticClassLiteral<'db>::try_mro_ 6.05MB 6.06MB +0.10% (6.01kB)
Type<'db>::apply_specialization_::interned_arguments 2.87MB 2.88MB +0.19% (5.62kB)
Specialization 2.51MB 2.51MB +0.20% (5.22kB)
Type<'db>::class_member_with_policy_ 17.30MB 17.30MB +0.03% (4.66kB)
infer_scope_types_impl 52.87MB 52.88MB +0.01% (4.56kB)
Type<'db>::try_call_dunder_get_ 10.48MB 10.49MB +0.04% (4.17kB)
FunctionType 8.48MB 8.49MB +0.05% (4.09kB)
Type<'db>::class_member_with_policy_::interned_arguments 9.35MB 9.35MB +0.03% (2.74kB)
infer_deferred_types 14.36MB 14.36MB +0.02% (2.50kB)
FunctionType<'db>::signature_ 3.88MB 3.88MB +0.06% (2.22kB)
GenericAlias 1.17MB 1.17MB +0.18% (2.18kB)
TupleType 694.38kB 696.42kB +0.29% (2.05kB)
... 26 more

sphinx

Name Old New Diff Outcome
infer_expression_types_impl 21.50MB 21.51MB +0.05% (11.91kB)
infer_definition_types 24.00MB 24.01MB +0.04% (10.41kB)
StaticClassLiteral<'db>::try_mro_ 2.11MB 2.11MB +0.28% (6.13kB)
TupleType 565.02kB 567.70kB +0.48% (2.69kB)
Type<'db>::apply_specialization_ 1.66MB 1.66MB +0.15% (2.48kB)
Specialization 1.02MB 1.02MB +0.20% (2.05kB)
GenericAlias 451.48kB 452.74kB +0.28% (1.27kB)
StaticClassLiteral<'db>::try_mro_::interned_arguments 486.56kB 487.76kB +0.25% (1.20kB)
TupleType<'db>::to_class_type_ 157.17kB 158.07kB +0.57% (924.00B)
infer_scope_types_impl 15.59MB 15.59MB +0.00% (624.00B)
Type<'db>::try_call_dunder_get_ 4.94MB 4.94MB +0.01% (532.00B)
is_redundant_with_impl 1.80MB 1.80MB +0.03% (528.00B)
Type<'db>::apply_specialization_::interned_arguments 1.45MB 1.45MB +0.03% (480.00B)
is_redundant_with_impl::interned_arguments 2.06MB 2.06MB +0.02% (352.00B)
IntersectionType 893.35kB 893.68kB +0.04% (336.00B)
... 13 more

trio

Name Old New Diff Outcome
infer_definition_types 7.57MB 7.57MB +0.01% (456.00B)
TupleType<'db>::to_class_type_ 51.66kB 51.96kB +0.58% (308.00B)
TupleType 110.42kB 110.67kB +0.23% (256.00B)
infer_expression_types_impl 7.06MB 7.06MB +0.00% (252.00B)
Type<'db>::apply_specialization_ 737.55kB 737.79kB +0.03% (240.00B)
infer_scope_types_impl 4.79MB 4.79MB +0.00% (240.00B)
Specialization 474.62kB 474.84kB +0.05% (224.00B)
GenericAlias 201.09kB 201.23kB +0.07% (144.00B)
UnionType 303.33kB 303.45kB +0.04% (128.00B)
UnionType<'db>::from_two_elements_ 272.48kB 272.60kB +0.04% (116.00B)
UnionType<'db>::from_two_elements_::interned_arguments 155.98kB 156.06kB +0.06% (88.00B)

flake8

Name Old New Diff Outcome
enum_metadata 67.60kB 68.09kB +0.73% (508.00B)
TupleType 78.48kB 78.78kB +0.38% (304.00B)
infer_definition_types 1.86MB 1.86MB +0.01% (228.00B)
StaticClassLiteral<'db>::try_metaclass_ 48.66kB 48.86kB +0.42% (208.00B)
infer_expression_types_impl 1.07MB 1.07MB +0.01% (132.00B)
UnionType<'db>::from_two_elements_ 80.87kB 80.98kB +0.14% (116.00B)
UnionType 101.25kB 101.36kB +0.11% (112.00B)
UnionType<'db>::from_two_elements_::interned_arguments 48.04kB 48.12kB +0.18% (88.00B)

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 7, 2026

mypy_primer results

Changes were detected when running on open source projects
more-itertools (https://github.com/more-itertools/more-itertools)
- more_itertools/more.py:5433:21: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `list[None]` on object of type `list[None]`
- Found 32 diagnostics
+ Found 31 diagnostics

spack (https://github.com/spack/spack)
- lib/spack/spack/vendor/jinja2/filters.py:170:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Any | Undefined` on object of type `list[None]`
- lib/spack/spack/vendor/pyrsistent/_pmap.py:430:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `list[tuple[Unknown, Unknown]]` on object of type `list[None]`
- lib/spack/spack/vendor/ruamel/yaml/resolver.py:156:35: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `tuple[list[tuple[int, int]], str, LazyEval, list[str]]`, found `tuple[list[tuple[int, int]], Unknown, Unknown, (Unknown & ~None) | list[None]]`
+ lib/spack/spack/vendor/ruamel/yaml/resolver.py:156:35: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `tuple[list[tuple[int, int]], str, LazyEval, list[str]]`, found `tuple[list[tuple[int, int]], Unknown, Unknown, (Unknown & ~None) | list[None | Unknown]]`
+ lib/spack/spack/vendor/ruamel/yaml/tokens.py:94:40: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ lib/spack/spack/vendor/ruamel/yaml/tokens.py:105:36: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ lib/spack/spack/vendor/ruamel/yaml/tokens.py:117:40: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- Found 4438 diagnostics
+ Found 4439 diagnostics

pip (https://github.com/pypa/pip)
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `int | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str]`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[str, str]`, found `int | Unknown | None | str | dict[str, None | Unknown]`
- src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None]`
+ src/pip/_vendor/requests/cookies.py:489:29: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `bool`, found `int | Unknown | None | str | dict[str, None | Unknown]`

jinja (https://github.com/pallets/jinja)
- src/jinja2/filters.py:120:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Any | Undefined` on object of type `list[None]`
- Found 203 diagnostics
+ Found 202 diagnostics

scrapy (https://github.com/scrapy/scrapy)
- tests/test_http_request.py:750:58: error[invalid-argument-type] Argument to bound method `from_response` is incorrect: Expected `dict[str, Iterable[str]] | list[tuple[str, Iterable[str]]] | None`, found `dict[str, None]`
+ tests/test_http_request.py:750:58: error[invalid-argument-type] Argument to bound method `from_response` is incorrect: Expected `dict[str, Iterable[str]] | list[tuple[str, Iterable[str]]] | None`, found `dict[str, None | Unknown]`
- tests/test_http_response.py:282:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None]`
+ tests/test_http_response.py:282:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None | Unknown]`
- tests/test_http_response.py:291:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None]`
+ tests/test_http_response.py:291:35: error[invalid-argument-type] Argument to bound method `follow_all` is incorrect: Expected `Iterable[str | Link]`, found `list[None | Unknown]`

ignite (https://github.com/pytorch/ignite)
- tests/ignite/engine/test_engine.py:182:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `Unknown | Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:236:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Unknown | Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1246:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1246:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1253:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[5]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1253:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `int | Unknown` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1265:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1265:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1273:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1273:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1281:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1281:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `Literal[0]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1288:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[9]` on object of type `list[None]`
- tests/ignite/engine/test_engine.py:1288:30: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `int | Unknown` on object of type `list[None]`
- Found 2237 diagnostics
+ Found 2223 diagnostics

sockeye (https://github.com/awslabs/sockeye)
- sockeye/model.py:812:23: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[int] | None`
+ sockeye/model.py:812:23: error[invalid-assignment] Object of type `list[None | Unknown]` is not assignable to `list[int] | None`
- test/unit/test_data_io.py:237:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:256:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:277:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:352:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:397:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:430:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:601:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:658:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:727:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- test/unit/test_data_io.py:760:60: error[invalid-argument-type] Argument to function `define_bucket_batch_sizes` is incorrect: Expected `list[int | float | None]`, found `list[None]`
- Found 447 diagnostics
+ Found 437 diagnostics

pylox (https://github.com/sco1/pylox)
- pylox/containers/array.py:146:9: error[invalid-assignment] Object of type `deque[None]` is not assignable to attribute `fields` of type `dict[Unknown, Unknown]`
+ pylox/containers/array.py:146:9: error[invalid-assignment] Object of type `deque[None | Unknown]` is not assignable to attribute `fields` of type `dict[Unknown, Unknown]`

tornado (https://github.com/tornadoweb/tornado)
- tornado/test/gen_test.py:960:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `ReferenceType[Future[Unknown]]` on object of type `list[None]`
- Found 335 diagnostics
+ Found 334 diagnostics

mypy (https://github.com/python/mypy)
- mypy/checkexpr.py:1958:42: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Type | None]`
- mypy/fastparse.py:931:25: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Type | None]`
- mypy/nodes.py:2389:25: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[str | None]`
- mypy/semanal_enum.py:256:22: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Expression | None]`
- mypy/typeanal.py:591:35: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[str | None]`
- mypyc/build.py:484:9: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `tuple[Unknown, Unknown | str]` on object of type `list[tuple[list[BuildSource], None]]`
- mypyc/build.py:486:12: error[invalid-return-type] Return type does not match returned value: expected `list[tuple[list[BuildSource], str | None]]`, found `list[tuple[list[BuildSource], str | None]] | list[Unknown] | list[tuple[list[BuildSource], None]]`
- Found 1768 diagnostics
+ Found 1761 diagnostics

comtypes (https://github.com/enthought/comtypes)
- comtypes/server/automation.py:32:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Literal[0]` on object of type `list[None]`
- comtypes/test/__init__.py:120:9: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- comtypes/tools/codegenerator/typeannotator.py:58:17: error[no-matching-overload] No overload of bound method `setdefault` matches arguments
- comtypes/tools/codegenerator/typeannotator.py:60:17: error[no-matching-overload] No overload of bound method `setdefault` matches arguments
- comtypes/tools/codegenerator/typeannotator.py:62:17: error[no-matching-overload] No overload of bound method `setdefault` matches arguments
- comtypes/tools/codegenerator/typeannotator.py:64:17: error[no-matching-overload] No overload of bound method `setdefault` matches arguments
- Found 504 diagnostics
+ Found 498 diagnostics

psycopg (https://github.com/psycopg/psycopg)
- psycopg/psycopg/_py_transformer.py:175:36: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[bytes | bytearray | memoryview[int] | None]`
- Found 667 diagnostics
+ Found 666 diagnostics

mitmproxy (https://github.com/mitmproxy/mitmproxy)
- mitmproxy/connection.py:160:17: error[invalid-assignment] Invalid subscript assignment with key of type `str` and value of type `Any | str` on object of type `dict[str, None]`
- Found 2141 diagnostics
+ Found 2140 diagnostics

meson (https://github.com/mesonbuild/meson)
- mesonbuild/build.py:223:24: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[str | None]`
- mesonbuild/build.py:1400:53: error[invalid-assignment] Object of type `(list[str | None] & ~AlwaysFalsy) | list[None]` is not assignable to `list[str | None]`: Incompatible value of type `(list[str | None] & ~AlwaysFalsy) | list[None]`
- mesonbuild/modules/python.py:548:21: error[invalid-argument-type] Argument to function `Popen_safe` is incorrect: Expected `list[str]`, found `Unknown | list[str | None] | list[Any] | list[Any | str]`
+ mesonbuild/modules/python.py:548:21: error[invalid-argument-type] Argument to function `Popen_safe` is incorrect: Expected `list[str]`, found `Unknown | list[str | None | Unknown] | list[Any] | list[Any | str] | list[str | None]`
- Found 2356 diagnostics
+ Found 2354 diagnostics

apprise (https://github.com/caronc/apprise)
- apprise/plugins/sendgrid.py:414:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["dynamic_template_data"]` and value of type `dict[Unknown, Unknown]` on object of type `dict[str, list[dict[str, None]]]`
+ apprise/plugins/sendgrid.py:414:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["dynamic_template_data"]` and value of type `dict[Unknown, Unknown]` on object of type `dict[str, list[dict[str, None | Unknown]]]`
- apprise/plugins/ses.py:787:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["type"]` and value of type `str` on object of type `dict[str, None]`
- apprise/plugins/smseagle.py:480:13: error[no-matching-overload] No overload of bound method `update` matches arguments
- apprise/plugins/smseagle.py:483:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["message"]` and value of type `str` on object of type `dict[str, None]`
- apprise/plugins/smseagle.py:490:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["message_type"]` and value of type `Literal["mms"]` on object of type `dict[str, None]`
- apprise/plugins/smseagle.py:491:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["attachments"]` and value of type `list[Unknown] & ~AlwaysFalsy` on object of type `dict[str, None]`
- apprise/plugins/sns.py:547:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["type"]` and value of type `str` on object of type `dict[str, None]`
- apprise/plugins/twitter.py:568:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["attachment"]` and value of type `dict[str, str | dict[str, Unknown]]` on object of type `dict[str, None]`
- apprise/plugins/twitter.py:577:21: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["text"]` and value of type `str` on object of type `dict[str, None]`
- tests/test_plugin_email.py:670:5: error[invalid-assignment] Object of type `tuple[tuple[Literal["Testing Lookup"], Pattern[str], dict[str, int | str | tuple[Unknown | str]]], tuple[Literal["Google Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Yandex"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Hotmail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Outlook"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Office 365"], Pattern[str], dict[str, int | str | Unknown]], tuple[Literal["Yahoo Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["GMX Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail Extended Addresses"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Zoho Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["SendGrid"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["163.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Foxmail.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Comcast.net"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Local Mail Server"], Pattern[str], dict[str, str | None]], tuple[Literal["Custom"], Pattern[str], dict[str, None]]]` is not assignable to attribute `EMAIL_TEMPLATES` of type `tuple[tuple[Literal["Google Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Yandex"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Hotmail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Outlook"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Office 365"], Pattern[str], dict[str, int | str | Unknown]], tuple[Literal["Yahoo Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["GMX Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail Extended Addresses"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Zoho Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["SendGrid"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["163.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Foxmail.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Comcast.net"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Local Mail Server"], Pattern[str], dict[str, str | None]], tuple[Literal["Custom"], Pattern[str], dict[str, None]]]`
+ tests/test_plugin_email.py:670:5: error[invalid-assignment] Object of type `tuple[tuple[Literal["Testing Lookup"], Pattern[str], dict[str, int | str | tuple[Unknown | str]]], tuple[Literal["Google Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Yandex"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Hotmail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Outlook"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Office 365"], Pattern[str], dict[str, int | str | Unknown]], tuple[Literal["Yahoo Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["GMX Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail Extended Addresses"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Zoho Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["SendGrid"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["163.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Foxmail.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Comcast.net"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Local Mail Server"], Pattern[str], dict[str, str | None]], tuple[Literal["Custom"], Pattern[str], dict[str, None | Unknown]]]` is not assignable to attribute `EMAIL_TEMPLATES` of type `tuple[tuple[Literal["Google Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Yandex"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Hotmail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Outlook"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Microsoft Office 365"], Pattern[str], dict[str, int | str | Unknown]], tuple[Literal["Yahoo Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["GMX Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Fast Mail Extended Addresses"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Zoho Mail"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["SendGrid"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["163.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Foxmail.com"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Comcast.net"], Pattern[str], dict[str, int | str | Unknown | tuple[Unknown | str]]], tuple[Literal["Local Mail Server"], Pattern[str], dict[str, str | None]], tuple[Literal["Custom"], Pattern[str], dict[str, None | Unknown]]]`
- tests/test_plugin_growl.py:323:36: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `<class 'NotifyGrowl'> | bool`
+ tests/test_plugin_growl.py:323:36: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `(Unknown & ~None) | <class 'NotifyGrowl'> | bool`
- tests/test_plugin_growl.py:349:33: error[unresolved-attribute] Object of type `(<class 'NotifyGrowl'> & ~AlwaysFalsy) | Literal[True]` has no attribute `items`
+ tests/test_plugin_growl.py:349:33: error[unresolved-attribute] Attribute `items` is not defined on `<class 'NotifyGrowl'> & ~AlwaysFalsy`, `Literal[True]` in union `(Unknown & ~AlwaysFalsy) | (<class 'NotifyGrowl'> & ~AlwaysFalsy) | Literal[True]`
- tests/test_plugin_growl.py:367:38: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `None | bool | <class 'NotifyGrowl'>`
+ tests/test_plugin_growl.py:367:38: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `None | Unknown | <class 'NotifyGrowl'> | bool`
- tests/test_plugin_growl.py:376:34: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `<class 'NotifyGrowl'> | bool`
+ tests/test_plugin_growl.py:376:34: error[invalid-argument-type] Argument to function `isinstance` is incorrect: Expected `type | tuple[Divergent, ...]`, found `(Unknown & ~None) | <class 'NotifyGrowl'> | bool`
- Found 3581 diagnostics
+ Found 3573 diagnostics

cwltool (https://github.com/common-workflow-language/cwltool)
- cwltool/workflow_job.py:180:9: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `list[None]` on object of type `dict[str, list[None | int | str | ... omitted 3 union elements]]`
- cwltool/workflow_job.py:235:9: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `list[None]` on object of type `dict[str, list[None | int | str | ... omitted 3 union elements]]`
- cwltool/workflow_job.py:302:9: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `list[None]` on object of type `dict[str, list[None | int | str | ... omitted 3 union elements]]`
- Found 506 diagnostics
+ Found 503 diagnostics

prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-databricks/tests/test_rest.py:38:25: error[invalid-argument-type] Argument to function `strip_kwargs` is incorrect: Expected `dict[Unknown, Unknown]`, found `None`
+ src/integrations/prefect-databricks/tests/test_rest.py:38:25: error[invalid-argument-type] Argument to function `strip_kwargs` is incorrect: Expected `dict[Unknown, Unknown]`, found `None | Unknown`
- src/integrations/prefect-dbt/tests/core/test_orchestrator_cache.py:324:54: error[invalid-argument-type] Argument to function `_hash_macro_dependencies` is incorrect: Expected `dict[str, str | None]`, found `dict[str, None]`
- src/integrations/prefect-github/tests/test_utils.py:31:25: error[invalid-argument-type] Argument to function `strip_kwargs` is incorrect: Expected `dict[Unknown, Unknown]`, found `None`
+ src/integrations/prefect-github/tests/test_utils.py:31:25: error[invalid-argument-type] Argument to function `strip_kwargs` is incorrect: Expected `dict[Unknown, Unknown]`, found `None | Unknown`
- src/prefect/server/schemas/responses.py:145:17: error[invalid-assignment] Invalid subscript assignment with key of type `str` and value of type `datetime` on object of type `dict[str, None]`
- Found 5885 diagnostics
+ Found 5883 diagnostics

pycryptodome (https://github.com/Legrandin/pycryptodome)
- lib/Crypto/IO/_PBES.py:530:54: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None`
+ lib/Crypto/IO/_PBES.py:530:54: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None | Unknown`
- lib/Crypto/IO/_PBES.py:531:26: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None`
+ lib/Crypto/IO/_PBES.py:531:26: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None | Unknown`
- lib/Crypto/IO/_PBES.py:531:36: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None`
+ lib/Crypto/IO/_PBES.py:531:36: error[invalid-argument-type] Argument to function `scrypt` is incorrect: Expected `int`, found `None | Unknown`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:262:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `list[Unknown]` on object of type `list[None]`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:264:17: error[unresolved-attribute] Object of type `None` has no attribute `append`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:266:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[1]` and value of type `bytes` on object of type `list[None]`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:267:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[2]` and value of type `bytes` on object of type `list[None]`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:268:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[3]` and value of type `Unknown | str` on object of type `list[None]`
- lib/Crypto/SelfTest/Hash/test_TupleHash.py:269:13: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[4]` and value of type `Unknown | <module 'Crypto.Hash.TupleHash128'> | <module 'Crypto.Hash.TupleHash256'>` on object of type `list[None]`
- Found 1360 diagnostics
+ Found 1354 diagnostics

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ddtrace/llmobs/_llmobs.py:1777:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["created_context"]` and value of type `Context` on object of type `dict[str, None]`
+ ddtrace/llmobs/_llmobs.py:1815:34: error[unresolved-attribute] Attribute `tracer` is not defined on `None` in union `Unknown | None`
+ ddtrace/llmobs/_llmobs.py:1817:21: error[unresolved-attribute] Attribute `tracer` is not defined on `None` in union `Unknown | None`
- ddtrace/vendor/ply/yacc.py:1619:33: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `None`, found `Production`
- ddtrace/vendor/ply/yacc.py:1640:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Production` on object of type `list[None]`
- tests/debugging/exploration/debugger.py:156:16: error[invalid-return-type] Return type does not match returned value: expected `list[bytes | None]`, found `(list[bytes] & ~AlwaysFalsy) | list[None]`
+ tests/debugging/exploration/debugger.py:156:16: error[invalid-return-type] Return type does not match returned value: expected `list[bytes | None]`, found `(list[bytes] & ~AlwaysFalsy) | list[None | Unknown]`
- tests/debugging/exploration/debugger.py:160:16: error[invalid-return-type] Return type does not match returned value: expected `list[Probe | None]`, found `(Unknown & ~AlwaysFalsy) | (list[Unknown] & ~AlwaysFalsy) | list[None]`
- tests/internal/test_periodic.py:141:26: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `None`, found `int`
- Found 9329 diagnostics
+ Found 9326 diagnostics

pwndbg (https://github.com/pwndbg/pwndbg)
- pwndbg/commands/buddydump.py:370:9: error[invalid-argument-type] Argument is incorrect: Expected `list[tuple[str | None, str | None]]`, found `list[tuple[None, None]]`
- Found 1872 diagnostics
+ Found 1871 diagnostics

pywin32 (https://github.com/mhammond/pywin32)
- com/win32com/client/genpy.py:470:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["_newenum"]` and value of type `tuple[Unknown, Unknown, None]` on object of type `dict[str, None]`
- com/win32com/client/genpy.py:477:17: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["value"] | Unknown` and value of type `tuple[Unknown, Unknown, None]` on object of type `dict[str, None]`
- com/win32com/client/genpy.py:522:21: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["value", "_newenum"] | Unknown` and value of type `tuple[Unknown, int, Unknown]` on object of type `dict[str, None]`
- com/win32com/client/genpy.py:568:21: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["value", "_newenum"] | Unknown` and value of type `tuple[Unknown, int, Unknown]` on object of type `dict[str, None]`
- Found 2743 diagnostics
+ Found 2739 diagnostics

manticore (https://github.com/trailofbits/manticore)
- manticore/core/smtlib/solver.py:775:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- manticore/core/smtlib/solver.py:782:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- manticore/core/smtlib/solver.py:787:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `bytes` on object of type `list[None]`
- manticore/platforms/decree.py:850:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | int | None` and value of type `Unknown | int` on object of type `list[None]`
+ manticore/platforms/decree.py:850:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | int | None` and value of type `Unknown | int` on object of type `list[None | Unknown]`
- manticore/platforms/decree.py:852:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | int | None` and value of type `None` on object of type `list[None]`
+ manticore/platforms/decree.py:852:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | int | None` and value of type `None` on object of type `list[None | Unknown]`
- manticore/platforms/linux.py:1106:44: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[int | None]`: Incompatible value of type `list[None]`
- manticore/platforms/wasm.py:280:40: error[invalid-argument-type] Argument is incorrect: Expected `list[FuncAddr | None]`, found `list[None]`
- tests/native/test_models.py:328:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- Found 11096 diagnostics
+ Found 11090 diagnostics

sympy (https://github.com/sympy/sympy)
- sympy/combinatorics/homomorphisms.py:564:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:1038:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:1058:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `dict[Unknown, Unknown]` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:1064:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `(x) -> Unknown` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:1078:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `def test(computed_words, l=...) -> Unknown` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:2223:21: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `int` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:4193:9: error[unresolved-attribute] Object of type `None` has no attribute `remove`
+ sympy/combinatorics/perm_groups.py:4193:9: error[unresolved-attribute] Attribute `remove` is not defined on `None` in union `None | Unknown`
- sympy/combinatorics/perm_groups.py:4200:13: error[unresolved-attribute] Object of type `None` has no attribute `sort`
+ sympy/combinatorics/perm_groups.py:4200:13: error[unresolved-attribute] Attribute `sort` is not defined on `None` in union `None | Unknown`
- sympy/combinatorics/perm_groups.py:4213:17: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `None`
+ sympy/combinatorics/perm_groups.py:4213:17: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `None | Unknown`
- sympy/combinatorics/perm_groups.py:4233:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `list[Unknown]` on object of type `list[None]`
- sympy/combinatorics/perm_groups.py:4256:17: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `None`
+ sympy/combinatorics/perm_groups.py:4256:17: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `None | Unknown`
- sympy/combinatorics/perm_groups.py:4292:38: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None`
+ sympy/combinatorics/perm_groups.py:4292:38: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None | Unknown`
- sympy/combinatorics/perm_groups.py:5023:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Literal[0]` on object of type `list[None]`
- sympy/combinatorics/permutations.py:2297:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `int` on object of type `list[None]`
- sympy/combinatorics/permutations.py:2300:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `int` on object of type `list[None]`
- sympy/combinatorics/permutations.py:2301:34: error[invalid-argument-type] Method `__getitem__` of type `Overload[(i: SupportsIndex, /) -> None, (s: slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], /) -> list[None]]` cannot be called with key of type `None` on object of type `list[None]`
+ sympy/combinatorics/permutations.py:2301:34: error[invalid-argument-type] Method `__getitem__` of type `Overload[(i: SupportsIndex, /) -> None | Unknown, (s: slice[SupportsIndex | None, SupportsIndex | None, SupportsIndex | None], /) -> list[None | Unknown]]` cannot be called with key of type `None` on object of type `list[None | Unknown]`
- sympy/combinatorics/util.py:245:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `list[Unknown]` on object of type `list[None]`
- sympy/combinatorics/util.py:302:9: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `dict[Unknown, Unknown]` on object of type `list[None]`
- sympy/combinatorics/util.py:304:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `list[Unknown]` on object of type `list[None]`
- sympy/combinatorics/util.py:304:36: error[unresolved-attribute] Object of type `None` has no attribute `keys`
+ sympy/combinatorics/util.py:304:36: error[unresolved-attribute] Attribute `keys` is not defined on `None` in union `None | Unknown`
- sympy/integrals/intpoly.py:747:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `list[Unknown | int]` on object of type `list[None]`
- sympy/integrals/intpoly.py:804:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `tuple[tuple[Unknown, Unknown], Unknown]` on object of type `list[None]`
- sympy/integrals/intpoly.py:816:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `tuple[list[Unknown], Unknown]` on object of type `list[None]`
- sympy/integrals/risch.py:545:34: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `None`, found `Literal["exp"]`
- sympy/integrals/risch.py:601:34: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `None`, found `Literal["log"]`
- sympy/matrices/common.py:2706:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Expr` on object of type `list[None]`
- sympy/physics/hep/gamma_matrices.py:551:9: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Literal[-1, 1]` on object of type `list[None]`
- sympy/physics/quantum/state.py:749:17: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Tuple` on object of type `list[None]`
- sympy/solvers/simplex.py:359:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Zero` on object of type `list[None]`
- sympy/solvers/simplex.py:361:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Expr | Unknown` on object of type `list[None]`
- sympy/solvers/simplex.py:365:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Zero` on object of type `list[None]`
- sympy/solvers/simplex.py:367:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Expr | Unknown` on object of type `list[None]`
- sympy/solvers/simplex.py:1070:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Unknown]`, found `Unknown | None | list[Unknown & tuple[object, ...]] | list[tuple[int, None]]`
+ sympy/solvers/simplex.py:1070:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Unknown]`, found `Unknown | None | list[Unknown & tuple[object, ...]] | list[tuple[int, None | Unknown]]`
- sympy/tensor/array/expressions/from_array_to_indexed.py:37:21: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `Dummy` on object of type `list[None]`
- sympy/tensor/index_methods.py:431:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown & ~Indexed` and value of type `list[Unknown] & ~AlwaysFalsy` on object of type `dict[None, set[Unknown]]`
+ sympy/tensor/index_methods.py:431:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown & ~Indexed` and value of type `list[Unknown] & ~AlwaysFalsy` on object of type `dict[None | Unknown, set[Unknown]]`
- sympy/tensor/index_methods.py:463:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown & Function & ~Indexed & ~exp & ~Piecewise` and value of type `list[Unknown] & ~AlwaysFalsy` on object of type `dict[None, set[Unknown & Function]]`
+ sympy/tensor/index_methods.py:463:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown & Function & ~Indexed & ~exp & ~Piecewise` and value of type `list[Unknown] & ~AlwaysFalsy` on object of type `dict[None | Unknown, set[Unknown & Function]]`
- sympy/tensor/tensor.py:230:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `TensorIndex` on object of type `list[None]`
- sympy/tensor/tensor.py:231:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `TensorIndex` on object of type `list[None]`
- sympy/tensor/tensor.py:3687:13: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Tensor` on object of type `list[None]`
- sympy/tensor/tensor.py:3704:17: error[invalid-assignment] Invalid subscript assignment with key of type `int | Unknown` and value of type `Literal[0] | Unknown` on object of type `list[None]`
- sympy/utilities/lambdify.py:1313:13: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `Unknown | str` on object of type `list[None]`
- Found 16510 diagnostics
+ Found 16479 diagnostics

static-frame (https://github.com/static-frame/static-frame)
+ static_frame/core/reduce.py:483:92: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- static_frame/core/reduce.py:455:29: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Unknown | ndarray[Any, Any]` on object of type `list[None]`
- static_frame/core/reduce.py:458:29: error[invalid-assignment] Invalid subscript assignment with key of type `int` and value of type `Unknown | ndarray[Any, Any]` on object of type `list[None]`
+ static_frame/core/reduce.py:638:88: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

pandas (https://github.com/pandas-dev/pandas)
- pandas/core/interchange/from_dataframe.py:369:42: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[None | int | float | str]`
- pandas/core/internals/managers.py:1242:43: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[ndarray[tuple[Any, ...], dtype[Any]] | None]`
- pandas/core/reshape/concat.py:726:40: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Hashable]`
- pandas/io/parsers/python_parser.py:614:40: error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `list[str | bytes | date | ... omitted 11 union elements]`, found `list[None]`
- pandas/io/parsers/python_parser.py:684:44: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[str | bytes | date | ... omitted 11 union elements]`
- pandas/tests/frame/methods/test_sample.py:181:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[5]` and value of type `float` on object of type `list[None]`
- pandas/tests/strings/test_split_partition.py:280:9: error[invalid-argument-type] Argument to bound method `from_tuples` is incorrect: Expected `Iterable[tuple[Hashable, ...]]`, found `list[tuple[str, str, str] | list[int | float] | list[None]]`
+ pandas/tests/strings/test_split_partition.py:280:9: error[invalid-argument-type] Argument to bound method `from_tuples` is incorrect: Expected `Iterable[tuple[Hashable, ...]]`, found `list[tuple[str, str, str] | list[int | float] | list[None | Unknown]]`
- Found 4583 diagnostics
+ Found 4577 diagnostics

jax (https://github.com/google/jax)
+ jax/_src/dispatch.py:686:54: warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- jax/_src/interpreters/mlir.py:1367:46: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[int | None]`
- jax/_src/interpreters/mlir.py:1883:34: error[invalid-argument-type] Argument to function `safe_zip` is incorrect: Expected `Iterable[Any]`, found `None | list[None | Sharding | AUTO]`
+ jax/_src/interpreters/mlir.py:1883:34: error[invalid-argument-type] Argument to function `safe_zip` is incorrect: Expected `Iterable[Any]`, found `None | list[None | Unknown | Sharding | AUTO]`
- jax/_src/interpreters/mlir.py:1948:34: error[invalid-argument-type] Argument to function `safe_zip` is incorrect: Expected `Iterable[Any]`, found `None | list[None | Sharding | AUTO]`
+ jax/_src/interpreters/mlir.py:1948:34: error[invalid-argument-type] Argument to function `safe_zip` is incorrect: Expected `Iterable[Any]`, found `None | list[None | Unknown | Sharding | AUTO]`
- jax/_src/interpreters/pxla.py:143:40: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Array | None]`
- jax/_src/interpreters/pxla.py:589:37: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[Hashable]`
- jax/_src/pallas/mosaic/interpret/shared_memory.py:57:50: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[ndarray[tuple[Any, ...], dtype[Any]] | None]`: Incompatible value of type `list[None]`
- jax/_src/pallas/mosaic/pallas_call_registration.py:142:37: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[MemorySpace | None]`
- jax/_src/pallas/mosaic/pallas_call_registration.py:160:34: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[MemorySpace | None]`
- jax/_src/pallas/mosaic_gpu/torch.py:192:44: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[int | None]`
- jax/_src/sharding_impls.py:924:37: error[invalid-assignment] Object of type `list[None]` is not assignable to `list[int | None]`
- jax/experimental/jet.py:462:35: error[invalid-argument-type] Argument to function `square` is incorrect: Expected `Array | ndarray[tuple[Any, ...], dtype[Any]] | numpy.bool[builtins.bool] | ... omitted 5 union elements`, found `None | Array`
+ jax/experimental/jet.py:462:35: error[invalid-argument-type] Argument to function `square` is incorrect: Expected `Array | ndarray[tuple[Any, ...], dtype[Any]] | numpy.bool[builtins.bool] | ... omitted 5 union elements`, found `None | Unknown | Array`
- jax/experimental/jet.py:463:33: error[invalid-argument-type] Argument to function `exp` is incorrect: Expected `Array | ndarray[tuple[Any, ...], dtype[Any]] | numpy.bool[builtins.bool] | ... omitted 5 union elements`, found `None | Array`
+ jax/experimental/jet.py:463:33: error[invalid-argument-type] Argument to function `exp` is incorrect: Expected `Array | ndarray[tuple[Any, ...], dtype[Any]] | numpy.bool[builtins.bool] | ... omitted 5 union elements`, found `None | Unknown | Array`
- jax/experimental/jet.py:473:22: error[unsupported-operator] Operator `*` is not supported between two objects of type `None | Array`
+ jax/experimental/jet.py:473:22: error[unsupported-operator] Operator `*` is not supported between two objects of type `None | Unknown | Array`
- jax/experimental/jet.py:476:22: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Array`
+ jax/experimental/jet.py:476:22: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Unknown | Array`
- jax/experimental/jet.py:497:16: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Array`
+ jax/experimental/jet.py:497:16: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Unknown | Array`
- jax/experimental/jet.py:539:27: error[unsupported-operator] Operator `-` is not supported between objects of type `Literal[1]` and `None | Array`
+ jax/experimental/jet.py:539:27: error[unsupported-operator] Operator `-` is not supported between objects of type `Literal[1]` and `None | Unknown | Array`
- jax/experimental/jet.py:542:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Literal[1]` and `None | Array`
+ jax/experimental/jet.py:542:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Literal[1]` and `None | Unknown | Array`
- jax/experimental/jet.py:542:36: error[unsupported-operator] Operator `*` is not supported between two objects of type `None | Array`
+ jax/experimental/jet.py:542:36: error[unsupported-operator] Operator `*` is not supported between two objects of type `None | Unknown | Array`
- jax/experimental/jet.py:566:16: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Array`
+ jax/experimental/jet.py:566:16: error[unsupported-operator] Operator `*` is not supported between objects of type `int` and `None | Unknown | Array`
- Found 2159 diagnostics
+ Found 2152 diagnostics

zulip (https://github.com/zulip/zulip)
- analytics/views/stats.py:540:21: error[invalid-argument-type] Argument to function `get_time_series_by_subgroup` is incorrect: Expected `dict[str | None, str]`, found `dict[str | None, str] | dict[str, str] | dict[str, Any] | dict[None, str]`
+ analytics/views/stats.py:540:21: error[invalid-argument-type] Argument to function `get_time_series_by_subgroup` is incorrect: Expected `dict[str | None, str]`, found `dict[str | None, str] | dict[str, str] | dict[str, Any] | dict[None | Unknown, str]`

rotki (https://github.com/rotki/rotki)
- rotkehlchen/api/services/external_services.py:20:17: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | str` and value of type `Unknown | dict[str, str]` on object of type `dict[str, None]`
- rotkehlchen/api/services/history.py:382:39: error[invalid-assignment] Object of type `Unknown | list[None]` is not assignable to `list[int | None]`
- rotkehlchen/tests/db/test_history_events.py:245:34: error[invalid-argument-type] Argument to function `add_history_events_to_db` is incorrect: Expected `dict[int, tuple[str, TimestampMS, FVal, dict[Unknown, Unknown] | None]]`, found `dict[int, tuple[str, TimestampMS, FVal, None]]`
- rotkehlchen/tests/db/test_history_events.py:260:34: error[invalid-argument-type] Method `__getitem__` of type `bound method dict[int, tuple[str, TimestampMS, FVal, None]].__getitem__(key: int, /) -> tuple[str, TimestampMS, FVal, None]` cannot be called with key of type `None` on object of type `dict[int, tuple[str, TimestampMS, FVal, None]]`
+ rotkehlchen/tests/db/test_history_events.py:260:34: error[invalid-argument-type] Method `__getitem__` of type `bound method dict[int, tuple[str, TimestampMS, FVal, None | Unknown]].__getitem__(key: int, /) -> tuple[str, TimestampMS, FVal, None | Unknown]` cannot be called with key of type `None` on object of type `dict[int, tuple[str, TimestampMS, FVal, None | Unknown]]`
- rotkehlchen/tests/db/test_history_events.py:273:34: error[invalid-argument-type] Method `__getitem__` of type `bound method dict[int, tuple[EVMTxHash, TimestampMS, FVal, str, str, None]].__getitem__(key: int, /) -> tuple[EVMTxHash, TimestampMS, FVal, str, str, None]` cannot be called with key of type `None` on object of type `dict[int, tuple[EVMTxHash, TimestampMS, FVal, str, str, None]]`
+ rotkehlchen/tests/db/test_history_events.py:273:34: error[invalid-argument-type] Method `__getitem__` of type `bound method dict[int, tuple[EVMTxHash, TimestampMS, FVal, str, str, None | Unknown]].__getitem__(key: int, /) -> tuple[EVMTxHash, TimestampMS, FVal, str, str, None | Unknown]` cannot be called with key of type `None` on object of type `dict[int, tuple[EVMTxHash, TimestampMS, FVal, str, str, None | Unknown]]`
- Found 2155 diagnostics
+ Found 2152 diagnostics

core (https://github.com/home-assistant/core)
- homeassistant/components/google_wifi/sensor.py:221:21: error[invalid-assignment] Invalid subscript assignment with key of type `str` and value of type `Unknown | str | None` on object of type `dict[str, None]`
- Found 12100 diagnostics
+ Found 12099 diagnostics

colour (https://github.com/colour-science/colour)
- colour/utilities/tests/test_array.py:2018:29: error[invalid-argument-type] Argument to function `has_only_nan` is incorrect: Expected `_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | ... omitted 5 union elements`, found `list[None]`
+ colour/utilities/tests/test_array.py:2018:29: error[invalid-argument-type] Argument to function `has_only_nan` is incorrect: Expected `_Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | ... omitted 5 union elements`, found `list[None | Unknown]`

pandas-stubs (https://github.com/pandas-dev/pandas-stubs)
+ tests/test_pandas.py:142:9: error[type-assertion-failure] Type `Unknown` does not match asserted type `Never`
+ tests/test_pandas.py:145:9: error[type-assertion-failure] Type `Unknown` does not match asserted type `Never`
- Found 4759 diagnostics
+ Found 4761 diagnostics

scipy (https://github.com/scipy/scipy)
- scipy/cluster/hierarchy/_hierarchy_impl.py:1152:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal[0]` and value of type `Self@pre_order` on object of type `list[None]`
- scipy/interpolate/_interpolate.py:2102:9: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown` and value of type `slice[Any, Any, Any]` on object of type `list[None]`
- scipy/optimize/_highspy/_highs_wrapper.py:247:9: error[no-matching-overload] No overload of bound method `update` matches arguments
- scipy/optimize/_highspy/_highs_wrapper.py:275:5: error[no-matching-overload] No overload of bound method `update` matches arguments
- scipy/optimize/_numdiff.py:632:9: error[invalid-assignment] Invalid subscript assignment with key of type `Literal["nfev"]` and value of type `Literal[0, 1] | Unknown` on object of type `dict[str, None]`
- scipy/optimize/_optimize.py:1824:16: error[unsupported-operator] Operator `<=` is not supported between objects of type `None` and `Unknown | float`
+ scipy/optimize/_optimize.py:1824:16: error[unsupported-operator] Operator `<=` is not supported between objects of type `None | Unknown` and `Unknown | float`
- scipy/optimize/_optimize.py:1828:27: error[invalid-argument-type] Argument to function `dot` is incorrect: Expected `ArrayLike`, found `None`
+ scipy/optimize/_optimize.py:1828:27: error[invalid-argument-type] Argument to function `dot` is incorrect: Expected `ArrayLike`, found `None | Unknown`
- scipy/optimize/_optimize.py:1828:31: error[invalid-argument-type] Argument to function `dot` is incorrect: Expected `ArrayLike`, found `None`
+ scipy/optimize/_optimize.py:1828:31: error[invalid-argument-type] Argument to function `dot` is incorrect: Expected `ArrayLike`, found `None

... (truncated 37 lines) ...

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 7, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-assignment 0 123 9
invalid-argument-type 0 29 34
invalid-await 40 0 0
unsupported-operator 6 3 12
no-matching-overload 0 7 0
unresolved-attribute 2 1 4
unused-type-ignore-comment 6 0 0
invalid-return-type 1 2 1
type-assertion-failure 2 0 0
Total 57 165 60

Full report with detailed diff (timing results)

@AlexWaygood AlexWaygood force-pushed the alex/promote-none branch 2 times, most recently from 2f8c33c to becce02 Compare March 7, 2026 18:05
@AlexWaygood AlexWaygood marked this pull request as ready for review March 7, 2026 18:05
Comment on lines +5235 to +5236
// `SingletonsOnly` promotion only recurses into `NominalInstance` types (tuples
// and specialized generics). For all other types, return early.
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be interesting to also handle class literal types here? See astral-sh/ty#3013 (comment). The y2: list[type] = [float] * 3 thing might be an interesting test case that could be added here?

Copy link
Member Author

Choose a reason for hiding this comment

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

hmmmmm that's indeed an interesting idea! I think you're right that a variable typed as list[<class 'float'>] is just as useless as a variable typed as list[None]

Copy link
Member Author

Choose a reason for hiding this comment

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

but probably we'd also want list[<class 'float'> | <class 'str'>] to be promoted to list[type]? in which case our more normal type-promotion machinery would be a better fit here, rather than the new kind of type promotion I'm adding in this PR that doesn't recurse into unions

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'm trying it out as a standalone change in #23872

Copy link
Contributor

Choose a reason for hiding this comment

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

astral-sh/ty#3013 is only helped if we promote <class 'float'> all the way to type[object] (or builtins.type) - promoting it only as far as type[float] (which is what #23872 currently does) won't help that case.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hey, let's not have the same conversation on two separate PRs simultaneously 😆

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 don't love having this one special edge case where gradual types are still unexpectedly inserted, and I think we should eventually offer an opt-in diagnostic whenever it happens. Or even better, remove it again when #1473 renders it unnecessary. But the ecosystem report suggests it fixes enough real-world false positives to be worth doing.

Approving with comments -- I think the "flip" issue at least does need to be fixed before landing. The other issue feels wrong and would be ideal to fix, but not sure how much it matters in practice.

@AlexWaygood
Copy link
Member Author

Or even better, remove it again when #1473 renders it unnecessary. But the ecosystem report suggests it fixes enough real-world false positives to be worth doing.

As I mentioned in the PR description, I think there are quite a few cases in the ecosystem report that won't be fixed by astral-sh/ty#1473. But (as I also said in the PR description), I agree that we should add a config option to switch this behaviour off at some point.

@AlexWaygood AlexWaygood merged commit af8db50 into main Mar 11, 2026
50 checks passed
@AlexWaygood AlexWaygood deleted the alex/promote-none branch March 11, 2026 18:09
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.

Reduce false positives on invariant containers initialized with a singleton type (e.g. None)

4 participants