mirror of https://github.com/astral-sh/ruff
3 Commits
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
ac882f7e63
|
[ty] Handle various invalid explicit specializations for `ParamSpec` (#21821)
## Summary fixes: https://github.com/astral-sh/ty/issues/1788 ## Test Plan Add new mdtests. --------- Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> |
|
|
|
b623189560
|
[ty] Complete support for `ParamSpec` (#21445)
## Summary
Closes: https://github.com/astral-sh/ty/issues/157
This PR adds support for the following capabilities involving a
`ParamSpec` type variable:
- Representing `P.args` and `P.kwargs` in the type system
- Matching against a callable containing `P` to create a type mapping
- Specializing `P` against the stored parameters
The value of a `ParamSpec` type variable is being represented using
`CallableType` with a `CallableTypeKind::ParamSpecValue` variant. This
`CallableTypeKind` is expanded from the existing `is_function_like`
boolean flag. An `enum` is used as these variants are mutually
exclusive.
For context, an initial iteration made an attempt to expand the
`Specialization` to use `TypeOrParameters` enum that represents that a
type variable can specialize into either a `Type` or `Parameters` but
that increased the complexity of the code as all downstream usages would
need to handle both the variants appropriately. Additionally, we'd have
also need to establish an invariant that a regular type variable always
maps to a `Type` while a paramspec type variable always maps to a
`Parameters`.
I've intentionally left out checking and raising diagnostics when the
`ParamSpec` type variable and it's components are not being used
correctly to avoid scope increase and it can easily be done as a
follow-up. This would also include the scoping rules which I don't think
a regular type variable implements either.
## Test Plan
Add new mdtest cases and update existing test cases.
Ran this branch on pyx, no new diagnostics.
### Ecosystem analysis
There's a case where in an annotated assignment like:
```py
type CustomType[P] = Callable[...]
def value[**P](...): ...
def another[**P](...):
target: CustomType[P] = value
```
The type of `value` is a callable and it has a paramspec that's bound to
`value`, `CustomType` is a type alias that's a callable and `P` that's
used in it's specialization is bound to `another`. Now, ty infers the
type of `target` same as `value` and does not use the declared type
`CustomType[P]`. [This is the
assignment](
|
|
|
|
8795d9f0cb
|
[ty] Split `ParamSpec` mdtests to separate legacy and PEP 695 tests (#21687)
## Summary This is another small refactor for https://github.com/astral-sh/ruff/pull/21445 that splits the single `paramspec.md` into `generics/legacy/paramspec.md` and `generics/pep695/paramspec.md`. ## Test Plan Make sure that all mdtests pass. |