Skip to content

[ty] Support basic narrowing with aliased conditional expressions#24302

Open
mtshiba wants to merge 2 commits intomainfrom
narrow-by-aliased-conditional-expr-minimal
Open

[ty] Support basic narrowing with aliased conditional expressions#24302
mtshiba wants to merge 2 commits intomainfrom
narrow-by-aliased-conditional-expr-minimal

Conversation

@mtshiba
Copy link
Copy Markdown
Collaborator

@mtshiba mtshiba commented Mar 30, 2026

Summary

Closes astral-sh/ty#719 (almost)

From #23937

A complete implementation is already available in #23937. However, due to the complexity of the mechanism, I decided to extract only the basic support. As explicitly stated in mdtest, this PR does not yet implement support for cross-scope alias narrowing and chained aliases.

Test Plan

new mdtest: narrow/aliased_conditions.md

@mtshiba mtshiba added ty Multi-file analysis & type inference ecosystem-analyzer labels Mar 30, 2026
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 30, 2026

Typing conformance results

No changes detected ✅

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

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 30, 2026

Memory usage report

Summary

Project Old New Diff Outcome
prefect 716.74MB 717.40MB +0.09% (677.36kB)
sphinx 265.21MB 265.61MB +0.15% (415.82kB)
trio 117.99MB 118.03MB +0.03% (36.02kB)
flake8 48.07MB 48.09MB +0.04% (19.48kB)

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
infer_expression_types_impl 61.76MB 62.07MB +0.51% (322.33kB)
all_narrowing_constraints_for_expression 7.13MB 7.28MB +2.10% (153.71kB)
semantic_index 171.50MB 171.61MB +0.06% (110.08kB)
Expression 8.73MB 8.77MB +0.56% (49.64kB)
all_negative_narrowing_constraints_for_expression 2.62MB 2.67MB +1.71% (46.01kB)
check_file_impl 17.95MB 17.95MB -0.02% (3.37kB)
infer_definition_types 89.72MB 89.73MB +0.00% (1.45kB)
infer_expression_type_impl 13.82MB 13.82MB -0.01% (1.21kB)
Type<'db>::member_lookup_with_policy_ 16.19MB 16.19MB -0.01% (1.16kB)
StaticClassLiteral<'db>::implicit_attribute_inner_ 9.93MB 9.93MB -0.01% (852.00B)
infer_scope_types_impl 54.11MB 54.11MB +0.00% (652.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_::interned_arguments 5.27MB 5.27MB -0.01% (384.00B)
place_table 748.83kB 749.18kB +0.05% (360.00B)
Type<'db>::class_member_with_policy_ 17.72MB 17.72MB -0.00% (360.00B)
UnionType 3.52MB 3.51MB -0.01% (240.00B)
... 9 more

sphinx

Name Old New Diff Outcome
infer_expression_types_impl 21.48MB 21.67MB +0.92% (201.34kB)
semantic_index 60.97MB 61.04MB +0.11% (66.36kB)
all_narrowing_constraints_for_expression 2.33MB 2.38MB +2.07% (49.48kB)
all_negative_narrowing_constraints_for_expression 1.00MB 1.05MB +4.37% (44.89kB)
Expression 3.18MB 3.22MB +1.19% (38.95kB)
infer_definition_types 23.97MB 23.97MB +0.01% (3.50kB)
infer_expression_type_impl 2.95MB 2.95MB +0.05% (1.44kB)
Type<'db>::class_member_with_policy_ 7.62MB 7.63MB +0.02% (1.22kB)
IntersectionType 880.59kB 881.70kB +0.13% (1.11kB)
Type<'db>::member_lookup_with_policy_ 6.51MB 6.51MB +0.02% (1.10kB)
Type<'db>::class_member_with_policy_::interned_arguments 4.01MB 4.01MB +0.02% (728.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 2.40MB 2.40MB +0.03% (672.00B)
infer_scope_types_impl 15.49MB 15.49MB +0.00% (612.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_::interned_arguments 1.93MB 1.93MB +0.03% (576.00B)
is_redundant_with_impl::interned_arguments 2.02MB 2.02MB +0.02% (528.00B)
... 13 more

trio

Name Old New Diff Outcome
infer_expression_types_impl 7.08MB 7.09MB +0.20% (14.84kB)
semantic_index 29.90MB 29.91MB +0.04% (11.86kB)
Expression 1.42MB 1.42MB +0.27% (3.87kB)
all_narrowing_constraints_for_expression 589.21kB 592.59kB +0.57% (3.38kB)
all_negative_narrowing_constraints_for_expression 183.25kB 184.07kB +0.45% (844.00B)
infer_definition_types 7.73MB 7.73MB +0.01% (696.00B)
IntersectionType 222.50kB 222.66kB +0.07% (168.00B)
IntersectionType<'db>::from_two_elements_ 17.49kB 17.61kB +0.65% (116.00B)
infer_expression_type_impl 1.32MB 1.32MB +0.01% (96.00B)
IntersectionType<'db>::from_two_elements_::interned_arguments 12.72kB 12.80kB +0.68% (88.00B)
infer_scope_types_impl 4.79MB 4.79MB +0.00% (60.00B)
loop_header_reachability 133.23kB 133.27kB +0.04% (48.00B)

flake8

Name Old New Diff Outcome
semantic_index 13.68MB 13.68MB +0.04% (5.96kB)
infer_expression_types_impl 1.07MB 1.07MB +0.43% (4.70kB)
all_narrowing_constraints_for_expression 82.01kB 85.14kB +3.82% (3.13kB)
Expression 366.54kB 368.44kB +0.52% (1.90kB)
all_negative_narrowing_constraints_for_expression 39.60kB 40.64kB +2.63% (1.04kB)
IntersectionType 68.56kB 69.10kB +0.79% (552.00B)
infer_definition_types 1.87MB 1.87MB +0.02% (448.00B)
is_redundant_with_impl::interned_arguments 139.56kB 139.99kB +0.31% (440.00B)
infer_expression_type_impl 141.97kB 142.25kB +0.20% (284.00B)
is_redundant_with_impl 136.72kB 136.96kB +0.17% (240.00B)
enum_metadata 67.08kB 67.26kB +0.27% (184.00B)
UnionType 101.28kB 101.39kB +0.11% (112.00B)
Type<'db>::member_lookup_with_policy_::interned_arguments 228.11kB 228.21kB +0.04% (104.00B)
loop_header_reachability 13.36kB 13.45kB +0.73% (100.00B)
Type<'db>::apply_specialization_ 215.68kB 215.77kB +0.04% (92.00B)
... 3 more

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 30, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
unresolved-attribute 1 37 1
invalid-argument-type 1 24 1
not-subscriptable 5 9 0
unused-type-ignore-comment 13 0 0
no-matching-overload 1 9 0
call-non-callable 0 8 0
invalid-assignment 2 4 2
invalid-return-type 1 2 0
not-iterable 0 3 0
redundant-cast 3 0 0
unsupported-operator 0 2 0
call-top-callable 1 0 0
Total 28 98 4
Raw diff (130 changes)
CPython (cases_generator) (https://github.com/python/cpython)
- Tools/cases_generator/stack.py:738:13 error[invalid-assignment] Object of type `PointerOffset | None` is not assignable to attribute `memory_offset` on type `None | Local`

PyGithub (https://github.com/PyGithub/PyGithub)
+ github/Repository.py:2331:35 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ github/Repository.py:4092:91 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

bokeh (https://github.com/bokeh/bokeh)
- src/bokeh/plotting/_geo_feature.py:505:23 error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `Unknown | None`
- src/bokeh/plotting/_geo_feature.py:521:40 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method

core (https://github.com/home-assistant/core)
- homeassistant/components/tts/__init__.py:371:41 error[invalid-argument-type] Argument to bound method `write` is incorrect: Expected `bytes | bytearray | memoryview[int]`, found `object`

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ddtrace/appsec/_common_module_patches.py:355:9 error[unresolved-attribute] Attribute `downstream_requests` is not defined on `None` in union `ASM_Environment | None`
- ddtrace/vendor/psutil/__init__.py:1071:24 error[invalid-argument-type] Argument to function `sleep` is incorrect: Expected `SupportsIndex | float`, found `Unknown | None`
- ddtrace/vendor/psutil/__init__.py:1829:24 error[invalid-argument-type] Argument to function `sleep` is incorrect: Expected `SupportsIndex | float`, found `Unknown | None`
- ddtrace/vendor/psutil/__init__.py:1839:24 error[invalid-argument-type] Argument to function `sleep` is incorrect: Expected `SupportsIndex | float`, found `Unknown | None`
- ddtrace/vendor/psutil/__init__.py:1894:24 error[invalid-argument-type] Argument to function `sleep` is incorrect: Expected `SupportsIndex | float`, found `Unknown | None`
- ddtrace/vendor/psutil/__init__.py:1904:24 error[invalid-argument-type] Argument to function `sleep` is incorrect: Expected `SupportsIndex | float`, found `Unknown | None`

discord.py (https://github.com/Rapptz/discord.py)
- discord/app_commands/transformers.py:112:67 error[invalid-argument-type] Argument to bound method `_checked_translate` is incorrect: Expected `locale_str`, found `str | locale_str`
- discord/app_commands/transformers.py:117:67 error[invalid-argument-type] Argument to bound method `_checked_translate` is incorrect: Expected `locale_str`, found `str | locale_str`
- discord/ext/commands/view.py:151:53 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `str | None`
- discord/ext/commands/view.py:162:57 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `str | None`
+ discord/ext/commands/view.py:184:69 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

ibis (https://github.com/ibis-project/ibis)
- ibis/backends/materialize/__init__.py:837:24 error[unresolved-attribute] Attribute `upper` is not defined on `None` in union `str | None`
- ibis/expr/api.py:1891:30 error[not-iterable] Object of type `Unknown | None` may not be iterable
- ibis/expr/api.py:1893:31 error[not-iterable] Object of type `Unknown | None` may not be iterable
- ibis/expr/api.py:1895:33 error[not-iterable] Object of type `Unknown | None` may not be iterable

jax (https://github.com/google/jax)
- jax/_src/pallas/mosaic_gpu/primitives.py:592:12 error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None | tuple[Unknown, ...]`
- jax/_src/pallas/mosaic_gpu/primitives.py:621:36 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- jax/_src/pallas/mosaic_gpu/primitives.py:637:36 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- jax/experimental/mosaic/gpu/tcgen05.py:452:8 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `TMEMRef | None`
- jax/experimental/mosaic/gpu/tcgen05.py:455:19 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `TMEMRef | None`
- jax/experimental/mosaic/gpu/tcgen05.py:457:8 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `TMEMRef | None`
- jax/experimental/mosaic/gpu/tcgen05.py:460:15 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `TMEMRef | None`
+ jax/experimental/mosaic/gpu/tcgen05.py:517:74 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

meson (https://github.com/mesonbuild/meson)
- mesonbuild/compilers/detect.py:1168:73 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | list[str]`, found `None | str | list[str]`
- mesonbuild/compilers/detect.py:1166:38 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `Unknown | str | None`
+ mesonbuild/compilers/detect.py:1166:38 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str`, found `str | None`

mitmproxy (https://github.com/mitmproxy/mitmproxy)
- test/mitmproxy/proxy/tutils.py:187:13 error[unresolved-attribute] Object of type `Command | Event` has no attribute `data`

more-itertools (https://github.com/more-itertools/more-itertools)
- more_itertools/more.py:4668:13 error[call-non-callable] Object of type `None` is not callable
- more_itertools/more.py:4692:13 error[call-non-callable] Object of type `None` is not callable
- more_itertools/more.py:4746:13 error[call-non-callable] Object of type `None` is not callable
- more_itertools/recipes.py:485:13 error[call-non-callable] Object of type `None` is not callable

mypy (https://github.com/python/mypy)
+ mypy/checkmember.py:1273:31 warning[redundant-cast] Value is already of type `Decorator`
+ mypy/checkmember.py:1302:24 warning[redundant-cast] Value is already of type `Decorator`

operator (https://github.com/canonical/operator)
+ ops/model.py:3700:16 warning[redundant-cast] Value is already of type `bool`

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/arrays/categorical.py:176:53 error[invalid-argument-type] Argument to function `invalid_comparison` is incorrect: Expected `ExtensionArray | ndarray[tuple[Any, ...], dtype[Any]] | list[Unknown] | ... omitted 14 union elements`, found `Hashable`
- pandas/core/construction.py:357:31 error[unresolved-attribute] Attribute `dtype` is not defined on `Sequence[object] & ~MaskedArray[tuple[object, ...], dtype[object]]` in union `(Sequence[object] & ~MaskedArray[tuple[object, ...], dtype[object]]) | (ExtensionArray & ~MaskedArray[tuple[object, ...], dtype[object]]) | ndarray[tuple[Any, ...], dtype[Any]] | (Index & ~MaskedArray[tuple[object, ...], dtype[object]]) | (Series & ~MaskedArray[tuple[object, ...], dtype[object]])`
- pandas/core/generic.py:8289:44 error[unsupported-operator] Unary operator `~` is not supported for object of type `ExtensionArray | ndarray[tuple[Any, ...], dtype[Any]] | Unknown`

pandera (https://github.com/pandera-dev/pandera)
- pandera/inspection_utils.py:14:37 error[unresolved-attribute] Object of type `(...) -> Unknown` has no attribute `__self__`

prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-bitbucket/prefect_bitbucket/repository.py:123:21 error[unresolved-attribute] Attribute `get_secret_value` is not defined on `None` in union `SecretStr | None`
- src/integrations/prefect-bitbucket/prefect_bitbucket/repository.py:123:21 error[unresolved-attribute] Attribute `token` is not defined on `None` in union `BitBucketCredentials | None`
- src/integrations/prefect-bitbucket/prefect_bitbucket/repository.py:124:24 error[unresolved-attribute] Attribute `username` is not defined on `None` in union `BitBucketCredentials | None`
- src/integrations/prefect-dbt/prefect_dbt/core/_orchestrator.py:1289:28 error[unsupported-operator] Operator `in` is not supported between objects of type `Literal["execution_time"]` and `Unknown | None`
- src/integrations/prefect-dbt/prefect_dbt/core/_orchestrator.py:1290:71 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- src/prefect/utilities/pydantic.py:192:5 error[invalid-assignment] Object of type `def __init__(__pydantic_self__: M@add_type_dispatch, **data: Any) -> None` is not assignable to attribute `__init__` of type `Overload[(self, o: object, /) -> None, (self, name: str, bases: tuple[type, ...], dict: dict[str, Any], /, **kwds: Any) -> None]`
+ src/prefect/utilities/pydantic.py:192:5 error[invalid-assignment] Object of type `def __init__(__pydantic_self__: M@add_type_dispatch, **data: Any) -> None` is not assignable to attribute `__init__` on type `type[M@add_type_dispatch] & ~<Protocol with members '__dispatch_key__'>`
- src/prefect/utilities/pydantic.py:193:5 error[invalid-assignment] Object of type `def __new__(cls: type[M@add_type_dispatch], **kwargs: Any) -> M@add_type_dispatch` is not assignable to attribute `__new__` of type `def __new__(mcs, cls_name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any], __pydantic_generic_metadata__: PydanticGenericMetadata | None = None, __pydantic_reset_parent_namespace__: bool = True, _create_model_module: str | None = None, **kwargs: Any) -> type`
+ src/prefect/utilities/pydantic.py:193:5 error[invalid-assignment] Object of type `def __new__(cls: type[M@add_type_dispatch], **kwargs: Any) -> M@add_type_dispatch` is not assignable to attribute `__new__` on type `type[M@add_type_dispatch] & ~<Protocol with members '__dispatch_key__'>`

pytest (https://github.com/pytest-dev/pytest)
- src/_pytest/runner.py:127:27 error[unresolved-attribute] Object of type `Item` has no attribute `_request`
- src/_pytest/runner.py:130:9 error[unresolved-attribute] Object of type `Item` has no attribute `_initrequest`
+ src/_pytest/runner.py:130:9 error[unresolved-attribute] Object of type `Item & <Protocol with members '_request'>` has no attribute `_initrequest`
- src/_pytest/runner.py:146:9 error[unresolved-attribute] Unresolved attribute `_request` on type `Item`
+ src/_pytest/runner.py:146:9 error[invalid-assignment] Object of type `Literal[False]` is not assignable to attribute `_request` on type `Item & <Protocol with members '_request'>`
- src/_pytest/runner.py:147:9 error[unresolved-attribute] Unresolved attribute `funcargs` on type `Item`
+ src/_pytest/runner.py:147:9 error[invalid-assignment] Object of type `None` is not assignable to attribute `funcargs` on type `Item & <Protocol with members '_request'>`

rotki (https://github.com/rotki/rotki)
+ rotkehlchen/chain/evm/names.py:63:94 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ rotkehlchen/chain/evm/names.py:67:73 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- rotkehlchen/chain/zksync_lite/manager.py:646:39 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `tuple[int, HistoryEventType, HistoryEventSubType, Asset, FVal, ChecksumAddress, ChecksumAddress | None, str]`, found `tuple[Literal[0], Literal[HistoryEventType.WITHDRAWAL], Literal[HistoryEventSubType.BRIDGE], Asset, FVal, ChecksumAddress | None, None, str]`
- rotkehlchen/chain/zksync_lite/manager.py:700:39 error[invalid-argument-type] Argument to bound method `append` is incorrect: Expected `tuple[int, HistoryEventType, HistoryEventSubType, Asset, FVal, ChecksumAddress, ChecksumAddress | None, str]`, found `tuple[Literal[0], Literal[HistoryEventType.RECEIVE], Literal[HistoryEventSubType.NONE], Asset, FVal, ChecksumAddress | None, ChecksumAddress, str]`
+ rotkehlchen/tests/api/test_ens.py:62:94 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ rotkehlchen/tests/api/test_ens.py:66:73 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

scikit-learn (https://github.com/scikit-learn/scikit-learn)
- sklearn/compose/_column_transformer.py:1085:29 error[unresolved-attribute] Object of type `Self@transform` has no attribute `feature_names_in_`
+ sklearn/compose/_column_transformer.py:1085:29 error[not-subscriptable] Cannot subscript object of type `object` with no `__getitem__` method
- sklearn/decomposition/_dict_learning.py:2321:23 error[no-matching-overload] No overload matches arguments
- sklearn/decomposition/_dict_learning.py:2322:23 error[no-matching-overload] No overload matches arguments
- sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py:786:32 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- sklearn/externals/array_api_extra/_lib/_utils/_helpers.py:194:16 error[invalid-return-type] Return type does not match returned value: expected `tuple[Array, Array]`, found `tuple[Array | int | float | complex, Array | int | float | complex]`
- sklearn/linear_model/_ridge.py:252:22 error[no-matching-overload] No overload of function `atleast_1d` matches arguments

scipy (https://github.com/scipy/scipy)
- scipy/_lib/_util.py:274:23 error[invalid-argument-type] Method `__getitem__` of type `Overload[(index: SupportsIndex, /) -> Unknown, (index: slice[Any, Any, Any], /) -> tuple[Unknown, ...]]` cannot be called with key of type `None` on object of type `tuple[Unknown, ...]`
- scipy/integrate/tests/test_quadrature.py:539:15 error[no-matching-overload] No overload of function `broadcast_to` matches arguments
- scipy/interpolate/_fitpack_impl.py:130:9 error[invalid-assignment] Invalid subscript assignment with key of type `Literal["u"]` and value of type `Unknown | None` on object of type `dict[str, ndarray[tuple[Any, ...], dtype[Any]] | int]`
- scipy/interpolate/_fitpack_impl.py:132:35 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- scipy/interpolate/_fitpack_impl.py:136:35 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- scipy/ndimage/_morphology.py:940:9 error[no-matching-overload] No overload matches arguments
- scipy/ndimage/_morphology.py:941:9 error[no-matching-overload] No overload matches arguments
- scipy/ndimage/_morphology.py:1166:9 error[no-matching-overload] No overload matches arguments
- scipy/ndimage/_morphology.py:2382:12 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2384:12 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2387:9 error[invalid-assignment] Cannot assign to a subscript on an object of type `None`
- scipy/ndimage/_morphology.py:2391:12 error[unresolved-attribute] Attribute `ndim` is not defined on `None` in union `Unknown | None | ndarray[tuple[Any, ...], Unknown]`
- scipy/ndimage/_morphology.py:2393:24 error[unresolved-attribute] Attribute `size` is not defined on `None` in union `Unknown | None | ndarray[tuple[Any, ...], Unknown]`
- scipy/ndimage/_morphology.py:2393:57 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None | ndarray[tuple[Any, ...], Unknown]`
- scipy/ndimage/_morphology.py:2398:10 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- scipy/ndimage/_morphology.py:2398:10 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- scipy/ndimage/_morphology.py:2407:16 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2409:16 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2414:25 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2415:29 error[not-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- scipy/ndimage/_morphology.py:2417:13 error[invalid-assignment] Cannot assign to a subscript on an object of type `None`
- scipy/ndimage/_morphology.py:2577:12 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2579:12 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2587:49 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2595:16 error[unresolved-attribute] Attribute `shape` is not defined on `None` in union `Unknown | None`
- scipy/ndimage/_morphology.py:2597:16 error[unresolved-attribute] Attribute `dtype` is not defined on `None` in union `Unknown | None`
+ scipy/optimize/_lsq/trf.py:235:19 error[not-subscriptable] Cannot subscript object of type `float` with no `__getitem__` method
+ scipy/optimize/_lsq/trf.py:235:19 error[not-subscriptable] Cannot subscript object of type `int` with no `__getitem__` method
+ scipy/optimize/_lsq/trf.py:285:23 error[not-subscriptable] Cannot subscript object of type `float` with no `__getitem__` method
+ scipy/optimize/_lsq/trf.py:285:23 error[not-subscriptable] Cannot subscript object of type `int` with no `__getitem__` method
- scipy/spatial/transform/_rigid_transform.py:1400:25 error[unresolved-attribute] Attribute `dtype` is not defined on `int`, `slice[Any, Any, Any]`, `EllipsisType`, `None`, `Buffer`, `_SupportsArray[dtype[Any]]`, `_NestedSequence[_SupportsArray[dtype[Any]]]`, `float`, `complex`, `str`, `_NestedSequence[int | float | complex | bytes | str]` in union `int | slice[Any, Any, Any] | EllipsisType | None | ArrayLike`
- scipy/spatial/transform/_rigid_transform.py:1402:36 error[unresolved-attribute] Attribute `dtype` is not defined on `int`, `slice[Any, Any, Any]`, `EllipsisType`, `None`, `Buffer`, `_SupportsArray[dtype[Any]]`, `_NestedSequence[_SupportsArray[dtype[Any]]]`, `float`, `complex`, `str`, `_NestedSequence[int | float | complex | bytes | str]` in union `int | slice[Any, Any, Any] | EllipsisType | None | ArrayLike`
- scipy/spatial/transform/_rotation.py:2219:25 error[unresolved-attribute] Object of type `int | slice[Any, Any, Any] | EllipsisType | None` has no attribute `dtype`
- scipy/spatial/transform/_rotation.py:2221:42 error[unresolved-attribute] Object of type `int | slice[Any, Any, Any] | EllipsisType | None` has no attribute `dtype`
- subprojects/array_api_extra/src/array_api_extra/_lib/_utils/_helpers.py:194:16 error[invalid-return-type] Return type does not match returned value: expected `tuple[Array, Array]`, found `tuple[Array | int | float | complex, Array | int | float | complex]`

scrapy (https://github.com/scrapy/scrapy)
- scrapy/core/spidermw.py:351:29 error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Iterable[_T@_process_spider_output] | AsyncIterator[_T@_process_spider_output] | Iterable[Unknown] | AsyncIterator[Unknown]`

setuptools (https://github.com/pypa/setuptools)
- setuptools/_imp.py:42:24 error[invalid-argument-type] Argument to function `issubclass` is incorrect: Expected `type`, found `Unknown | Loader | None`
- setuptools/_imp.py:50:24 error[invalid-argument-type] Argument to function `issubclass` is incorrect: Expected `type`, found `Unknown | Loader | None`
- setuptools/_vendor/more_itertools/more.py:4671:13 error[call-non-callable] Object of type `None` is not callable
- setuptools/_vendor/more_itertools/more.py:4695:13 error[call-non-callable] Object of type `None` is not callable
- setuptools/_vendor/more_itertools/more.py:4749:13 error[call-non-callable] Object of type `None` is not callable
- setuptools/_vendor/more_itertools/recipes.py:540:13 error[call-non-callable] Object of type `None` is not callable

spack (https://github.com/spack/spack)
- lib/spack/spack/audit.py:422:25 error[no-matching-overload] No overload of bound method `join` matches arguments
- lib/spack/spack/package_base.py:1772:21 error[unresolved-attribute] Object of type `Self@do_patch` has no attribute `patch`
+ lib/spack/spack/package_base.py:1772:21 error[call-top-callable] Object of type `Top[(...) -> object]` is not safe to call; its signature is not known

sphinx (https://github.com/sphinx-doc/sphinx)
- sphinx/ext/imgmath.py:269:9 error[unresolved-attribute] Unresolved attribute `_imgmath_warned_latex` on type `StandaloneHTMLBuilder`
- sphinx/ext/imgmath.py:279:9 error[unresolved-attribute] Unresolved attribute `_imgmath_warned_image_translator` on type `StandaloneHTMLBuilder`

static-frame (https://github.com/static-frame/static-frame)
+ static_frame/core/container_util.py:1830:66 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/frame.py:7561:43 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/index_hierarchy.py:1880:77 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
+ static_frame/core/loc_map.py:187:32 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive
- static_frame/core/util.py:1429:26 error[no-matching-overload] No overload matches arguments
+ static_frame/core/util.py:3092:65 warning[unused-type-ignore-comment] Unused blanket `type: ignore` directive

sympy (https://github.com/sympy/sympy)
+ sympy/solvers/solveset.py:3137:19 error[unresolved-attribute] Object of type `object` has no attribute `name`
+ sympy/solvers/solveset.py:3167:15 error[no-matching-overload] No overload of bound method `subs` matches arguments
- sympy/solvers/solveset.py:3129:25 error[invalid-argument-type] Argument to function `next` is incorrect: Expected `SupportsNext[Unknown]`, found `tuple[Unknown, ...] | (Unknown & <Protocol with members '__iter__'>)`

xarray (https://github.com/pydata/xarray)
- xarray/core/groupby.py:770:22 error[invalid-argument-type] Argument to bound method `_to_temp_dataset` is incorrect: Expected `DataArray`, found `T_Xarray@GroupBy`
- xarray/core/groupby.py:776:20 error[invalid-argument-type] Argument to bound method `_shuffle` is incorrect: Argument type `T_Xarray@GroupBy` does not satisfy upper bound `DataArray` of type variable `Self`
- xarray/core/groupby.py:776:20 error[invalid-argument-type] Argument to bound method `_shuffle` is incorrect: Argument type `T_Xarray@GroupBy` does not satisfy upper bound `Dataset` of type variable `Self`
- xarray/core/groupby.py:781:20 error[invalid-argument-type] Argument to bound method `_from_temp_dataset` is incorrect: Argument type `T_Xarray@GroupBy` does not satisfy upper bound `DataArray` of type variable `Self`
+ xarray/core/groupby.py:781:20 error[invalid-return-type] Return type does not match returned value: expected `T_Xarray@GroupBy`, found `DataArray`

Full report with detailed diff (timing results)

@mtshiba mtshiba force-pushed the narrow-by-aliased-conditional-expr-minimal branch from 950c3e0 to 3a5a4b7 Compare March 30, 2026 09:23
@mtshiba mtshiba force-pushed the narrow-by-aliased-conditional-expr-minimal branch from 3a5a4b7 to a59b9b9 Compare March 30, 2026 09:45
@mtshiba mtshiba marked this pull request as ready for review March 30, 2026 10:34
@carljm carljm removed their request for review March 30, 2026 17:04
@sharkdp
Copy link
Copy Markdown
Contributor

sharkdp commented Mar 31, 2026

Thank you! I'm planning to take a look soon.

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.

Type narrowing fails to account for reassignment in a conditional based on an intermediate variable (aliased conditional expressions)

2 participants