mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-19 03:48:29 +00:00
[ty] Support attribute-expression TYPE_CHECKING conditionals (#21449)
This commit is contained in:
parent
e9a5337136
commit
5f501374c4
2 changed files with 61 additions and 6 deletions
|
|
@ -132,8 +132,29 @@ def f(x: int | str):
|
||||||
Inside an `if TYPE_CHECKING` block, we allow "stub" style function definitions with empty bodies,
|
Inside an `if TYPE_CHECKING` block, we allow "stub" style function definitions with empty bodies,
|
||||||
since these functions will never actually be called.
|
since these functions will never actually be called.
|
||||||
|
|
||||||
|
`compat/__init__.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
```
|
||||||
|
|
||||||
|
`compat/sub/__init__.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
```
|
||||||
|
|
||||||
|
`compat/sub/sub.py`:
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
```
|
||||||
|
|
||||||
|
`main.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
import typing
|
||||||
|
import typing as t
|
||||||
|
import compat.sub.sub
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
def f() -> int: ...
|
def f() -> int: ...
|
||||||
|
|
@ -199,6 +220,24 @@ if get_bool():
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
if not TYPE_CHECKING:
|
if not TYPE_CHECKING:
|
||||||
def n() -> str: ...
|
def n() -> str: ...
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
def o() -> str: ...
|
||||||
|
|
||||||
|
if not typing.TYPE_CHECKING:
|
||||||
|
def p() -> str: ... # error: [invalid-return-type]
|
||||||
|
|
||||||
|
if compat.sub.sub.TYPE_CHECKING:
|
||||||
|
def q() -> str: ...
|
||||||
|
|
||||||
|
if not compat.sub.sub.TYPE_CHECKING:
|
||||||
|
def r() -> str: ... # error: [invalid-return-type]
|
||||||
|
|
||||||
|
if t.TYPE_CHECKING:
|
||||||
|
def s() -> str: ...
|
||||||
|
|
||||||
|
if not t.TYPE_CHECKING:
|
||||||
|
def t() -> str: ... # error: [invalid-return-type]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conditional return type
|
## Conditional return type
|
||||||
|
|
|
||||||
|
|
@ -3131,15 +3131,31 @@ impl ExpressionsScopeMapBuilder {
|
||||||
|
|
||||||
/// Returns if the expression is a `TYPE_CHECKING` expression.
|
/// Returns if the expression is a `TYPE_CHECKING` expression.
|
||||||
fn is_if_type_checking(expr: &ast::Expr) -> bool {
|
fn is_if_type_checking(expr: &ast::Expr) -> bool {
|
||||||
matches!(expr, ast::Expr::Name(ast::ExprName { id, .. }) if id == "TYPE_CHECKING")
|
fn is_dotted_name(expr: &ast::Expr) -> bool {
|
||||||
|
match expr {
|
||||||
|
ast::Expr::Name(_) => true,
|
||||||
|
ast::Expr::Attribute(ast::ExprAttribute { value, .. }) => is_dotted_name(value),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match expr {
|
||||||
|
ast::Expr::Name(ast::ExprName { id, .. }) => id == "TYPE_CHECKING",
|
||||||
|
ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) => {
|
||||||
|
attr == "TYPE_CHECKING" && is_dotted_name(value)
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns if the expression is a `not TYPE_CHECKING` expression.
|
/// Returns if the expression is a `not TYPE_CHECKING` expression.
|
||||||
fn is_if_not_type_checking(expr: &ast::Expr) -> bool {
|
fn is_if_not_type_checking(expr: &ast::Expr) -> bool {
|
||||||
matches!(expr, ast::Expr::UnaryOp(ast::ExprUnaryOp { op, operand, .. }) if *op == ruff_python_ast::UnaryOp::Not
|
matches!(
|
||||||
&& matches!(
|
expr,
|
||||||
&**operand,
|
ast::Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
ast::Expr::Name(ast::ExprName { id, .. }) if id == "TYPE_CHECKING"
|
op: ast::UnaryOp::Not,
|
||||||
)
|
operand,
|
||||||
|
..
|
||||||
|
}) if is_if_type_checking(operand)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue