Skip to content

[ty] report unused bindings as unnecessary hint diagnostics#23305

Open
denyszhak wants to merge 10 commits intoastral-sh:mainfrom
denyszhak:feat/unused-binding-diagnostics
Open

[ty] report unused bindings as unnecessary hint diagnostics#23305
denyszhak wants to merge 10 commits intoastral-sh:mainfrom
denyszhak:feat/unused-binding-diagnostics

Conversation

@denyszhak
Copy link
Contributor

@denyszhak denyszhak commented Feb 16, 2026

Fixes astral-sh/ty#2607

Summary

Add unused-binding dimming in ty via diagnostics (Hint + DiagnosticTag::Unnecessary) so VS Code fades unused locals even without Pylance. VS Code default fading for “unused” is diagnostics-driven, so this PR uses diagnostics, not semantic tokens.

The unused-binding detection now lives in ty_python_semantic and is consumed by ty_server, with local-scope to avoid false positives for now. Cros-modile/class reference will be addressed in a follow up PR because it requires a bit more thinking and effort. Unused-binding analysis centralized in semantic (unused_bindings) so other IDE surfaces can reuse it later (for example emit semantic info).

Test Plan

Added unit tests in unused_bindings.rs
Added/updated e2e diagnostics coverage in pull_diagnostics.rs
Manually tested in VSCode

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 16, 2026

Typing conformance results

No changes detected ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 16, 2026

mypy_primer results

Changes were detected when running on open source projects
spack (https://github.com/spack/spack)
- lib/spack/spack/verify_libraries.py:164:46: error[invalid-argument-type] Argument to function `candidate_matches` is incorrect: Expected `bytes`, found `Unknown | bytes | str | PathLike[str] | PathLike[bytes]`
+ lib/spack/spack/verify_libraries.py:164:46: error[invalid-argument-type] Argument to function `candidate_matches` is incorrect: Expected `bytes`, found `bytes | Unknown | str | PathLike[str] | PathLike[bytes]`
- lib/spack/spack/verify_libraries.py:165:17: error[invalid-assignment] Invalid subscript assignment with key of type `Unknown | bytes | str | PathLike[str] | PathLike[bytes]` and value of type `Unknown | bytes | str | PathLike[str] | PathLike[bytes]` on object of type `dict[bytes, bytes]`
+ lib/spack/spack/verify_libraries.py:165:17: error[invalid-assignment] Invalid subscript assignment with key of type `bytes | Unknown | str | PathLike[str] | PathLike[bytes]` and value of type `bytes | Unknown | str | PathLike[str] | PathLike[bytes]` on object of type `dict[bytes, bytes]`
- lib/spack/spack/verify_libraries.py:170:57: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `list[bytes]`, found `list[Unknown | bytes | str | PathLike[str] | PathLike[bytes]]`
+ lib/spack/spack/verify_libraries.py:170:57: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `list[bytes]`, found `list[bytes | Unknown | str | PathLike[str] | PathLike[bytes]]`
- lib/spack/spack/verify_libraries.py:170:69: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `list[bytes]`, found `list[Unknown | bytes | str | PathLike[str] | PathLike[bytes]]`
+ lib/spack/spack/verify_libraries.py:170:69: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `list[bytes]`, found `list[bytes | Unknown | str | PathLike[str] | PathLike[bytes]]`

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

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

PyGithub (https://github.com/PyGithub/PyGithub)
- github/Requester.py:899:57: error[invalid-argument-type] Argument to bound method `__hostnameHasDomain` is incorrect: Expected `str | list[str]`, found `Unknown | list[Unknown | str] | list[None | Unknown | str]`
+ github/Requester.py:899:57: error[invalid-argument-type] Argument to bound method `__hostnameHasDomain` is incorrect: Expected `str | list[str]`, found `Unknown | list[Unknown | str] | list[str | Unknown | None]`

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

cloud-init (https://github.com/canonical/cloud-init)
- tests/unittests/distros/test_user_data_normalize.py:24:31: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[Unknown, Unknown]`, found `Unknown | dict[Unknown | str, Unknown | str] | str | ... omitted 3 union elements`
+ tests/unittests/distros/test_user_data_normalize.py:24:31: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[Unknown, Unknown]`, found `Unknown | bool | list[Unknown] | ... omitted 3 union elements`
- tests/unittests/sources/test_gce.py:71:31: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[Unknown, Unknown]`, found `Unknown | dict[Unknown | str, Unknown | str] | str | ... omitted 3 union elements`
+ tests/unittests/sources/test_gce.py:71:31: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `dict[Unknown, Unknown]`, found `Unknown | bool | list[Unknown] | ... omitted 3 union elements`

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- scripts/freshvenvs.py:343:69: error[invalid-argument-type] Argument to function `_versions_fully_cover_bounds` is incorrect: Expected `list[str]`, found `list[Version | Unknown] & ~AlwaysFalsy`
+ scripts/freshvenvs.py:343:69: error[invalid-argument-type] Argument to function `_versions_fully_cover_bounds` is incorrect: Expected `list[str]`, found `list[Unknown | Version] & ~AlwaysFalsy`
- tests/tracer/test_span.py:193:29: error[invalid-argument-type] Argument to bound method `set_metric` is incorrect: Expected `int | float`, found `int | float | complex | ... omitted 6 union elements`
+ tests/tracer/test_span.py:193:29: error[invalid-argument-type] Argument to bound method `set_metric` is incorrect: Expected `int | float`, found `int | Unknown | None | ... omitted 6 union elements`

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/cli/mz_workload_anonymize.py:251:13: error[no-matching-overload] No overload of bound method `join` matches arguments
- Found 527 diagnostics
+ Found 528 diagnostics

scikit-learn (https://github.com/scikit-learn/scikit-learn)
- sklearn/utils/tests/test_multiclass.py:399:27: error[unresolved-attribute] Attribute `toarray` is not defined on `list[Unknown | list[Unknown | int]] & SparseABC`, `ndarray[tuple[Any, ...], dtype[Any]] & SparseABC`, `_NotAnArray & SparseABC`, `list[Unknown | int] & SparseABC`, `list[Unknown | str] & SparseABC`, `list[Unknown | list[Unknown | str]] & SparseABC`, `list[Unknown] & SparseABC`, `list[Unknown | int | float] & SparseABC`, `list[Unknown | list[Unknown]] & SparseABC`, `list[Unknown | tuple[()]] & SparseABC`, `list[Unknown | ndarray[tuple[Any, ...], dtype[Unknown]]] & SparseABC`, `list[Unknown | set[Unknown | int]] & SparseABC`, `list[Unknown | frozenset[int | Unknown]] & SparseABC`, `list[Unknown | dict[Unknown | int, Unknown | str]] & SparseABC` in union `(Unknown & SparseABC) | (list[Unknown | list[Unknown | int]] & SparseABC) | (ndarray[tuple[Any, ...], dtype[Any]] & SparseABC) | ... omitted 12 union elements`
+ sklearn/utils/tests/test_multiclass.py:399:27: error[unresolved-attribute] Attribute `toarray` is not defined on `list[Unknown | list[Unknown | int]] & SparseABC`, `ndarray[tuple[Any, ...], dtype[Any]] & SparseABC`, `_NotAnArray & SparseABC`, `list[Unknown | int] & SparseABC`, `list[Unknown | str] & SparseABC`, `list[Unknown | list[Unknown | str]] & SparseABC`, `list[Unknown] & SparseABC`, `list[Unknown | int | float] & SparseABC`, `list[Unknown | list[Unknown]] & SparseABC`, `list[Unknown | tuple[()]] & SparseABC`, `list[Unknown | ndarray[tuple[Any, ...], dtype[Unknown]]] & SparseABC`, `list[Unknown | set[Unknown | int]] & SparseABC`, `list[Unknown | frozenset[Unknown | int]] & SparseABC`, `list[Unknown | dict[Unknown | int, Unknown | str]] & SparseABC` in union `(Unknown & SparseABC) | (list[Unknown | list[Unknown | int]] & SparseABC) | (ndarray[tuple[Any, ...], dtype[Any]] & SparseABC) | ... omitted 12 union elements`

pandas (https://github.com/pandas-dev/pandas)
- pandas/core/methods/describe.py:210:21: error[not-iterable] Object of type `Sized | Unknown` may not be iterable
+ pandas/core/methods/describe.py:210:21: error[not-iterable] Object of type `Unknown | Sized` may not be iterable

sympy (https://github.com/sympy/sympy)
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
- sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic | int | float | complex | Any` is not assignable to `Expr | int | float | complex`
+ sympy/algebras/quaternion.py:132:22: error[invalid-assignment] Object of type `Basic` is not assignable to `Expr | int | float | complex`
- sympy/algebras/tests/test_quaternion.py:423:33: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/codegen/tests/test_matrix_nodes.py:28:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/functions/combinatorial/factorials.py:967:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:967:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/functions/combinatorial/factorials.py:968:29: error[unresolved-attribute] Attribute `is_nonnegative` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:968:47: error[unresolved-attribute] Attribute `is_integer` is not defined on `int`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:969:12: error[unresolved-attribute] Attribute `is_zero` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:972:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:972:13: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/functions/combinatorial/factorials.py:975:12: error[unresolved-attribute] Attribute `is_integer` is not defined on `int`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:976:16: error[unresolved-attribute] Attribute `is_negative` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:978:18: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:984:14: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/functions/combinatorial/factorials.py:986:26: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:986:26: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/functions/combinatorial/factorials.py:986:40: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/functions/combinatorial/factorials.py:986:40: error[unsupported-operator] Operator `+` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/functions/combinatorial/factorials.py:986:53: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/functions/combinatorial/factorials.py:986:53: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/geometry/polygon.py:1501:12: error[unresolved-attribute] Attribute `is_Number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/geometry/polygon.py:1502:20: error[invalid-argument-type] Argument to function `as_int` is incorrect: Expected `SupportsIndex`, found `Basic | int | float | complex | Any`
+ sympy/geometry/polygon.py:1502:20: error[invalid-argument-type] Argument to function `as_int` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/geometry/polygon.py:1503:16: error[unsupported-operator] Operator `<` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[3]`
+ sympy/geometry/polygon.py:1503:16: error[unsupported-operator] Operator `<` is not supported between objects of type `Basic` and `Literal[3]`
- sympy/geometry/polygon.py:1510:40: error[unresolved-attribute] Attribute `is_number` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/matrices/eigen.py:1202:37: error[unresolved-attribute] Object of type `T2'return@call_highest_priority | T1'return@call_highest_priority` has no attribute `pow`
- sympy/matrices/expressions/hadamard.py:82:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Any | Basic | int | float | complex`
+ sympy/matrices/expressions/hadamard.py:82:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Basic`
- sympy/matrices/expressions/kronecker.py:110:16: error[unresolved-attribute] Attribute `is_Identity` is not defined on `Basic`, `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
- sympy/matrices/expressions/kronecker.py:111:33: error[unresolved-attribute] Attribute `rows` is not defined on `Basic`, `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
+ sympy/matrices/expressions/kronecker.py:110:16: error[unresolved-attribute] Object of type `Basic` has no attribute `is_Identity`
+ sympy/matrices/expressions/kronecker.py:111:33: error[unresolved-attribute] Object of type `Basic` has no attribute `rows`
- sympy/matrices/expressions/matadd.py:61:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Unknown | Basic | int | float | complex`
+ sympy/matrices/expressions/matadd.py:61:22: error[invalid-argument-type] Argument to function `validate_matadd_integer` is incorrect: Expected `MatrixExpr`, found `Unknown | Basic`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:13: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:33: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:236:53: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_blockmatrix.py:460:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/expressions/tests/test_derivatives.py:552:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matadd.py:37:12: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase` and `MatrixBase | Expr`
- sympy/matrices/expressions/tests/test_matpow.py:125: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 | Unknown`
- 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 | Unknown`
- sympy/matrices/repmatrix.py:321:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `Self@_eval_is_symmetric`
- sympy/matrices/solvers.py:741:12: error[invalid-return-type] Return type does not match returned value: expected `Tmat@_pinv_solve`, found `T2'return@call_highest_priority | T1'return@call_highest_priority`
- sympy/matrices/tests/test_commonmatrix.py:1250:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_eigen.py:407:20: error[invalid-argument-type] Argument to function `max` is incorrect: Expected `Iterable[Unknown]`, found `MatrixBase | Unknown`
- sympy/matrices/tests/test_immutable.py:106:23: error[unsupported-operator] Operator `+` is not supported between two objects of type `ImmutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:122:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:124:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:142:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2180:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2208:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2909:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2922: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:2938:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:2949:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:3472:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrices.py:3479:12: error[unresolved-attribute] Attribute `rank` is not defined on `MatrixExpr` in union `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_matrices.py:3480:12: error[unresolved-attribute] Attribute `rank` is not defined on `MatrixExpr` in union `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_matrixbase.py:492:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:494:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:545:12: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:824:31: error[unsupported-operator] Operator `+` is not supported between objects of type `MutableDenseMatrix` and `ImmutableDenseNDimArray`
- sympy/matrices/tests/test_matrixbase.py:877:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:879:32: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:901:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:2932:22: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:2960:26: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3611:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3625: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:3641:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_matrixbase.py:3653:14: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_reductions.py:378:21: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_reductions.py:385:12: error[unresolved-attribute] Attribute `rank` is not defined on `MatrixExpr` in union `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_reductions.py:386:12: error[unresolved-attribute] Attribute `rank` is not defined on `MatrixExpr` in union `MatrixBase | MatrixExpr | Unknown`
- sympy/matrices/tests/test_solvers.py:69:13: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/matrices/tests/test_sparse.py:574:12: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableSparseMatrix`
- sympy/matrices/tests/test_sparse.py:578:52: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableSparseMatrix`
- sympy/matrices/tests/test_sparse.py:594: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:3778:31: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/control/tests/test_lti.py:3778:38: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/mechanics/lagrange.py:223:23: error[unsupported-operator] Operator `-` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/lagrange.py:347:17: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:218:28: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:230:29: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/linearize.py:242:29: error[unsupported-operator] Operator `+` is not supported between two objects of type `Unknown | MutableDenseMatrix`
- sympy/physics/mechanics/tests/test_jointsmethod.py:248:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/mechanics/tests/test_jointsmethod.py:250:17: error[unsupported-operator] Operator `-` is not supported between two objects of type `MutableDenseMatrix`
- sympy/physics/optics/gaussopt.py:264:56: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:264:56: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:299:54: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:299:54: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:299:69: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:299:69: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:708:12: error[unsupported-operator] Operator `**` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[2]`
+ sympy/physics/optics/gaussopt.py:708:12: error[unsupported-operator] Operator `**` is not supported between objects of type `Basic` and `Literal[2]`
- sympy/physics/optics/gaussopt.py:757:8: error[unresolved-attribute] Attribute `is_infinite` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/physics/optics/gaussopt.py:757:25: error[unresolved-attribute] Attribute `is_infinite` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/physics/optics/gaussopt.py:758:21: error[unresolved-attribute] Attribute `is_infinite` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/physics/optics/gaussopt.py:760:16: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:760:16: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:760:21: error[unsupported-operator] Operator `+` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:760:21: error[unsupported-operator] Operator `+` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:791:34: error[unsupported-operator] Unary operator `-` is not supported for object of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:791:34: error[unsupported-operator] Unary operator `-` is not supported for object of type `Basic`
- sympy/physics/optics/gaussopt.py:838:30: error[unsupported-operator] Operator `**` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[2]`
+ sympy/physics/optics/gaussopt.py:838:30: error[unsupported-operator] Operator `**` is not supported between objects of type `Basic` and `Literal[2]`
- sympy/physics/optics/gaussopt.py:838:41: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:838:41: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:838:54: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[1]` and `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:838:54: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[1]` and `Basic`
- sympy/physics/optics/gaussopt.py:839:22: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:839:22: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:839:37: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:839:37: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:840:31: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:840:31: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:840:46: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:840:46: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/optics/gaussopt.py:888:9: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/physics/optics/gaussopt.py:888:9: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/physics/quantum/cg.py:84:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Basic`, found `Basic | int | float | complex | Any`
- sympy/physics/quantum/cg.py:259:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Basic`, found `Basic | int | float | complex | Any`
- sympy/physics/quantum/cg.py:348:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Basic`, found `Basic | int | float | complex | Any`
- sympy/physics/quantum/tests/test_represent.py:90:17: error[unsupported-operator] Operator `+` is not supported between objects of type `MatrixBase | Expr` and `MatrixBase`
- sympy/physics/quantum/tests/test_represent.py:92:24: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/physics/quantum/tests/test_represent.py:94:28: error[unsupported-operator] Operator `+` is not supported between two objects of type `MatrixBase | Expr`
- sympy/physics/vector/functions.py:381:21: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `MatrixBase | Unknown`
- sympy/polys/fields.py:101:24: error[unresolved-attribute] Attribute `as_numer_denom` is not defined on `Basic`, `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
+ sympy/polys/fields.py:101:24: error[unresolved-attribute] Object of type `Basic` has no attribute `as_numer_denom`
- sympy/polys/polyoptions.py:472:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:472:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:474:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:474:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:476:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:476:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:478:63: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:478:63: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:480:63: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:480:63: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:482:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:482:61: error[invalid-argument-type] Argument to bound method `poly_ring` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:492:62: error[invalid-argument-type] Argument to bound method `frac_field` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:492:62: error[invalid-argument-type] Argument to bound method `frac_field` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polyoptions.py:494:62: error[invalid-argument-type] Argument to bound method `frac_field` is incorrect: Expected `str | Expr`, found `Any | Basic | int | float | complex`
+ sympy/polys/polyoptions.py:494:62: error[invalid-argument-type] Argument to bound method `frac_field` is incorrect: Expected `str | Expr`, found `Basic`
- sympy/polys/polytools.py:6008:12: error[unresolved-attribute] Attribute `is_algebraic` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6008:31: error[unresolved-attribute] Attribute `is_irrational` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6008:51: error[unresolved-attribute] Attribute `is_algebraic` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6008:70: error[unresolved-attribute] Attribute `is_irrational` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6009:20: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/polys/polytools.py:6009:20: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/polys/polytools.py:6138:12: error[unresolved-attribute] Attribute `is_algebraic` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6138:31: error[unresolved-attribute] Attribute `is_irrational` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6138:51: error[unresolved-attribute] Attribute `is_algebraic` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6138:70: error[unresolved-attribute] Attribute `is_irrational` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/polys/polytools.py:6139:20: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/polys/polytools.py:6139:20: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/series/formal.py:988:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Basic`, found `Basic | int | float | complex | Any`
- sympy/series/fourier.py:147:34: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `Basic`, found `Basic | int | float | complex | Any`
- sympy/series/order.py:154:20: error[unresolved-attribute] Attribute `is_symbol` is not defined on `int`, `float`, `complex` in union `Unknown | Basic | int | float | complex`
- sympy/series/order.py:189:28: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[1]` and `Unknown | Basic | int | float | complex`
+ sympy/series/order.py:189:28: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[1]` and `Unknown | Basic`
- sympy/series/order.py:193:29: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[-1]` and `Unknown | Basic | int | float | complex`
+ sympy/series/order.py:193:29: error[unsupported-operator] Operator `/` is not supported between objects of type `Literal[-1]` and `Unknown | Basic`
- sympy/series/order.py:270:52: error[invalid-argument-type] Argument to bound method `as_independent` is incorrect: Expected `Basic | type[Basic]`, found `Any | Basic | int | float | complex`
- sympy/series/order.py:270:52: error[invalid-argument-type] Argument to bound method `as_independent` is incorrect: Expected `Basic | type[Basic]`, found `Any | Basic | int | float | complex`
- sympy/series/order.py:270:52: error[invalid-argument-type] Argument to bound method `as_independent` is incorrect: Expected `Basic | type[Basic]`, found `Any | Basic | int | float | complex`
- sympy/series/order.py:288:45: error[unsupported-operator] Unary operator `-` is not supported for object of type `Any | Basic | int | float | complex`
+ sympy/series/order.py:288:45: error[unsupported-operator] Unary operator `-` is not supported for object of type `Unknown | Basic`
- sympy/series/order.py:289:48: error[unsupported-operator] Operator `**` is not supported between objects of type `Any | Basic | int | float | complex` and `Basic`
+ sympy/series/order.py:289:48: error[unsupported-operator] Operator `**` is not supported between objects of type `Unknown | Basic` and `Basic`
- sympy/series/order.py:292:49: error[unsupported-operator] Unary operator `-` is not supported for object of type `Any | Basic | int | float | complex`
+ sympy/series/order.py:292:49: error[unsupported-operator] Unary operator `-` is not supported for object of type `Unknown | Basic`
- sympy/series/order.py:298:53: error[unsupported-operator] Unary operator `-` is not supported for object of type `Any | Basic | int | float | complex`
+ sympy/series/order.py:298:53: error[unsupported-operator] Unary operator `-` is not supported for object of type `Unknown | Basic`
- sympy/simplify/cse_main.py:300:23: error[not-iterable] Object of type `Unknown | Sized` may not be iterable
+ sympy/simplify/cse_main.py:300:23: error[not-iterable] Object of type `Sized | Unknown` may not be iterable
- sympy/simplify/cse_main.py:306:16: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `Unknown | Sized`
+ sympy/simplify/cse_main.py:306:16: error[unsupported-operator] Operator `in` is not supported between objects of type `Unknown` and `Sized | Unknown`
- sympy/simplify/hyperexpand.py:1047:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1047:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1048:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1048:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1049:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1049:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/hyperexpand.py:1088:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1088:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1089:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1089:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1090:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1090:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/hyperexpand.py:1176:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1176:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1177:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1177:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1178:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1178:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1179:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1179:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1180:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1180:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/hyperexpand.py:1214:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1214:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1215:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1215:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1216:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1216:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1217:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1217:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1218:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1218:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/hyperexpand.py:1266:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1266:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1267:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1267:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1268:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1268:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1269:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1269:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1270:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1270:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/hyperexpand.py:1314:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1314:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1315:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1315:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1316:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1316:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1317:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1317:19: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Iterable[Unknown]`, found `Basic`
- sympy/simplify/hyperexpand.py:1318:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Any | Basic | int | float | complex`
+ sympy/simplify/hyperexpand.py:1318:21: error[invalid-argument-type] Argument to bound method `pop` is incorrect: Expected `SupportsIndex`, found `Basic`
- sympy/simplify/simplify.py:357:10: error[unsupported-operator] Operator `/` is not supported between two objects of type `Any | Basic | int | float | complex`
+ sympy/simplify/simplify.py:357:10: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/simplify/sqrtdenest.py:431:25: error[unresolved-attribute] Attribute `subs` is not defined on `int`, `float`, `complex` in union `Basic | int | float | complex | Any`
- sympy/solvers/recurr.py:418:9: error[unresolved-attribute] Attribute `subs` is not defined on `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
- sympy/solvers/recurr.py:418:9: error[unresolved-attribute] Attribute `expand` is not defined on `Basic` in union `Any | Basic`
+ sympy/solvers/recurr.py:418:9: error[unresolved-attribute] Object of type `Basic` has no attribute `expand`
- sympy/solvers/recurr.py:422:24: error[unresolved-attribute] Attribute `subs` is not defined on `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
- sympy/solvers/recurr.py:437:24: error[unresolved-attribute] Attribute `subs` is not defined on `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
- sympy/solvers/recurr.py:590:23: error[unresolved-attribute] Attribute `subs` is not defined on `int`, `float`, `complex` in union `Any | Basic | int | float | complex`
- sympy/solvers/tests/test_numeric.py:138:11: error[unsupported-operator] Operator `+` is not supported between two objects of type `MutableDenseMatrix`
- sympy/solvers/tests/test_pde.py:109:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:109:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- sympy/solvers/tests/test_pde.py:130:22: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:130:22: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- sympy/solvers/tests/test_pde.py:138:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:138:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- sympy/solvers/tests/test_pde.py:164:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:164:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- sympy/solvers/tests/test_pde.py:202:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:202:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- sympy/solvers/tests/test_pde.py:216:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(Unknown | str, /) -> Unknown`, found `<class 'Function'>`
+ sympy/solvers/tests/test_pde.py:216:16: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `(str | Unknown, /) -> Unknown`, found `<class 'Function'>`
- 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:725:19: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/solvers/tests/test_solvers.py:725:30: error[unsupported-operator] Operator `-` is not supported between two objects of type `MatrixBase | Expr`
- sympy/stats/symbolic_probability.py:532:55: error[unresolved-attribute] Attribute `expand` is not defined on `Basic` in union `Basic | Unknown`
+ sympy/stats/symbolic_probability.py:532:55: error[unresolved-attribute] Attribute `expand` is not defined on `Basic` in union `Unknown | Basic`
- sympy/stats/symbolic_probability.py:533:55: error[unresolved-attribute] Attribute `expand` is not defined on `Basic` in union `Basic | Unknown`
+ sympy/stats/symbolic_probability.py:533:55: error[unresolved-attribute] Attribute `expand` is not defined on `Basic` in union `Unknown | Basic`
- sympy/stats/tests/test_finite_rv.py:358:31: error[unsupported-operator] Operator `+` is not supported between objects of type `int | Basic | float | complex | Any` and `Literal[1]`
+ sympy/stats/tests/test_finite_rv.py:358:31: error[unsupported-operator] Operator `+` is not supported between objects of type `int | Basic` and `Literal[1]`
- sympy/stats/tests/test_finite_rv.py:362:32: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:362:32: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:363:20: error[unsupported-operator] Operator `>` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/stats/tests/test_finite_rv.py:363:20: error[unsupported-operator] Operator `>` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/stats/tests/test_finite_rv.py:364:46: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:364:46: error[unsupported-operator] Operator `/` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:364:52: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:364:52: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:364:62: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:364:62: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:364:70: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/stats/tests/test_finite_rv.py:364:70: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/stats/tests/test_finite_rv.py:366:20: error[unsupported-operator] Operator `>` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[2]`
+ sympy/stats/tests/test_finite_rv.py:366:20: error[unsupported-operator] Operator `>` is not supported between objects of type `Basic` and `Literal[2]`
- sympy/stats/tests/test_finite_rv.py:366:30: error[unsupported-operator] Operator `<` is not supported between objects of type `Literal[0]` and `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:366:30: error[unsupported-operator] Operator `<` is not supported between objects of type `Literal[0]` and `Basic`
- sympy/stats/tests/test_finite_rv.py:366:34: error[unsupported-operator] Operator `<` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:366:34: error[unsupported-operator] Operator `<` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:366:44: error[unsupported-operator] Operator `<` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:366:44: error[unsupported-operator] Operator `<` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:367:57: error[unsupported-operator] Operator `*` is not supported between objects of type `Literal[2]` and `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:367:57: error[unsupported-operator] Operator `*` is not supported between objects of type `Literal[2]` and `Basic`
- sympy/stats/tests/test_finite_rv.py:367:67: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic | int | float | complex | Any` and `Literal[1]`
+ sympy/stats/tests/test_finite_rv.py:367:67: error[unsupported-operator] Operator `-` is not supported between objects of type `Basic` and `Literal[1]`
- sympy/stats/tests/test_finite_rv.py:367:79: error[unsupported-operator] Operator `*` is not supported between objects of type `Literal[2]` and `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:367:79: error[unsupported-operator] Operator `*` is not supported between objects of type `Literal[2]` and `Basic`
- sympy/stats/tests/test_finite_rv.py:368:33: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:368:33: error[unsupported-operator] Operator `*` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_finite_rv.py:368:38: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic | int | float | complex | Any`
+ sympy/stats/tests/test_finite_rv.py:368:38: error[unsupported-operator] Operator `-` is not supported between two objects of type `Basic`
- sympy/stats/tests/test_f

... (truncated 41 lines) ...

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 16, 2026

Memory usage report

Summary

Project Old New Diff Outcome
prefect 713.43MB 714.74MB +0.18% (1.31MB)
sphinx 274.63MB 275.16MB +0.20% (548.80kB)
trio 121.61MB 121.92MB +0.25% (312.36kB)
flake8 49.61MB 49.77MB +0.33% (166.91kB)

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
semantic_index 189.58MB 190.88MB +0.69% (1.31MB)

sphinx

Name Old New Diff Outcome
semantic_index 69.45MB 69.99MB +0.77% (548.80kB)

trio

Name Old New Diff Outcome
semantic_index 33.39MB 33.70MB +0.91% (312.36kB)

flake8

Name Old New Diff Outcome
semantic_index 15.29MB 15.45MB +1.07% (166.91kB)

@AlexWaygood AlexWaygood added server Related to the LSP server ty Multi-file analysis & type inference labels Feb 16, 2026
@denyszhak
Copy link
Contributor Author

mypy_primer results

Changes were detected when running on open source projects

Don't seem related but maybe I messed up somewhere, will review tomorrow

@carljm
Copy link
Contributor

carljm commented Feb 16, 2026

Thanks for working on this! I have no opinion on the LSP side (that'd be @BurntSushi or @dhruvmanila or @MichaReiser), but in terms of how this data is collected: I suspect it could be done with less repeated work and less added code (and thus less potential for independent bugs / ty disagreeing with itself) by doing it in SemanticIndexBuilder / UseDefMapBuilder, where we already build up use->def links. I think it should be fairly easy to add a compact data structure there that tracks a "used" bit for each Binding and sets it whenever we record a use of a binding. Then we'd just need an API to query that bit from UseDefMap or SemanticIndex.

Did you explore the possibility of such an implementation at all?

@carljm
Copy link
Contributor

carljm commented Feb 16, 2026

Don't seem related but maybe I messed up somewhere, will review tomorrow

We currently have some non-determinism, so it could be that. I just added ecosystem-analyzer tag, the ecosystem analyzer will tell you which projects have flaky results.

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

carljm commented Feb 16, 2026

(Assigning myself here at least on the topic of how we collect the data; maybe someone from LSP team can also assign yourself as reviewer on the LSP-side implementation?)

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 16, 2026

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@denyszhak
Copy link
Contributor Author

Don't seem related but maybe I messed up somewhere, will review tomorrow

We currently have some non-determinism, so it could be that. I just added ecosystem-analyzer tag, the ecosystem analyzer will tell you which projects have flaky results.

@denyszhak denyszhak closed this Feb 16, 2026
@denyszhak denyszhak reopened this Feb 16, 2026
@denyszhak
Copy link
Contributor Author

denyszhak commented Feb 16, 2026

Thanks for working on this! I have no opinion on the LSP side (that'd be @BurntSushi or @dhruvmanila or @MichaReiser), but in terms of how this data is collected: I suspect it could be done with less repeated work and less added code (and thus less potential for independent bugs / ty disagreeing with itself) by doing it in SemanticIndexBuilder / UseDefMapBuilder, where we already build up use->def links. I think it should be fairly easy to add a compact data structure there that tracks a "used" bit for each Binding and sets it whenever we record a use of a binding. Then we'd just need an API to query that bit from UseDefMap or SemanticIndex.

Did you explore the possibility of such an implementation at all?

Repeated/duplicated code in traversal was my main concern before shipping, I though about alternatives but not the exact option you suggesting. I treated the semantic index as something to query rather than looking at what it already computes.
Having said that, I agree with you and I'll look into refactoring to that approach today.

(closed this pr accidentally so I reopened it back)

@sharkdp sharkdp removed their request for review February 16, 2026 10:21
@denyszhak
Copy link
Contributor Author

Add unused-binding dimming in ty via diagnostics (Hint + DiagnosticTag::Unnecessary) so VS Code fades unused locals even without Pylance. VS Code default fading for “unused” is diagnostics-driven, so this PR uses diagnostics, not semantic tokens.

I think we might need to introduce a new Level::Hint (

) and add this as a "hint" level rule. But, I'd wait until @MichaReiser is back as he has the most context on this (cc @BurntSushi). I'd be ok to move ahead with approach (as is in this PR) for now and then we can hook this into the "hint" rule infrastructure later.
Another option would be to only start with adding the DiagnosticTag::Unnecessary and avoid adding the hint level diagnostic for now.

Right, that's what I meant here #23305 (comment) and I can submit a follow up PR with this change if we are ok with leaving as if in the current one

@BurntSushi
Copy link
Member

Add unused-binding dimming in ty via diagnostics (Hint + DiagnosticTag::Unnecessary) so VS Code fades unused locals even without Pylance. VS Code default fading for “unused” is diagnostics-driven, so this PR uses diagnostics, not semantic tokens.

I think we might need to introduce a new Level::Hint (


) and add this as a "hint" level rule. But, I'd wait until @MichaReiser is back as he has the most context on this (cc @BurntSushi). I'd be ok to move ahead with approach (as is in this PR) for now and then we can hook this into the "hint" rule infrastructure later.

Another option would be to only start with adding the DiagnosticTag::Unnecessary and avoid adding the hint level diagnostic for now.

It seems fine to me to do this since it's only bringing our internal representation more in line with what the LSP specification provides: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity

@denyszhak denyszhak force-pushed the feat/unused-binding-diagnostics branch from faee0e6 to af6bd5e Compare February 19, 2026 23:16
@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 19, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@denyszhak denyszhak force-pushed the feat/unused-binding-diagnostics branch from af6bd5e to aba2679 Compare February 19, 2026 23:46
@denyszhak
Copy link
Contributor Author

Add unused-binding dimming in ty via diagnostics (Hint + DiagnosticTag::Unnecessary) so VS Code fades unused locals even without Pylance. VS Code default fading for “unused” is diagnostics-driven, so this PR uses diagnostics, not semantic tokens.

I think we might need to introduce a new Level::Hint (

) and add this as a "hint" level rule. But, I'd wait until @MichaReiser is back as he has the most context on this (cc @BurntSushi). I'd be ok to move ahead with approach (as is in this PR) for now and then we can hook this into the "hint" rule infrastructure later.
Another option would be to only start with adding the DiagnosticTag::Unnecessary and avoid adding the hint level diagnostic for now.

It seems fine to me to do this since it's only bringing our internal representation more in line with what the LSP specification provides: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity

@dhruvmanila I addressed this in aba2679. If you have a moment, could you take a look? I can also split it into a separate PR if you’d prefer.

@denyszhak denyszhak requested a review from carljm February 20, 2026 11:02
carljm
carljm previously requested changes Feb 25, 2026
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

I reviewed only the ty_python_semantic changes (well I did make one observation in ty_server). Looking generally good, some updates needed I think.

Co-authored-by: Carl Meyer <carl@oddbird.net>
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 25, 2026

Merging this PR will not alter performance

✅ 56 untouched benchmarks


Comparing denyszhak:feat/unused-binding-diagnostics (f0d5a77) with main (f14edd8)

Open in CodSpeed

@denyszhak denyszhak force-pushed the feat/unused-binding-diagnostics branch 2 times, most recently from a5c3cb5 to ae41dcb Compare February 25, 2026 14:37
@AlexWaygood AlexWaygood removed their request for review February 25, 2026 14:49
@denyszhak denyszhak force-pushed the feat/unused-binding-diagnostics branch from ae41dcb to 82016f1 Compare February 25, 2026 15:17
@carljm carljm dismissed their stale review February 25, 2026 20:29

Issues noted are addressed.

@carljm carljm requested review from carljm and removed request for carljm February 25, 2026 20:29
@carljm carljm removed their assignment Feb 25, 2026
@carljm
Copy link
Contributor

carljm commented Feb 25, 2026

I'm happy with the semantic side of this. Thanks @denyszhak ! Removing my assignment and my review request. Hoping either @BurntSushi or @dhruvmanila (or @MichaReiser once he's back) can pick this up and make sure the LSP/diagnostics side of it is good.

@BurntSushi
Copy link
Member

I can take a look at this tomorrow. Thanks for the ping @carljm!

@BurntSushi BurntSushi self-assigned this Feb 25, 2026
Copy link
Member

@BurntSushi BurntSushi left a comment

Choose a reason for hiding this comment

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

I think there are a few things in this PR that I'm uncertain about. In particular:

  • I'm less certain now about whether we want to add a new "hint" level. And especially adding that to our configuration schema.
  • Adding these hints as a diagnostic that is more like a side-channel to our existing diagnostics is concerning to me. This means it exists outside of how we normally suppress or configure diagnostics, which leads to a worse UX IMO.

Valid severities are:

* `ignore`: Disable the rule.
* `hint`: Enable the rule and create a hint diagnostic.
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I am having second thoughts on this. pyright does not have a "hint" level setting: https://code.visualstudio.com/docs/python/settings-reference

And note that even though we have an "info" level setting, it does not appear in the docs here.

I guess maybe we should wait for @MichaReiser to come back to review this bit.

Can you say why you can't use the "info" level here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There’s a UX difference between Hint and Info, so this is mostly about how noisy we want this to be.

In my local VSCode setup:

Hint + Unnecessary shows dimming only
image

Info + Unnecessary shows dimming and underline (more visually invasive)
image

So I used pyright as the reference and kept Hint for unused-code dimming (pyright also uses Hint for unreachable or deprecated tagged diagnostics):
https://github.com/microsoft/pyright/blob/main/packages/pyright-internal/src/languageServerBase.ts#L1547

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, but the pyright docs don't note "hint" as a diagnostic level. So it might be using "hint" without actually publishing it as part of their configuration schema.

I think we'll want to wait for @MichaReiser to review this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@BurntSushi Right. the initial implementation was intentionally side-wired for UX only, not integrated into the normal lint/diagnostic pipeline.

Thanks for the feedback!

I’ll wait for your and @MichaReiser’s guidance on the preferred direction, and in the meantime I’ll address your other comments that are independent of that decision.

Copy link
Member

Choose a reason for hiding this comment

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

This is a cool feature! Thanks for working on it.

I think the right design here heavily depends on our goal:

  1. Is this an IDE-only feature that we don't want to expose on the CLI, then using Diagnostics feels wrong. Instead, ty_server should append the LSP-diagnostics manually where necessary
  2. Is this a re-implementation of Ruff's F821 lint rule that can also be enabled on the CLI like any other rule? If so, we should add a new rule code and decide on a default severity (that the server might decide to override).

Reading through the PR, my impression is that we tried to accomplish one but using some of the infrastructure of 2.

To keep things simple, I'm leaning towards aiming for 1. but we should implement it without using ruff_db::Diagnostic. Instead, we should inject the additional LSP diagnostics in publish_diagnostic and the workspace diagnostic handlers. We can always pull this code out and create a separate lint rule if we decide to go for 2. in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for review! Sounds good to me, I will get this updated soon

Copy link
Contributor

@DetachHead DetachHead Mar 9, 2026

Choose a reason for hiding this comment

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

Tbh I don't think it's a good idea to follow pyright's example here. It doesn't have a hint category but that makes it much less flexible for users who may want to turn them off per rule, or have hints for rules where a diagnostic tag (unreachable, unused or deprecated) doesn't apply.

Its also worth noting that pretty much every editor other than vscode renders these hints in a much less subtle way (basically the same as information), for example neovim. So users will want more configurability over these hints than you may think

Adding ahint diagnostic level was the solution I went with to address the issues many users had with pyright's diagnostic tags and i'd recommend the same thing for ty

(Kinda unrelated but maybe worth mentioning that astral-sh/ty#1074 is another use case for hints)

@@ -24,6 +25,8 @@ use crate::system::{AnySystemPath, file_to_url};
use crate::{DIAGNOSTIC_NAME, Db, DiagnosticMode};
use crate::{PositionEncoding, Session};

const UNUSED_BINDING_CODE: &str = "unused-binding";
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, this seems concerning to me. Why is this defined outside of where we typically define lints in ty? And in particular, how would one disable this lint via configuration?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same rationale as in my comment below, I initially treated this as editor UX-only dimming, so I kept it outside the normal lint flow.

I agree with you it's not ideal to keep it hanging here, I will move this.

@@ -325,7 +328,10 @@ pub(super) fn compute_diagnostics(
return None;
};

let diagnostics = db.check_file(file);
let mut diagnostics = db.check_file(file);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe a dumb question, but why aren't these diagnostics returned as part of db.check_file? Is it because we don't want to show them on the CLI? This feels non-ideal to me because it creates a subtle inconsistency with how diagnostics are generated between the CLI and LSP.

Copy link
Contributor Author

@denyszhak denyszhak Feb 26, 2026

Choose a reason for hiding this comment

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

That was my original intent. I treated this as an editor UX signal (dimming) rather than a normal lint category, so I initially kept it outside the lint pipeline and CLI path.

I agree centralized generation through the lint pipeline is better here. The open question is presentation. Should CLI display this rule, or should we filter it similarly to Pyright’s unused-code UX diagnostics? My concern with CLI is that It can be a low-signal UX noise that can drown actionable type errors/warnings.

Copy link
Contributor

Choose a reason for hiding this comment

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

Emitting a diagnostic seems very useful, and could also be used in astral-sh/ty#2829.

@MichaReiser MichaReiser changed the title ty: report unused bindings as unnecessary hint diagnostics [ty] report unused bindings as unnecessary hint diagnostics Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LSP not showing unused variable (in VSCode)

8 participants