mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
Add support for PEP 696 syntax (#11120)
This commit is contained in:
parent
45725d3275
commit
cd3e319538
49 changed files with 4338 additions and 669 deletions
|
@ -1568,8 +1568,8 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
// Step 1: Binding
|
||||
match type_param {
|
||||
ast::TypeParam::TypeVar(ast::TypeParamTypeVar { name, range, .. })
|
||||
| ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { name, range })
|
||||
| ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { name, range }) => {
|
||||
| ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { name, range, .. })
|
||||
| ast::TypeParam::ParamSpec(ast::TypeParamParamSpec { name, range, .. }) => {
|
||||
self.add_binding(
|
||||
name.as_str(),
|
||||
*range,
|
||||
|
@ -1579,13 +1579,46 @@ impl<'a> Visitor<'a> for Checker<'a> {
|
|||
}
|
||||
}
|
||||
// Step 2: Traversal
|
||||
if let ast::TypeParam::TypeVar(ast::TypeParamTypeVar {
|
||||
bound: Some(bound), ..
|
||||
}) = type_param
|
||||
{
|
||||
self.visit
|
||||
.type_param_definitions
|
||||
.push((bound, self.semantic.snapshot()));
|
||||
match type_param {
|
||||
ast::TypeParam::TypeVar(ast::TypeParamTypeVar {
|
||||
bound,
|
||||
default,
|
||||
name: _,
|
||||
range: _,
|
||||
}) => {
|
||||
if let Some(expr) = bound {
|
||||
self.visit
|
||||
.type_param_definitions
|
||||
.push((expr, self.semantic.snapshot()));
|
||||
}
|
||||
if let Some(expr) = default {
|
||||
self.visit
|
||||
.type_param_definitions
|
||||
.push((expr, self.semantic.snapshot()));
|
||||
}
|
||||
}
|
||||
ast::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple {
|
||||
default,
|
||||
name: _,
|
||||
range: _,
|
||||
}) => {
|
||||
if let Some(expr) = default {
|
||||
self.visit
|
||||
.type_param_definitions
|
||||
.push((expr, self.semantic.snapshot()));
|
||||
}
|
||||
}
|
||||
ast::TypeParam::ParamSpec(ast::TypeParamParamSpec {
|
||||
default,
|
||||
name: _,
|
||||
range: _,
|
||||
}) => {
|
||||
if let Some(expr) = default {
|
||||
self.visit
|
||||
.type_param_definitions
|
||||
.push((expr, self.semantic.snapshot()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ F821_17.py:77:15: F821 Undefined name `DoesNotExist1`
|
|||
77 | class Foo[T: (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
78 |
|
||||
79 | # Type parameters in nested classes
|
||||
79 | # Same in defaults
|
||||
|
|
||||
|
||||
F821_17.py:77:30: F821 Undefined name `DoesNotExist2`
|
||||
|
@ -144,35 +144,117 @@ F821_17.py:77:30: F821 Undefined name `DoesNotExist2`
|
|||
77 | class Foo[T: (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
78 |
|
||||
79 | # Type parameters in nested classes
|
||||
79 | # Same in defaults
|
||||
|
|
||||
|
||||
F821_17.py:92:52: F821 Undefined name `t`
|
||||
F821_17.py:81:14: F821 Undefined name `DoesNotExist`
|
||||
|
|
||||
90 | return x
|
||||
91 |
|
||||
92 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
| ^ F821
|
||||
93 | t # F821: Undefined name `t`
|
||||
94 | return x
|
||||
79 | # Same in defaults
|
||||
80 |
|
||||
81 | type Foo[T = DoesNotExist] = T # F821: Undefined name `DoesNotExist`
|
||||
| ^^^^^^^^^^^^ F821
|
||||
82 | def foo[T = DoesNotExist](t: T) -> T: return t # F821: Undefined name `DoesNotExist`
|
||||
83 | class Foo[T = DoesNotExist](list[T]): ... # F821: Undefined name `DoesNotExist`
|
||||
|
|
||||
|
||||
F821_17.py:92:58: F821 Undefined name `t`
|
||||
F821_17.py:82:13: F821 Undefined name `DoesNotExist`
|
||||
|
|
||||
90 | return x
|
||||
91 |
|
||||
92 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
| ^ F821
|
||||
93 | t # F821: Undefined name `t`
|
||||
94 | return x
|
||||
81 | type Foo[T = DoesNotExist] = T # F821: Undefined name `DoesNotExist`
|
||||
82 | def foo[T = DoesNotExist](t: T) -> T: return t # F821: Undefined name `DoesNotExist`
|
||||
| ^^^^^^^^^^^^ F821
|
||||
83 | class Foo[T = DoesNotExist](list[T]): ... # F821: Undefined name `DoesNotExist`
|
||||
|
|
||||
|
||||
F821_17.py:93:17: F821 Undefined name `t`
|
||||
F821_17.py:83:15: F821 Undefined name `DoesNotExist`
|
||||
|
|
||||
92 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
93 | t # F821: Undefined name `t`
|
||||
| ^ F821
|
||||
94 | return x
|
||||
81 | type Foo[T = DoesNotExist] = T # F821: Undefined name `DoesNotExist`
|
||||
82 | def foo[T = DoesNotExist](t: T) -> T: return t # F821: Undefined name `DoesNotExist`
|
||||
83 | class Foo[T = DoesNotExist](list[T]): ... # F821: Undefined name `DoesNotExist`
|
||||
| ^^^^^^^^^^^^ F821
|
||||
84 |
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
|
|
||||
|
||||
F821_17.py:85:15: F821 Undefined name `DoesNotExist1`
|
||||
|
|
||||
83 | class Foo[T = DoesNotExist](list[T]): ... # F821: Undefined name `DoesNotExist`
|
||||
84 |
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
|
|
||||
|
||||
F821_17.py:85:30: F821 Undefined name `DoesNotExist2`
|
||||
|
|
||||
83 | class Foo[T = DoesNotExist](list[T]): ... # F821: Undefined name `DoesNotExist`
|
||||
84 |
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
|
|
||||
|
||||
F821_17.py:86:14: F821 Undefined name `DoesNotExist1`
|
||||
|
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
|
|
||||
|
||||
F821_17.py:86:29: F821 Undefined name `DoesNotExist2`
|
||||
|
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
|
|
||||
|
||||
F821_17.py:87:16: F821 Undefined name `DoesNotExist1`
|
||||
|
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
88 |
|
||||
89 | # Type parameters in nested classes
|
||||
|
|
||||
|
||||
F821_17.py:87:31: F821 Undefined name `DoesNotExist2`
|
||||
|
|
||||
85 | type Foo[T = (DoesNotExist1, DoesNotExist2)] = T # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
86 | def foo[T = (DoesNotExist1, DoesNotExist2)](t: T) -> T: return t # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
87 | class Foo[T = (DoesNotExist1, DoesNotExist2)](list[T]): ... # F821: Undefined name `DoesNotExist1`, Undefined name `DoesNotExist2`
|
||||
| ^^^^^^^^^^^^^ F821
|
||||
88 |
|
||||
89 | # Type parameters in nested classes
|
||||
|
|
||||
|
||||
F821_17.py:102:52: F821 Undefined name `t`
|
||||
|
|
||||
100 | return x
|
||||
101 |
|
||||
102 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
| ^ F821
|
||||
103 | t # F821: Undefined name `t`
|
||||
104 | return x
|
||||
|
|
||||
|
||||
F821_17.py:102:58: F821 Undefined name `t`
|
||||
|
|
||||
100 | return x
|
||||
101 |
|
||||
102 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
| ^ F821
|
||||
103 | t # F821: Undefined name `t`
|
||||
104 | return x
|
||||
|
|
||||
|
||||
F821_17.py:103:17: F821 Undefined name `t`
|
||||
|
|
||||
102 | def cannot_access_parent_variable(self, x: t) -> t: # F821: Undefined name `T`
|
||||
103 | t # F821: Undefined name `t`
|
||||
| ^ F821
|
||||
104 | return x
|
||||
|
|
||||
|
|
|
@ -132,6 +132,9 @@ pub(crate) fn non_pep695_type_alias(checker: &mut Checker, stmt: &StmtAnnAssign)
|
|||
}
|
||||
None => None,
|
||||
},
|
||||
// We don't handle defaults here yet. Should perhaps be a different rule since
|
||||
// defaults are only valid in 3.13+.
|
||||
default: None,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue