mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:15:12 +00:00

This PR fixes the following false positive in a `.pyi` stub file: ```py x: int y = x # F821 currently emitted here, but shouldn't be in a stub file ``` In a `.py` file, this is invalid regardless of whether `from __future__ import annotations` is enabled or not. In a `.pyi` stub file, however, it's always valid, as an annotation counts as a binding in a stub file even if no value is assigned to the variable. I also added more test coverage for `.pyi` stub files in various edge cases where ruff's behaviour is currently correct, but where `.pyi` stub files do slightly different things to `.py` files.
44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
"""Tests for constructs allowed in `.pyi` stub files but not at runtime"""
|
|
|
|
from typing import Optional, TypeAlias, Union
|
|
|
|
__version__: str
|
|
__author__: str
|
|
|
|
# Forward references:
|
|
MaybeCStr: TypeAlias = Optional[CStr] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
MaybeCStr2: TypeAlias = Optional["CStr"] # always okay
|
|
CStr: TypeAlias = Union[C, str] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
CStr2: TypeAlias = Union["C", str] # always okay
|
|
|
|
# References to a class from inside the class:
|
|
class C:
|
|
other: C = ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
other2: "C" = ... # always okay
|
|
def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
def from_str2(self, s: str) -> "C": ... # always okay
|
|
|
|
# Circular references:
|
|
class A:
|
|
foo: B # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
foo2: "B" # always okay
|
|
bar: dict[str, B] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
bar2: dict[str, "A"] # always okay
|
|
|
|
class B:
|
|
foo: A # always okay
|
|
bar: dict[str, A] # always okay
|
|
|
|
class Leaf: ...
|
|
class Tree(list[Tree | Leaf]): ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
class Tree2(list["Tree | Leaf"]): ... # always okay
|
|
|
|
# Annotations are treated as assignments in .pyi files, but not in .py files
|
|
class MyClass:
|
|
foo: int
|
|
bar = foo # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
bar = "foo" # always okay
|
|
|
|
baz: MyClass
|
|
eggs = baz # valid in a `.pyi` stub file, not in a `.py` runtime file
|
|
eggs = "baz" # always okay
|