mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[ty] Reduce false positives for ParamSpec
s and TypeVarTuple
s (#20239)
This commit is contained in:
parent
08c1d3660c
commit
888a22e849
2 changed files with 44 additions and 29 deletions
|
@ -28,6 +28,23 @@ def i(callback: Callable[Concatenate[int, P], R_co], *args: P.args, **kwargs: P.
|
||||||
class Foo:
|
class Foo:
|
||||||
def method(self, x: Self):
|
def method(self, x: Self):
|
||||||
reveal_type(x) # revealed: Self@method
|
reveal_type(x) # revealed: Self@method
|
||||||
|
|
||||||
|
def ex2(msg: str):
|
||||||
|
def wrapper(fn: Callable[P, R_co]) -> Callable[P, R_co]:
|
||||||
|
def wrapped(*args: P.args, **kwargs: P.kwargs) -> R_co:
|
||||||
|
print(msg)
|
||||||
|
return fn(*args, **kwargs)
|
||||||
|
return wrapped
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def ex3(msg: str):
|
||||||
|
P = ParamSpec("P")
|
||||||
|
def wrapper(fn: Callable[P, R_co]) -> Callable[P, R_co]:
|
||||||
|
def wrapped(*args: P.args, **kwargs: P.kwargs) -> R_co:
|
||||||
|
print(msg)
|
||||||
|
return fn(*args, **kwargs)
|
||||||
|
return wrapped
|
||||||
|
return wrapper
|
||||||
```
|
```
|
||||||
|
|
||||||
## Type expressions
|
## Type expressions
|
||||||
|
|
|
@ -125,6 +125,7 @@ use crate::types::typed_dict::{
|
||||||
validate_typed_dict_key_assignment,
|
validate_typed_dict_key_assignment,
|
||||||
};
|
};
|
||||||
use crate::types::unpacker::{UnpackResult, Unpacker};
|
use crate::types::unpacker::{UnpackResult, Unpacker};
|
||||||
|
use crate::types::visitor::any_over_type;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
CallDunderError, CallableType, ClassLiteral, ClassType, DataclassParams, DynamicType,
|
CallDunderError, CallableType, ClassLiteral, ClassType, DataclassParams, DynamicType,
|
||||||
IntersectionBuilder, IntersectionType, KnownClass, KnownInstanceType, LintDiagnosticGuard,
|
IntersectionBuilder, IntersectionType, KnownClass, KnownInstanceType, LintDiagnosticGuard,
|
||||||
|
@ -9271,26 +9272,27 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||||
|
|
||||||
let typevars: Result<FxOrderSet<_>, GenericContextError> = typevars
|
let typevars: Result<FxOrderSet<_>, GenericContextError> = typevars
|
||||||
.iter()
|
.iter()
|
||||||
.map(|typevar| match typevar {
|
.map(|typevar| {
|
||||||
Type::KnownInstance(KnownInstanceType::TypeVar(typevar)) => bind_typevar(
|
if let Type::KnownInstance(KnownInstanceType::TypeVar(typevar)) = typevar {
|
||||||
self.db(),
|
bind_typevar(
|
||||||
self.module(),
|
self.db(),
|
||||||
self.index,
|
self.module(),
|
||||||
self.scope().file_scope_id(self.db()),
|
self.index,
|
||||||
self.typevar_binding_context,
|
self.scope().file_scope_id(self.db()),
|
||||||
*typevar,
|
self.typevar_binding_context,
|
||||||
)
|
*typevar,
|
||||||
.ok_or(GenericContextError::InvalidArgument),
|
)
|
||||||
Type::Dynamic(DynamicType::TodoUnpack) => Err(GenericContextError::NotYetSupported),
|
.ok_or(GenericContextError::InvalidArgument)
|
||||||
Type::NominalInstance(nominal)
|
} else if any_over_type(self.db(), *typevar, &|ty| match ty {
|
||||||
if matches!(
|
Type::Dynamic(DynamicType::TodoUnpack) => true,
|
||||||
|
Type::NominalInstance(nominal) => matches!(
|
||||||
nominal.class(self.db()).known(self.db()),
|
nominal.class(self.db()).known(self.db()),
|
||||||
Some(KnownClass::TypeVarTuple | KnownClass::ParamSpec)
|
Some(KnownClass::TypeVarTuple | KnownClass::ParamSpec)
|
||||||
) =>
|
),
|
||||||
{
|
_ => false,
|
||||||
|
}) {
|
||||||
Err(GenericContextError::NotYetSupported)
|
Err(GenericContextError::NotYetSupported)
|
||||||
}
|
} else {
|
||||||
_ => {
|
|
||||||
if let Some(builder) =
|
if let Some(builder) =
|
||||||
self.context.report_lint(&INVALID_ARGUMENT_TYPE, value_node)
|
self.context.report_lint(&INVALID_ARGUMENT_TYPE, value_node)
|
||||||
{
|
{
|
||||||
|
@ -11265,18 +11267,14 @@ impl<'db> TypeInferenceBuilder<'db, '_> {
|
||||||
// `Callable[]`.
|
// `Callable[]`.
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match self.infer_name_load(name) {
|
if any_over_type(self.db(), self.infer_name_load(name), &|ty| match ty {
|
||||||
Type::Dynamic(DynamicType::TodoPEP695ParamSpec) => {
|
Type::Dynamic(DynamicType::TodoPEP695ParamSpec) => true,
|
||||||
return Some(Parameters::todo());
|
Type::NominalInstance(nominal) => nominal
|
||||||
}
|
.class(self.db())
|
||||||
Type::NominalInstance(nominal)
|
.is_known(self.db(), KnownClass::ParamSpec),
|
||||||
if nominal
|
_ => false,
|
||||||
.class(self.db())
|
}) {
|
||||||
.is_known(self.db(), KnownClass::ParamSpec) =>
|
return Some(Parameters::todo());
|
||||||
{
|
|
||||||
return Some(Parameters::todo());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue