Skip to content

Comments

[ty] remove static_expression_truthiness and improve reachability analysis#22971

Merged
carljm merged 1 commit intoastral-sh:mainfrom
mtshiba:remove-static-expression-truthiness
Jan 30, 2026
Merged

[ty] remove static_expression_truthiness and improve reachability analysis#22971
carljm merged 1 commit intoastral-sh:mainfrom
mtshiba:remove-static-expression-truthiness

Conversation

@mtshiba
Copy link
Collaborator

@mtshiba mtshiba commented Jan 30, 2026

Summary

cf: #19579, #20566 (comment)

Currently, we use the query static_expression_truthiness to determine the truthiness of an expression.
This always determines the truthinesses of non-definitely-bound places as Ambiguous, preventing cycles that occur when their reachabilities depend on themselves. However, this can lead to inaccurate analysis of code like the following.

def _(flag: bool):
    if flag:
        ALWAYS_TRUE_IF_BOUND = True

    # error: [possibly-unresolved-reference] "Name `ALWAYS_TRUE_IF_BOUND` used when possibly not defined"
    if ALWAYS_TRUE_IF_BOUND:
        x = 1
    else:
        x = 2

    # If `ALWAYS_TRUE_IF_BOUND` were not defined, an error would occur, and therefore the `x = 2` branch would never be executed.
    reveal_type(x)  # expected: Literal[1], but: Literal[1, 2]

Since #20566, we can determine the Place by looking at the previous cycle result.
Therefore, we can now remove static_expression_truthiness, improving reachability analysis of the above code.

Test Plan

mdtest updated

@mtshiba mtshiba added the ty Multi-file analysis & type inference label Jan 30, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 30, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 30, 2026

mypy_primer results

Changes were detected when running on open source projects
pip (https://github.com/pypa/pip)
- src/pip/_internal/resolution/legacy/resolver.py:455:69: error[invalid-argument-type] Argument to bound method `prepare_installed_requirement` is incorrect: Expected `str`, found `str | None`
- src/pip/_internal/resolution/legacy/resolver.py:477:20: warning[possibly-missing-attribute] Attribute `scheme` may be missing on object of type `Unknown | Link | None`
- Found 625 diagnostics
+ Found 623 diagnostics

spack (https://github.com/spack/spack)
- lib/spack/spack/test/builder.py:137:12: error[unresolved-attribute] Object of type `Builder` has no attribute `pkg_with_dispatcher`
- Found 4338 diagnostics
+ Found 4337 diagnostics

kopf (https://github.com/nolar/kopf)
- kopf/_kits/hierarchies.py:51:21: error[invalid-assignment] Object of type `list[Unknown]` is not assignable to attribute `owner_references` on type `V1ObjectMetaProtocol | None`
- kopf/_kits/hierarchies.py:89:21: error[invalid-assignment] Object of type `list[Unknown]` is not assignable to attribute `owner_references` on type `V1ObjectMetaProtocol | None`
- kopf/_kits/hierarchies.py:130:21: error[invalid-assignment] Object of type `dict[Unknown, Unknown]` is not assignable to attribute `labels` on type `V1ObjectMetaProtocol | None`
- kopf/_kits/hierarchies.py:191:56: warning[possibly-missing-attribute] Attribute `generate_name` may be missing on object of type `V1ObjectMetaProtocol | None`
- Found 296 diagnostics
+ Found 292 diagnostics

ignite (https://github.com/pytorch/ignite)
- tests/ignite/metrics/test_precision.py:377:17: warning[possibly-missing-attribute] Attribute `cpu` may be missing on object of type `Unknown | int | float | ... omitted 3 union elements`
- tests/ignite/metrics/test_precision.py:461:17: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:462:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:462:48: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:467:21: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:468:28: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:468:54: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:471:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:471:68: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:471:89: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:494:17: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:495:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:495:48: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:500:21: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:501:28: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:501:54: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:504:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:504:68: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_precision.py:504:89: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:380:17: warning[possibly-missing-attribute] Attribute `cpu` may be missing on object of type `Unknown | int | float | ... omitted 3 union elements`
- tests/ignite/metrics/test_recall.py:463:17: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:464:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:464:48: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:469:21: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:470:28: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:470:54: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:473:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:473:68: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:473:89: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:497:17: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:498:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:498:48: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:503:21: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:504:28: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:504:54: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:507:24: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:507:68: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- tests/ignite/metrics/test_recall.py:507:89: warning[possibly-missing-attribute] Attribute `device` may be missing on object of type `int | Unknown`
- Found 2072 diagnostics
+ Found 2034 diagnostics

dulwich (https://github.com/dulwich/dulwich)
- dulwich/porcelain/__init__.py:2138:18: warning[possibly-unresolved-reference] Name `path1` used when possibly not defined
- dulwich/porcelain/__init__.py:2143:18: warning[possibly-unresolved-reference] Name `path2` used when possibly not defined
- Found 227 diagnostics
+ Found 225 diagnostics

pyodide (https://github.com/pyodide/pyodide)
- src/tests/test_webloop.py:466:16: error[unresolved-attribute] Object of type `AbstractEventLoop` has no attribute `_in_progress`
- Found 939 diagnostics
+ Found 938 diagnostics

trio (https://github.com/python-trio/trio)
- src/trio/_tests/test_ssl.py:925:15: error[call-non-callable] Object of type `None` is not callable
- src/trio/testing/_raises_group.py:714:17: error[unsupported-operator] Operator `+=` is not supported between objects of type `None` and `str`
- src/trio/testing/_raises_group.py:714:88: warning[possibly-unresolved-reference] Name `expected` used when possibly not defined
- src/trio/testing/_raises_group.py:714:136: warning[possibly-unresolved-reference] Name `expected` used when possibly not defined
- Found 481 diagnostics
+ Found 477 diagnostics

prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `dict[Any, Any] | int | dict[str, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/integrations/prefect-dbt/prefect_dbt/core/settings.py:94:28: error[invalid-assignment] Object of type `dict[str, Any] | int | dict[Any, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
- src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `dict[Any, Any] | int | dict[str, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
+ src/prefect/cli/deploy/_core.py:86:21: error[invalid-assignment] Object of type `dict[str, Any] | int | dict[Any, Any] | ... omitted 4 union elements` is not assignable to `dict[str, Any]`
- src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Argument type `dict[Any, Any] | int | dict[str, Any] | ... omitted 4 union elements` does not satisfy constraints (`str`, `int`, `int | float`, `bool`, `dict[Any, Any]`, `list[Any]`, `None`) of type variable `T`
+ src/prefect/deployments/steps/core.py:137:38: error[invalid-argument-type] Argument is incorrect: Argument type `dict[str, Any] | int | dict[Any, Any] | ... omitted 4 union elements` does not satisfy constraints (`str`, `int`, `int | float`, `bool`, `dict[Any, Any]`, `list[Any]`, `None`) of type variable `T`
- src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `Unknown | int | dict[str, Any] | ... omitted 4 union elements` on object of type `dict[str, Any]`
+ src/prefect/utilities/templating.py:320:13: error[invalid-assignment] Invalid subscript assignment with key of type `object` and value of type `dict[str, Any] | int | Unknown | ... omitted 4 union elements` on object of type `dict[str, Any]`
- src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | int | dict[str, Any] | ... omitted 4 union elements]`
+ src/prefect/utilities/templating.py:323:16: error[invalid-return-type] Return type does not match returned value: expected `T@resolve_block_document_references | dict[str, Any]`, found `list[Unknown | dict[str, Any] | int | ... omitted 4 union elements]`
- src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Argument type `str | int | dict[str, Any] | ... omitted 3 union elements` does not satisfy constraints (`str`, `int`, `int | float`, `bool`, `dict[Any, Any]`, `list[Any]`, `None`) of type variable `T`
+ src/prefect/workers/base.py:232:13: error[invalid-argument-type] Argument is incorrect: Argument type `dict[str, Any] | int | str | ... omitted 3 union elements` does not satisfy constraints (`str`, `int`, `int | float`, `bool`, `dict[Any, Any]`, `list[Any]`, `None`) of type variable `T`

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:69:12: warning[possibly-missing-attribute] Attribute `vulnerability_budget` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:70:12: warning[possibly-missing-attribute] Attribute `vulnerabilities_request_limit` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:84:12: warning[possibly-missing-attribute] Attribute `is_first_vulnerability` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:85:12: warning[possibly-missing-attribute] Attribute `vulnerability_budget` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:86:12: warning[possibly-missing-attribute] Attribute `vulnerabilities_request_limit` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:87:12: warning[possibly-missing-attribute] Attribute `vulnerabilities_request_limit` may be missing on object of type `IASTEnvironment | None`
- tests/appsec/iast/taint_sinks/test_vulnerability_detection.py:88:12: warning[possibly-missing-attribute] Attribute `vulnerabilities_request_limit` may be missing on object of type `IASTEnvironment | None`
- Found 8560 diagnostics
+ Found 8553 diagnostics

static-frame (https://github.com/static-frame/static-frame)
- static_frame/core/util.py:1402:32: warning[possibly-unresolved-reference] Name `rows` used when possibly not defined
- Found 1827 diagnostics
+ Found 1826 diagnostics

sympy (https://github.com/sympy/sympy)
- sympy/polys/matrices/tests/test_xxm.py:88:20: warning[possibly-missing-attribute] Attribute `to_ddm` may be missing on object of type `SDM | DDM | DFM | DFM_dummy`
- sympy/polys/matrices/tests/test_xxm.py:90:20: warning[possibly-missing-attribute] Attribute `to_ddm` may be missing on object of type `SDM | DDM | DFM | DFM_dummy`
- sympy/polys/matrices/tests/test_xxm.py:94:20: warning[possibly-missing-attribute] Attribute `to_ddm` may be missing on object of type `SDM | DDM | DFM | DFM_dummy`
- sympy/polys/numberfields/galoisgroups.py:126:21: warning[possibly-unresolved-reference] Name `current_degree` used when possibly not defined
- Found 15656 diagnostics
+ Found 15652 diagnostics

core (https://github.com/home-assistant/core)
- homeassistant/components/universal/media_player.py:677:24: warning[possibly-unresolved-reference] Name `child_state_order` used when possibly not defined
+ homeassistant/util/variance.py:47:12: error[invalid-return-type] Return type does not match returned value: expected `(**_P@ignore_variance) -> _R@ignore_variance`, found `_Wrapped[_P@ignore_variance, int | _R@ignore_variance | float | datetime, _P@ignore_variance, _R@ignore_variance | int | float | datetime]`

scipy (https://github.com/scipy/scipy)
- scipy/optimize/tests/test_bracket.py:318:9: error[unresolved-attribute] Unresolved attribute `count` on type `def f(x) -> Unknown`
- scipy/stats/tests/test_resampling.py:1223:16: error[unresolved-attribute] Function `test` has no attribute `batch_size`
- scipy/stats/tests/test_resampling.py:1226:9: error[unresolved-attribute] Unresolved attribute `counter` on type `def test(x, axis) -> Unknown`
- scipy/stats/tests/test_resampling.py:1228:16: error[unresolved-attribute] Function `test` has no attribute `counter`
- scipy/stats/tests/test_resampling.py:1229:16: error[unresolved-attribute] Function `test` has no attribute `batch_size`
- scipy/stats/tests/test_resampling.py:1232:9: error[unresolved-attribute] Unresolved attribute `counter` on type `def test(x, axis) -> Unknown`
- scipy/stats/tests/test_resampling.py:1234:16: error[unresolved-attribute] Function `test` has no attribute `counter`
- scipy/stats/tests/test_resampling.py:1235:16: error[unresolved-attribute] Function `test` has no attribute `batch_size`
- scipy/stats/tests/test_resampling.py:1415:16: error[unresolved-attribute] Function `statistic` has no attribute `batch_size`
- scipy/stats/tests/test_resampling.py:1417:9: error[unresolved-attribute] Unresolved attribute `counter` on type `def statistic(x, y, axis) -> Unknown`
- scipy/stats/tests/test_resampling.py:1420:16: error[unresolved-attribute] Function `statistic` has no attribute `counter`
- scipy/stats/tests/test_resampling.py:1421:16: error[unresolved-attribute] Function `statistic` has no attribute `batch_size`
- scipy/stats/tests/test_resampling.py:1423:9: error[unresolved-attribute] Unresolved attribute `counter` on type `def statistic(x, y, axis) -> Unknown`
- scipy/stats/tests/test_resampling.py:1426:16: error[unresolved-attribute] Function `statistic` has no attribute `counter`
- scipy/stats/tests/test_resampling.py:1427:16: error[unresolved-attribute] Function `statistic` has no attribute `batch_size`
- Found 8057 diagnostics
+ Found 8042 diagnostics

Memory usage changes were detected when running on open source projects
sphinx (https://github.com/sphinx-doc/sphinx)
- TOTAL MEMORY USAGE: ~287MB
+ TOTAL MEMORY USAGE: ~301MB

@astral-sh-bot
Copy link

astral-sh-bot bot commented Jan 30, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
possibly-missing-attribute 0 50 0
unresolved-attribute 0 17 0
invalid-argument-type 2 2 3
invalid-assignment 0 3 4
invalid-parameter-default 0 0 7
possibly-unresolved-reference 0 7 0
invalid-return-type 0 4 2
unused-type-ignore-comment 0 2 0
call-non-callable 0 1 0
unsupported-operator 0 1 0
Total 2 87 16

Full report with detailed diff (timing results)

@mtshiba mtshiba marked this pull request as ready for review January 30, 2026 10:29
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

The ecosystem results look great, thank you!

@carljm carljm merged commit 48a4d9d into astral-sh:main Jan 30, 2026
51 checks passed
@mtshiba mtshiba deleted the remove-static-expression-truthiness branch January 31, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants