ruff/crates
Dhruv Manilawala cb2e277482
[ty] Understand legacy and PEP 695 ParamSpec (#21139)
## Summary

This PR adds support for understanding the legacy definition and PEP 695
definition for `ParamSpec`.

This is still very initial and doesn't really implement any of the
semantics.

Part of https://github.com/astral-sh/ty/issues/157

## Test Plan

Add mdtest cases.

## Ecosystem analysis

Most of the diagnostics in `starlette` are due to the fact that ty now
understands `ParamSpec` is not a `Todo` type, so the assignability check
fails. The code looks something like:

```py
class _MiddlewareFactory(Protocol[P]):
    def __call__(self, app: ASGIApp, /, *args: P.args, **kwargs: P.kwargs) -> ASGIApp: ...  # pragma: no cover

class Middleware:
    def __init__(
        self,
        cls: _MiddlewareFactory[P],
        *args: P.args,
        **kwargs: P.kwargs,
    ) -> None:
        self.cls = cls
        self.args = args
        self.kwargs = kwargs

# ty complains that `ServerErrorMiddleware` is not assignable to `_MiddlewareFactory[P]`
Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)
```

There are multiple diagnostics where there's an attribute access on the
`Wrapped` object of `functools` which Pyright also raises:
```py
from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        return f(*args, **kwds)

	# Pyright: Cannot access attribute "__signature__" for class "_Wrapped[..., Unknown, ..., Unknown]"
      Attribute "__signature__" is unknown [reportAttributeAccessIssue]
	# ty: Object of type `_Wrapped[Unknown, Unknown, Unknown, Unknown]` has no attribute `__signature__` [unresolved-attribute]
    wrapper.__signature__
    return wrapper
```

There are additional diagnostics that is due to the assignability checks
failing because ty now infers the `ParamSpec` instead of using the
`Todo` type which would always succeed. This results in a few
`no-matching-overload` diagnostics because the assignability checks
fail.

There are a few diagnostics related to
https://github.com/astral-sh/ty/issues/491 where there's a variable
which is either a bound method or a variable that's annotated with
`Callable` that doesn't contain the instance as the first parameter.

Another set of (valid) diagnostics are where the code hasn't provided
all the type variables. ty is now raising diagnostics for these because
we include `ParamSpec` type variable in the signature. For example,
`staticmethod[Any]` which contains two type variables.
2025-11-06 11:14:40 -05:00
..
ruff Update Rust toolchain to 1.91 (#21179) 2025-11-01 01:50:58 +00:00
ruff_annotate_snippets
ruff_benchmark [ty] Update expected diagnostic count in benchmarks (#21269) 2025-11-04 03:18:12 +00:00
ruff_cache
ruff_db [ty] Smaller refactors to server API in prep for notebook support (#21095) 2025-10-31 20:00:04 +00:00
ruff_dev Update Rust toolchain to 1.91 (#21179) 2025-11-01 01:50:58 +00:00
ruff_diagnostics
ruff_formatter [ty] Use "cannot" consistently over "can not" (#21255) 2025-11-03 10:38:20 -05:00
ruff_graph [ruff]: Make ruff analyze graph work with jupyter notebooks (#21161) 2025-10-31 21:47:01 +00:00
ruff_index
ruff_linter [syntax-error]: no binding for nonlocal PLE0117 as a semantic syntax error (#21032) 2025-11-05 19:13:28 +00:00
ruff_macros Document when a rule was added (#21035) 2025-10-23 14:48:41 -04:00
ruff_memory_usage
ruff_notebook
ruff_options_metadata
ruff_python_ast [refurb] Preserve argument ordering in autofix (FURB103) (#20790) 2025-10-31 11:16:09 -04:00
ruff_python_ast_integration_tests
ruff_python_codegen Configurable "unparse mode" for ruff_python_codegen::Generator (#21041) 2025-10-24 15:44:48 +00:00
ruff_python_formatter Avoid extra parentheses for long match patterns with as captures (#21176) 2025-11-03 17:06:52 -05:00
ruff_python_importer
ruff_python_index
ruff_python_literal
ruff_python_parser [syntax-error]: no binding for nonlocal PLE0117 as a semantic syntax error (#21032) 2025-11-05 19:13:28 +00:00
ruff_python_semantic [pyflakes] Revert to stable behavior if imports for module lie in alternate branches for F401 (#20878) 2025-10-27 10:23:36 -05:00
ruff_python_stdlib
ruff_python_trivia
ruff_python_trivia_integration_tests
ruff_server Fix missing diagnostics for notebooks (#21156) 2025-10-31 01:16:43 +00:00
ruff_source_file
ruff_text_size [ruff] Update schemars to v1 (#20942) 2025-10-20 08:59:52 +02:00
ruff_wasm Bump v0.14.3 (#21152) 2025-10-30 17:06:29 -07:00
ruff_workspace Improve extend docs (#21135) 2025-10-31 15:10:14 +00:00
ty [ty] Understand legacy and PEP 695 ParamSpec (#21139) 2025-11-06 11:14:40 -05:00
ty_combine
ty_completion_eval [ty] Favour imported symbols over builtin symbols (#21285) 2025-11-06 06:46:08 -05:00
ty_ide [ty] Understand legacy and PEP 695 ParamSpec (#21139) 2025-11-06 11:14:40 -05:00
ty_project [ty] Discover site-packages from the environment that ty is installed in (#21286) 2025-11-06 09:27:49 -05:00
ty_python_semantic [ty] Understand legacy and PEP 695 ParamSpec (#21139) 2025-11-06 11:14:40 -05:00
ty_server [ty] Understand legacy and PEP 695 ParamSpec (#21139) 2025-11-06 11:14:40 -05:00
ty_static
ty_test [ty] Fix bug where ty would think all types had an __mro__ attribute (#20995) 2025-10-27 11:19:12 +00:00
ty_vendored [ty] Constraining a typevar with itself (possibly via union or intersection) (#21273) 2025-11-05 12:31:53 -05:00
ty_wasm