Skip to content

Commit

Permalink
Visit TypeVar and NewType name arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed May 24, 2023
1 parent 3644695 commit 9765ade
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 31 deletions.
85 changes: 54 additions & 31 deletions crates/ruff/src/checkers/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4043,32 +4043,42 @@ where
match callable {
Some(Callable::Bool) => {
self.visit_expr(func);
if !args.is_empty() {
self.visit_boolean_test(&args[0]);
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_boolean_test(arg);
}
for expr in args.iter().skip(1) {
self.visit_expr(expr);
for arg in args {
self.visit_expr(arg);
}
}
Some(Callable::Cast) => {
self.visit_expr(func);
if !args.is_empty() {
self.visit_type_definition(&args[0]);
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_type_definition(arg);
}
for expr in args.iter().skip(1) {
self.visit_expr(expr);
for arg in args {
self.visit_expr(arg);
}
}
Some(Callable::NewType) => {
self.visit_expr(func);
for expr in args.iter().skip(1) {
self.visit_type_definition(expr);
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_non_type_definition(arg);
}
for arg in args {
self.visit_type_definition(arg);
}
}
Some(Callable::TypeVar) => {
self.visit_expr(func);
for expr in args.iter().skip(1) {
self.visit_type_definition(expr);
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_non_type_definition(arg);
}
for arg in args {
self.visit_type_definition(arg);
}
for keyword in keywords {
let Keyword {
Expand All @@ -4089,24 +4099,30 @@ where
self.visit_expr(func);

// Ex) NamedTuple("a", [("a", int)])
if args.len() > 1 {
match &args[1] {
Expr::List(ast::ExprList { elts, .. })
| Expr::Tuple(ast::ExprTuple { elts, .. }) => {
for elt in elts {
match elt {
Expr::List(ast::ExprList { elts, .. })
| Expr::Tuple(ast::ExprTuple { elts, .. }) => {
if elts.len() == 2 {
self.visit_non_type_definition(&elts[0]);
self.visit_type_definition(&elts[1]);
}
}
_ => {}
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_non_type_definition(arg);
}
for arg in args {
if let Expr::List(ast::ExprList { elts, .. })
| Expr::Tuple(ast::ExprTuple { elts, .. }) = arg
{
for elt in elts {
match elt {
Expr::List(ast::ExprList { elts, .. })
| Expr::Tuple(ast::ExprTuple { elts, .. })
if elts.len() == 2 =>
{
self.visit_non_type_definition(&elts[0]);
self.visit_type_definition(&elts[1]);
}
_ => {
self.visit_non_type_definition(elt);
}
}
}
_ => {}
} else {
self.visit_non_type_definition(arg);
}
}

Expand All @@ -4120,19 +4136,25 @@ where
self.visit_expr(func);

// Ex) TypedDict("a", {"a": int})
if args.len() > 1 {
let mut args = args.iter();
if let Some(arg) = args.next() {
self.visit_non_type_definition(arg);
}
for arg in args {
if let Expr::Dict(ast::ExprDict {
keys,
values,
range: _,
}) = &args[1]
}) = arg
{
for key in keys.iter().flatten() {
self.visit_non_type_definition(key);
}
for value in values {
self.visit_type_definition(value);
}
} else {
self.visit_non_type_definition(arg);
}
}

Expand All @@ -4145,11 +4167,12 @@ where
Some(Callable::MypyExtension) => {
self.visit_expr(func);

if let Some(arg) = args.first() {
let mut args = args.iter();
if let Some(arg) = args.next() {
// Ex) DefaultNamedArg(bool | None, name="some_prop_name")
self.visit_type_definition(arg);

for arg in args.iter().skip(1) {
for arg in args {
self.visit_non_type_definition(arg);
}
for keyword in keywords {
Expand Down
10 changes: 10 additions & 0 deletions crates/ruff/src/rules/pyflakes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3689,6 +3689,16 @@ mod tests {
"#,
&[],
);
flakes(
r#"
from typing import NewType
def f():
name = "x"
NewType(name, int)
"#,
&[],
);
}

#[test]
Expand Down

0 comments on commit 9765ade

Please sign in to comment.