Skip to content

[ty] Avoid literal promotion when constrained bounds#23209

Merged
charliermarsh merged 2 commits intomainfrom
charlie/literal
Feb 10, 2026
Merged

[ty] Avoid literal promotion when constrained bounds#23209
charliermarsh merged 2 commits intomainfrom
charlie/literal

Conversation

@charliermarsh
Copy link
Member

Summary

Closes astral-sh/ty#2771.

@charliermarsh charliermarsh added ty Multi-file analysis & type inference bug Something isn't working labels Feb 10, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 10, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 10, 2026

mypy_primer results

Changes were detected when running on open source projects
porcupine (https://github.com/Akuli/porcupine)
- porcupine/pluginmanager.py:133:49: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Never]`, found `Unknown | str`
- Found 25 diagnostics
+ Found 24 diagnostics

Expression (https://github.com/cognitedata/Expression)
+ tests/test_compose.py:21:16: error[invalid-assignment] Object of type `(Never, /) -> Never` is not assignable to `(int, /) -> int`
- Found 204 diagnostics
+ Found 205 diagnostics

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `Unknown | Coroutine[Any, Any, Unknown]`
+ src/prefect/input/run_input.py:672:20: error[invalid-return-type] Return type does not match returned value: expected `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]`, found `T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler] | Coroutine[Any, Any, T@GetAutomaticInputHandler | AutomaticRunInput[T@GetAutomaticInputHandler]]`

pandas (https://github.com/pandas-dev/pandas)
- pandas/io/json/_json.py:853:16: error[no-matching-overload] No overload of bound method `read` matches arguments
- pandas/tests/io/json/test_readlines.py:244:10: error[invalid-context-manager] Object of type `JsonReader[str]` cannot be used with `with` because it does not correctly implement `__enter__` or `__exit__`
- pandas/tests/io/json/test_readlines.py:245:9: error[no-matching-overload] No overload of bound method `read` matches arguments
- Found 4439 diagnostics
+ Found 4436 diagnostics

sympy (https://github.com/sympy/sympy)
- sympy/algebras/tests/test_quaternion.py:422:33: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/codegen/tests/test_matrix_nodes.py:27:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/eigen.py:1202:37: error[unresolved-attribute] Object of type `T2'return@call_highest_priority | T1'return@call_highest_priority` has no attribute `pow`
- sympy/matrices/expressions/tests/test_blockmatrix.py:235:13: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:235:33: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:235:53: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:459:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_derivatives.py:551:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matadd.py:36:12: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase` and `MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matpow.py:124:47: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/inverse.py:385:11: error[unsupported-operator] Operator `-` is not supported between objects of type `MatrixBase` and `MatrixBase | Expr | Unknown`
- sympy/matrices/inverse.py:393:11: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase` and `MatrixBase | Expr | Unknown`
- sympy/matrices/matrixbase.py:979:18: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@_eval_wilkinson`
- sympy/matrices/matrixbase.py:2957:16: error[invalid-return-type] Return type does not match returned value: expected `Self@_eval_pow_by_cayley`, found `Self@_eval_pow_by_cayley | T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/matrixbase.py:3256:16: error[invalid-return-type] Return type does not match returned value: expected `MatrixBase`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/matrixbase.py:3256:29: error[invalid-argument-type] Argument is incorrect: Expected `T2'return@call_highest_priority | T1'return@call_highest_priority`, found `MatrixBase`
- sympy/matrices/matrixbase.py:3310:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase`
- sympy/matrices/matrixbase.py:3314:16: error[invalid-return-type] Return type does not match returned value: expected `Tmat@__sub__`, found `MatrixBase`
- sympy/matrices/matrixbase.py:4386:16: error[unsupported-operator] Operator `+` is not supported between two objects of type `Self@add`
- sympy/matrices/matrixbase.py:4923:16: error[invalid-return-type] Return type does not match returned value: expected `Self@analytic_func`, found `Self@analytic_func | T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/repmatrix.py:321:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `Self@_eval_is_symmetric`
- sympy/matrices/tests/test_commonmatrix.py:1249:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_eigen.py:406:20: error[invalid-argument-type] Argument to function `max` is incorrect: Expected `Iterable[Unknown]`, found `MatrixBase | Unknown`
- sympy/matrices/tests/test_immutable.py:105:23: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:121:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:123:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:141:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2179:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2207:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2908:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2921:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2936:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2937:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2948:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:3471:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:3478:12: warning[possibly-missing-attribute] Attribute `rank` may be missing on object of type `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_matrices.py:3479:12: warning[possibly-missing-attribute] Attribute `rank` may be missing on object of type `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_matrixbase.py:491:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:493:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:544:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:823:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_matrixbase.py:876:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:878:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:900:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:2931:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:2959:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3610:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3624:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3639:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3640:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3652:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_reductions.py:377:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_reductions.py:384:12: warning[possibly-missing-attribute] Attribute `rank` may be missing on object of type `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_reductions.py:385:12: warning[possibly-missing-attribute] Attribute `rank` may be missing on object of type `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_solvers.py:68:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_sparse.py:573:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableSparseMatrix`
- sympy/matrices/tests/test_sparse.py:577:52: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableSparseMatrix`
- sympy/matrices/tests/test_sparse.py:593:17: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableSparseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:13:6: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:16:38: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:16:84: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:16:131: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:21:44: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:21:90: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:21:137: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:25:37: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:25:83: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/parsing/autolev/test-examples/ruletest5.py:25:130: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
+ sympy/parsing/mathematica.py:692:38: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Iterable[Never]`, found `Unknown | list[Unknown | str]`
- sympy/physics/control/tests/test_lti.py:3733:31: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/control/tests/test_lti.py:3733:38: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/mechanics/lagrange.py:222:23: error[unsupported-operator] Operator `-` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/lagrange.py:346:17: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:217:28: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:229:29: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:241:29: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/tests/test_jointsmethod.py:247:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/mechanics/tests/test_jointsmethod.py:249:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/quantum/tests/test_represent.py:89:17: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase | Expr` and `MatrixBase`
- sympy/physics/quantum/tests/test_represent.py:91:24: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/physics/quantum/tests/test_represent.py:93:28: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase | Expr`
- sympy/physics/vector/functions.py:380:21: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `MatrixBase | Unknown`
- sympy/solvers/tests/test_numeric.py:137:11: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/solvers/tests/test_solvers.py:722:19: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/solvers/tests/test_solvers.py:723:19: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/solvers/tests/test_solvers.py:724:19: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/solvers/tests/test_solvers.py:724:30: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/stats/tests/test_symbolic_multivariate.py:84:36: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/stats/tests/test_symbolic_multivariate.py:84:84: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/stats/tests/test_symbolic_multivariate.py:85:36: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/tensor/tests/test_tensor.py:1693:19: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/tensor/tests/test_tensor.py:1694:23: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- Found 15920 diagnostics
+ Found 15830 diagnostics

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 10, 2026

Memory usage report

Summary

Project Old New Diff Outcome
flake8 51.85MB 51.85MB -0.0% (-0.00MB) ⬇️
trio 123.95MB 123.94MB -0.0% (-0.00MB) ⬇️
prefect 710.27MB 710.27MB -0.0% (-0.00MB) ⬇️
sphinx 282.30MB 282.30MB -0.0% (-0.00MB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
infer_definition_types 1.94MB 1.94MB -0.0% (-0.00MB) ⬇️

prefect

Name Old New Diff Outcome
Specialization 2.55MB 2.55MB -0.0% (-0.00MB) ⬇️
GenericAlias 1.20MB 1.20MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_::interned_arguments 1.44MB 1.44MB -0.0% (-0.00MB) ⬇️
infer_expression_types_impl 53.40MB 53.40MB -0.0% (-0.00MB) ⬇️
infer_definition_types 86.72MB 86.72MB -0.0% (-0.00MB) ⬇️
TupleType < 'db >::to_class_type_ 0.49MB 0.49MB -0.1% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_ 6.23MB 6.23MB -0.0% (-0.00MB) ⬇️
inferable_typevars_inner 0.17MB 0.17MB -0.1% (-0.00MB) ⬇️
infer_expression_type_impl 10.79MB 10.79MB -0.0% (-0.00MB) ⬇️
Type < 'db >::member_lookup_with_policy_ 15.84MB 15.84MB -0.0% (-0.00MB) ⬇️
infer_scope_types_impl 59.94MB 59.94MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::implicit_attribute_inner_ 10.27MB 10.27MB -0.0% (-0.00MB) ⬇️

sphinx

Name Old New Diff Outcome
Specialization 1.08MB 1.08MB -0.0% (-0.00MB) ⬇️
GenericAlias 0.47MB 0.47MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_::interned_arguments 0.50MB 0.50MB -0.0% (-0.00MB) ⬇️
infer_definition_types 24.48MB 24.48MB -0.0% (-0.00MB) ⬇️
infer_expression_types_impl 22.29MB 22.29MB -0.0% (-0.00MB) ⬇️
TupleType < 'db >::to_class_type_ 0.16MB 0.16MB -0.3% (-0.00MB) ⬇️
infer_scope_types_impl 18.32MB 18.32MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_ 2.22MB 2.22MB -0.0% (-0.00MB) ⬇️
inferable_typevars_inner 0.08MB 0.08MB -0.2% (-0.00MB) ⬇️
infer_deferred_types 6.10MB 6.10MB -0.0% (-0.00MB) ⬇️

trio

Name Old New Diff Outcome
Specialization 0.49MB 0.49MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_::interned_arguments 0.21MB 0.21MB -0.0% (-0.00MB) ⬇️
GenericAlias 0.21MB 0.21MB -0.0% (-0.00MB) ⬇️
StaticClassLiteral < 'db >::try_mro_ 0.90MB 0.90MB -0.0% (-0.00MB) ⬇️
inferable_typevars_inner 0.07MB 0.07MB -0.2% (-0.00MB) ⬇️
TupleType < 'db >::to_class_type_ 0.06MB 0.06MB -0.3% (-0.00MB) ⬇️
infer_expression_types_impl 5.88MB 5.88MB -0.0% (-0.00MB) ⬇️
infer_definition_types 7.54MB 7.54MB -0.0% (-0.00MB) ⬇️
infer_scope_types_impl 5.83MB 5.83MB +0.0% (0.00MB) ⬇️

@charliermarsh charliermarsh marked this pull request as ready for review February 10, 2026 20:55
Copy link
Member

@ibraheemdev ibraheemdev left a comment

Choose a reason for hiding this comment

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

We could also apply the same fix for typevars with upper bounds. Also note that there are likely many edge cases here, and this will all be fixed by the new constraint solver, so it's probably not worth spending too much time on.

@charliermarsh
Copy link
Member Author

Good call, thank you.

@AlexWaygood AlexWaygood removed their request for review February 10, 2026 21:19
@charliermarsh charliermarsh enabled auto-merge (squash) February 10, 2026 21:25
@charliermarsh charliermarsh merged commit 0cef8aa into main Feb 10, 2026
49 checks passed
@charliermarsh charliermarsh deleted the charlie/literal branch February 10, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Literal promotion should respect Literal upper bounds

2 participants