mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 20:42:10 +00:00
[ty] Document nearly all lints (#17981)
This commit is contained in:
parent
861ef2504e
commit
249a852a6e
3 changed files with 558 additions and 116 deletions
|
@ -61,7 +61,23 @@ Calling a non-callable object will raise a `TypeError` at runtime.
|
||||||
<summary>detects when an argument is used as both a value and a type form in a call</summary>
|
<summary>detects when an argument is used as both a value and a type form in a call</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Checks whether an argument is used as both a value and a type form in a call
|
Checks whether an argument is used as both a value and a type form in a call.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Such calls have confusing semantics and often indicate a logic error.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
from typing import reveal_type
|
||||||
|
from ty_extensions import is_fully_static
|
||||||
|
|
||||||
|
if flag:
|
||||||
|
f = repr # Expects a value
|
||||||
|
else:
|
||||||
|
f = is_fully_static # Expects a type form
|
||||||
|
|
||||||
|
f(int) # error
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-argument-forms)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-argument-forms)
|
||||||
|
@ -83,9 +99,19 @@ A variable with two conflicting declarations likely indicates a mistake.
|
||||||
Moreover, it could lead to incorrect or ill-defined type inference for
|
Moreover, it could lead to incorrect or ill-defined type inference for
|
||||||
other code that relies on these variables.
|
other code that relies on these variables.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
if b:
|
||||||
|
a: int
|
||||||
|
else:
|
||||||
|
a: str
|
||||||
|
|
||||||
|
a = 1
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-declarations)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-declarations)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L125)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L141)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `conflicting-metaclass`
|
## `conflicting-metaclass`
|
||||||
|
@ -95,11 +121,28 @@ other code that relies on these variables.
|
||||||
<details>
|
<details>
|
||||||
<summary>detects conflicting metaclasses</summary>
|
<summary>detects conflicting metaclasses</summary>
|
||||||
|
|
||||||
TODO #14889
|
### What it does
|
||||||
|
Checks for class definitions where the metaclass of the class
|
||||||
|
being created would not be a subclass of the metaclasses of
|
||||||
|
all the class's bases.
|
||||||
|
|
||||||
|
### Why is it bad?
|
||||||
|
Such a class definition raises a `TypeError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class M1(type): ...
|
||||||
|
class M2(type): ...
|
||||||
|
class A(metaclass=M1): ...
|
||||||
|
class B(metaclass=M2): ...
|
||||||
|
|
||||||
|
## TypeError: metaclass conflict
|
||||||
|
class C(A, B): ...
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-metaclass)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20conflicting-metaclass)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L140)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L166)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `cyclic-class-definition`
|
## `cyclic-class-definition`
|
||||||
|
@ -110,14 +153,27 @@ TODO #14889
|
||||||
<summary>detects cyclic class definitions</summary>
|
<summary>detects cyclic class definitions</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Checks for class definitions with a cyclic inheritance chain.
|
Checks for class definitions in stub files that inherit
|
||||||
|
(directly or indirectly) from themselves.
|
||||||
|
|
||||||
### Why is it bad?
|
### Why is it bad?
|
||||||
TODO #14889
|
Although forward references are natively supported in stub files,
|
||||||
|
inheritance cycles are still disallowed, as it is impossible to
|
||||||
|
resolve a consistent [method resolution order] for a class that
|
||||||
|
inherits from itself.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
## foo.pyi
|
||||||
|
class A(B): ...
|
||||||
|
class B(A): ...
|
||||||
|
```
|
||||||
|
|
||||||
|
[method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-class-definition)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20cyclic-class-definition)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L149)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L192)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `division-by-zero`
|
## `division-by-zero`
|
||||||
|
@ -140,7 +196,7 @@ Dividing by zero raises a `ZeroDivisionError` at runtime.
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20division-by-zero)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20division-by-zero)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L162)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L218)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `duplicate-base`
|
## `duplicate-base`
|
||||||
|
@ -154,11 +210,19 @@ Dividing by zero raises a `ZeroDivisionError` at runtime.
|
||||||
Checks for class definitions with duplicate bases.
|
Checks for class definitions with duplicate bases.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Class definitions with duplicate bases raise a `TypeError` at runtime.
|
Class definitions with duplicate bases raise `TypeError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class A: ...
|
||||||
|
|
||||||
|
## TypeError: duplicate base class
|
||||||
|
class B(A, A): ...
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-base)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20duplicate-base)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L180)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L236)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `escape-character-in-forward-annotation`
|
## `escape-character-in-forward-annotation`
|
||||||
|
@ -295,7 +359,7 @@ TypeError: multiple bases have instance lay-out conflict
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20incompatible-slots)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20incompatible-slots)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L193)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L257)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `inconsistent-mro`
|
## `inconsistent-mro`
|
||||||
|
@ -306,14 +370,25 @@ TypeError: multiple bases have instance lay-out conflict
|
||||||
<summary>detects class definitions with an inconsistent MRO</summary>
|
<summary>detects class definitions with an inconsistent MRO</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Checks for classes with an inconsistent method resolution order (MRO).
|
Checks for classes with an inconsistent [method resolution order] (MRO).
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Classes with an inconsistent MRO will raise a `TypeError` at runtime.
|
Classes with an inconsistent MRO will raise a `TypeError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class A: ...
|
||||||
|
class B(A): ...
|
||||||
|
|
||||||
|
## TypeError: Cannot create a consistent method resolution order
|
||||||
|
class C(A, B): ...
|
||||||
|
```
|
||||||
|
|
||||||
|
[method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20inconsistent-mro)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20inconsistent-mro)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L279)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L343)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `index-out-of-bounds`
|
## `index-out-of-bounds`
|
||||||
|
@ -330,9 +405,15 @@ a container.
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Using an out of bounds index will raise an `IndexError` at runtime.
|
Using an out of bounds index will raise an `IndexError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
t = (0, 1, 2)
|
||||||
|
t[3] # IndexError: tuple index out of range
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20index-out-of-bounds)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20index-out-of-bounds)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L292)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L367)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-argument-type`
|
## `invalid-argument-type`
|
||||||
|
@ -358,7 +439,7 @@ func("foo") # error: [invalid-argument-type]
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-argument-type)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-argument-type)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L306)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L387)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-assignment`
|
## `invalid-assignment`
|
||||||
|
@ -368,11 +449,24 @@ func("foo") # error: [invalid-argument-type]
|
||||||
<details>
|
<details>
|
||||||
<summary>detects invalid assignments</summary>
|
<summary>detects invalid assignments</summary>
|
||||||
|
|
||||||
TODO #14889
|
### What it does
|
||||||
|
Checks for assignments where the type of the value
|
||||||
|
is not [assignable to] the type of the assignee.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Such assignments break the rules of the type system and
|
||||||
|
weaken a type checker's ability to accurately reason about your code.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
a: int = ''
|
||||||
|
```
|
||||||
|
|
||||||
|
[assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-assignment)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-assignment)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L346)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L427)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-attribute-access`
|
## `invalid-attribute-access`
|
||||||
|
@ -383,20 +477,29 @@ TODO #14889
|
||||||
<summary>Invalid attribute access</summary>
|
<summary>Invalid attribute access</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Makes sure that instance attribute accesses are valid.
|
Checks for assignments to class variables from instances
|
||||||
|
and assignments to instance variables from its class.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Incorrect assignments break the rules of the type system and
|
||||||
|
weaken a type checker's ability to accurately reason about your code.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
```python
|
```python
|
||||||
class C:
|
class C:
|
||||||
var: ClassVar[int] = 1
|
class_var: ClassVar[int] = 1
|
||||||
|
instance_var: int
|
||||||
|
|
||||||
C.var = 3 # okay
|
C.class_var = 3 # okay
|
||||||
C().var = 3 # error: Cannot assign to class variable
|
C().class_var = 3 # error: Cannot assign to class variable
|
||||||
|
|
||||||
|
C().instance_var = 3 # okay
|
||||||
|
C.instance_var = 3 # error: Cannot assign to instance variable
|
||||||
```
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-attribute-access)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-attribute-access)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1099)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1311)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-base`
|
## `invalid-base`
|
||||||
|
@ -404,13 +507,13 @@ C().var = 3 # error: Cannot assign to class variable
|
||||||
**Default level**: error
|
**Default level**: error
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>detects class definitions with an invalid base</summary>
|
<summary>detects invalid bases in class definitions</summary>
|
||||||
|
|
||||||
TODO #14889
|
TODO #14889
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-base)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-base)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L355)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L449)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-context-manager`
|
## `invalid-context-manager`
|
||||||
|
@ -420,11 +523,23 @@ TODO #14889
|
||||||
<details>
|
<details>
|
||||||
<summary>detects expressions used in with statements that don't implement the context manager protocol</summary>
|
<summary>detects expressions used in with statements that don't implement the context manager protocol</summary>
|
||||||
|
|
||||||
TODO #14889
|
### What it does
|
||||||
|
Checks for expressions used in `with` statements
|
||||||
|
that do not implement the context manager protocol.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Such a statement will raise `TypeError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
## TypeError: 'int' object does not support the context manager protocol
|
||||||
|
with 1:
|
||||||
|
print(2)
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-context-manager)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-context-manager)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L364)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L458)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-declaration`
|
## `invalid-declaration`
|
||||||
|
@ -434,11 +549,25 @@ TODO #14889
|
||||||
<details>
|
<details>
|
||||||
<summary>detects invalid declarations</summary>
|
<summary>detects invalid declarations</summary>
|
||||||
|
|
||||||
TODO #14889
|
### What it does
|
||||||
|
Checks for declarations where the inferred type of an existing symbol
|
||||||
|
is not [assignable to] its post-hoc declared type.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
Such declarations break the rules of the type system and
|
||||||
|
weaken a type checker's ability to accurately reason about your code.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
a = 1
|
||||||
|
a: str
|
||||||
|
```
|
||||||
|
|
||||||
|
[assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-declaration)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-declaration)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L373)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L479)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-exception-caught`
|
## `invalid-exception-caught`
|
||||||
|
@ -479,7 +608,7 @@ except ZeroDivisionError:
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-exception-caught)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-exception-caught)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L382)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L502)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-generic-class`
|
## `invalid-generic-class`
|
||||||
|
@ -510,7 +639,7 @@ class C[U](Generic[T]): ...
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-generic-class)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-generic-class)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L418)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L538)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-legacy-type-variable`
|
## `invalid-legacy-type-variable`
|
||||||
|
@ -543,7 +672,7 @@ def f(t: TypeVar("U")): ...
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-legacy-type-variable)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-legacy-type-variable)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L444)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L564)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-metaclass`
|
## `invalid-metaclass`
|
||||||
|
@ -575,7 +704,7 @@ class B(metaclass=f): ...
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-metaclass)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-metaclass)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L472)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L592)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-overload`
|
## `invalid-overload`
|
||||||
|
@ -623,7 +752,7 @@ def foo(x: int) -> int: ...
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-overload)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-overload)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L499)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L619)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-parameter-default`
|
## `invalid-parameter-default`
|
||||||
|
@ -634,14 +763,21 @@ def foo(x: int) -> int: ...
|
||||||
<summary>detects default values that can't be assigned to the parameter's annotated type</summary>
|
<summary>detects default values that can't be assigned to the parameter's annotated type</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Checks for default values that can't be assigned to the parameter's annotated type.
|
Checks for default values that can't be
|
||||||
|
assigned to the parameter's annotated type.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
TODO #14889
|
This breaks the rules of the type system and
|
||||||
|
weakens a type checker's ability to accurately reason about your code.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
def f(a: int = ''): ...
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-parameter-default)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-parameter-default)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L542)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L662)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-protocol`
|
## `invalid-protocol`
|
||||||
|
@ -674,7 +810,7 @@ TypeError: Protocols can only inherit from other protocols, got <class 'int'>
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-protocol)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-protocol)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L251)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L315)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-raise`
|
## `invalid-raise`
|
||||||
|
@ -722,7 +858,7 @@ def g():
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-raise)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-raise)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L555)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L682)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-return-type`
|
## `invalid-return-type`
|
||||||
|
@ -746,7 +882,7 @@ def func() -> int:
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-return-type)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-return-type)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L327)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L408)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-super-argument`
|
## `invalid-super-argument`
|
||||||
|
@ -790,7 +926,7 @@ super(B, A) # error: `A` does not satisfy `issubclass(A, B)`
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-super-argument)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-super-argument)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L598)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L725)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-syntax-in-forward-annotation`
|
## `invalid-syntax-in-forward-annotation`
|
||||||
|
@ -825,9 +961,15 @@ code seen only by the type checker, and not at runtime. Normally this flag is im
|
||||||
must be assigned the value `False` at runtime; the type checker will consider its value to
|
must be assigned the value `False` at runtime; the type checker will consider its value to
|
||||||
be `True`. If annotated, it must be annotated as a type that can accept `bool` values.
|
be `True`. If annotated, it must be annotated as a type that can accept `bool` values.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
TYPE_CHECKING: str
|
||||||
|
TYPE_CHECKING = ''
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-checking-constant)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-checking-constant)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L637)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L764)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-type-form`
|
## `invalid-type-form`
|
||||||
|
@ -838,14 +980,24 @@ be `True`. If annotated, it must be annotated as a type that can accept `bool` v
|
||||||
<summary>detects invalid type forms</summary>
|
<summary>detects invalid type forms</summary>
|
||||||
|
|
||||||
### What it does
|
### What it does
|
||||||
Checks for invalid type expressions.
|
Checks for expressions that are used as type expressions
|
||||||
|
but cannot validly be interpreted as such.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
TODO #14889
|
Such expressions cannot be understood by ty.
|
||||||
|
In some cases, they might raise errors at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
|
a: type[1] # `1` is not a type
|
||||||
|
b: Annotated[int] # `Annotated` expects at least two arguments
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-form)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-form)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L655)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L788)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `invalid-type-variable-constraints`
|
## `invalid-type-variable-constraints`
|
||||||
|
@ -855,11 +1007,31 @@ TODO #14889
|
||||||
<details>
|
<details>
|
||||||
<summary>detects invalid type variable constraints</summary>
|
<summary>detects invalid type variable constraints</summary>
|
||||||
|
|
||||||
TODO #14889
|
### What it does
|
||||||
|
Checks for constrained [type variables] with only one constraint.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
A constrained type variable must have at least two constraints.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
T = TypeVar('T', str) # invalid constrained TypeVar
|
||||||
|
```
|
||||||
|
|
||||||
|
Use instead:
|
||||||
|
```python
|
||||||
|
T = TypeVar('T', str, int) # valid constrained TypeVar
|
||||||
|
## or
|
||||||
|
T = TypeVar('T', bound=str) # valid bound TypeVar
|
||||||
|
```
|
||||||
|
|
||||||
|
[type variables]: https://docs.python.org/3/library/typing.html#typing.TypeVar
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-variable-constraints)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20invalid-type-variable-constraints)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L668)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L811)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `missing-argument`
|
## `missing-argument`
|
||||||
|
@ -883,7 +1055,7 @@ func() # TypeError: func() missing 1 required positional argument: 'x'
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-argument)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20missing-argument)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L677)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L840)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `no-matching-overload`
|
## `no-matching-overload`
|
||||||
|
@ -911,7 +1083,7 @@ func("string") # error: [no-matching-overload]
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20no-matching-overload)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20no-matching-overload)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L696)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L859)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `non-subscriptable`
|
## `non-subscriptable`
|
||||||
|
@ -934,7 +1106,7 @@ Subscripting an object that does not support it will raise a `TypeError` at runt
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20non-subscriptable)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20non-subscriptable)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L719)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L882)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `not-iterable`
|
## `not-iterable`
|
||||||
|
@ -959,7 +1131,7 @@ for i in 34: # TypeError: 'int' object is not iterable
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20not-iterable)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20not-iterable)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L737)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L900)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `parameter-already-assigned`
|
## `parameter-already-assigned`
|
||||||
|
@ -985,7 +1157,7 @@ f(1, x=2) # Error raised here
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20parameter-already-assigned)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20parameter-already-assigned)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L788)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L951)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `raw-string-type-annotation`
|
## `raw-string-type-annotation`
|
||||||
|
@ -1028,6 +1200,11 @@ def test(): -> "int":
|
||||||
### What it does
|
### What it does
|
||||||
Makes sure that the argument of `static_assert` is statically known to be true.
|
Makes sure that the argument of `static_assert` is statically known to be true.
|
||||||
|
|
||||||
|
### Why is this bad?
|
||||||
|
A `static_assert` call represents an explicit request from the user
|
||||||
|
for the type checker to emit an error if the argument cannot be verified
|
||||||
|
to evaluate to `True` in a boolean context.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
```python
|
```python
|
||||||
from ty_extensions import static_assert
|
from ty_extensions import static_assert
|
||||||
|
@ -1039,7 +1216,7 @@ static_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known tr
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20static-assert-error)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20static-assert-error)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1080)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1287)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `subclass-of-final-class`
|
## `subclass-of-final-class`
|
||||||
|
@ -1067,7 +1244,7 @@ class B(A): ... # Error raised here
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20subclass-of-final-class)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20subclass-of-final-class)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L858)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1042)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `too-many-positional-arguments`
|
## `too-many-positional-arguments`
|
||||||
|
@ -1093,7 +1270,7 @@ f("foo") # Error raised here
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20too-many-positional-arguments)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20too-many-positional-arguments)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L903)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1087)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `type-assertion-failure`
|
## `type-assertion-failure`
|
||||||
|
@ -1120,7 +1297,7 @@ def _(x: int):
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20type-assertion-failure)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20type-assertion-failure)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L881)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1065)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unavailable-implicit-super-arguments`
|
## `unavailable-implicit-super-arguments`
|
||||||
|
@ -1164,7 +1341,7 @@ class A:
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unavailable-implicit-super-arguments)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unavailable-implicit-super-arguments)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L924)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1108)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unknown-argument`
|
## `unknown-argument`
|
||||||
|
@ -1190,7 +1367,7 @@ f(x=1, y=2) # Error raised here
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unknown-argument)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unknown-argument)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L979)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1165)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unresolved-attribute`
|
## `unresolved-attribute`
|
||||||
|
@ -1204,11 +1381,20 @@ f(x=1, y=2) # Error raised here
|
||||||
Checks for unresolved attributes.
|
Checks for unresolved attributes.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Accessing an unbound attribute will raise an `AttributeError` at runtime. An unresolved attribute is not guaranteed to exist from the type alone, so this could also indicate that the object is not of the type that the user expects.
|
Accessing an unbound attribute will raise an `AttributeError` at runtime.
|
||||||
|
An unresolved attribute is not guaranteed to exist from the type alone,
|
||||||
|
so this could also indicate that the object is not of the type that the user expects.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class A: ...
|
||||||
|
|
||||||
|
A().foo # AttributeError: 'A' object has no attribute 'foo'
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-attribute)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-attribute)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1000)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1186)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unresolved-import`
|
## `unresolved-import`
|
||||||
|
@ -1222,12 +1408,17 @@ Accessing an unbound attribute will raise an `AttributeError` at runtime. An unr
|
||||||
Checks for import statements for which the module cannot be resolved.
|
Checks for import statements for which the module cannot be resolved.
|
||||||
|
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Importing a module that cannot be resolved will raise an `ImportError`
|
Importing a module that cannot be resolved will raise a `ModuleNotFoundError`
|
||||||
at runtime.
|
at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
import foo # ModuleNotFoundError: No module named 'foo'
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-import)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-import)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1013)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1208)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unresolved-reference`
|
## `unresolved-reference`
|
||||||
|
@ -1251,7 +1442,7 @@ print(x) # NameError: name 'x' is not defined
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-reference)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unresolved-reference)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1027)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1227)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unsupported-bool-conversion`
|
## `unsupported-bool-conversion`
|
||||||
|
@ -1287,7 +1478,7 @@ b1 < b2 < b1 # exception raised here
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-bool-conversion)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-bool-conversion)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L757)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L920)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unsupported-operator`
|
## `unsupported-operator`
|
||||||
|
@ -1305,9 +1496,16 @@ the operands don't support the operator.
|
||||||
Attempting to use an unsupported operator will raise a `TypeError` at
|
Attempting to use an unsupported operator will raise a `TypeError` at
|
||||||
runtime.
|
runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class A: ...
|
||||||
|
|
||||||
|
A() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A'
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-operator)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20unsupported-operator)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1046)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1246)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `zero-stepsize-in-slice`
|
## `zero-stepsize-in-slice`
|
||||||
|
@ -1331,7 +1529,7 @@ l[1:10:0] # ValueError: slice step cannot be zero
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20zero-stepsize-in-slice)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20zero-stepsize-in-slice)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1061)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1268)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `call-possibly-unbound-method`
|
## `call-possibly-unbound-method`
|
||||||
|
@ -1394,9 +1592,18 @@ Checks for possibly unbound attributes.
|
||||||
### Why is this bad?
|
### Why is this bad?
|
||||||
Attempting to access an unbound attribute will raise an `AttributeError` at runtime.
|
Attempting to access an unbound attribute will raise an `AttributeError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
class A:
|
||||||
|
if b:
|
||||||
|
c = 0
|
||||||
|
|
||||||
|
A.c # AttributeError: type object 'A' has no attribute 'c'
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unbound-attribute)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unbound-attribute)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L809)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L972)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `possibly-unbound-import`
|
## `possibly-unbound-import`
|
||||||
|
@ -1413,9 +1620,21 @@ Checks for imports of symbols that may be unbound.
|
||||||
Importing an unbound module or name will raise a `ModuleNotFoundError`
|
Importing an unbound module or name will raise a `ModuleNotFoundError`
|
||||||
or `ImportError` at runtime.
|
or `ImportError` at runtime.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
```python
|
||||||
|
## module.py
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
if datetime.date.today().weekday() != 6:
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
## main.py
|
||||||
|
from module import a # ImportError: cannot import name 'a' from 'module'
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unbound-import)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unbound-import)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L822)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L994)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `redundant-cast`
|
## `redundant-cast`
|
||||||
|
@ -1441,7 +1660,7 @@ cast(int, f()) # Redundant
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20redundant-cast)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20redundant-cast)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1118)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1339)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `undefined-reveal`
|
## `undefined-reveal`
|
||||||
|
@ -1458,11 +1677,13 @@ Checks for calls to `reveal_type` without importing it.
|
||||||
Using `reveal_type` without importing it will raise a `NameError` at runtime.
|
Using `reveal_type` without importing it will raise a `NameError` at runtime.
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
TODO #14889
|
```python
|
||||||
|
reveal_type(1) # NameError: name 'reveal_type' is not defined
|
||||||
|
```
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20undefined-reveal)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20undefined-reveal)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L963)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1147)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unknown-rule`
|
## `unknown-rule`
|
||||||
|
@ -1519,7 +1740,7 @@ print(x) # NameError: name 'x' is not defined
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference)
|
* [Related issues](https://github.com/astral-sh/ty/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20possibly-unresolved-reference)
|
||||||
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L836)
|
* [View source](https://github.com/astral-sh/ruff/blob/main/crates%2Fty_python_semantic%2Fsrc%2Ftypes%2Fdiagnostic.rs#L1020)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## `unused-ignore-comment`
|
## `unused-ignore-comment`
|
||||||
|
|
|
@ -114,7 +114,23 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks whether an argument is used as both a value and a type form in a call
|
/// Checks whether an argument is used as both a value and a type form in a call.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Such calls have confusing semantics and often indicate a logic error.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// from typing import reveal_type
|
||||||
|
/// from ty_extensions import is_fully_static
|
||||||
|
///
|
||||||
|
/// if flag:
|
||||||
|
/// f = repr # Expects a value
|
||||||
|
/// else:
|
||||||
|
/// f = is_fully_static # Expects a type form
|
||||||
|
///
|
||||||
|
/// f(int) # error
|
||||||
|
/// ```
|
||||||
pub(crate) static CONFLICTING_ARGUMENT_FORMS = {
|
pub(crate) static CONFLICTING_ARGUMENT_FORMS = {
|
||||||
summary: "detects when an argument is used as both a value and a type form in a call",
|
summary: "detects when an argument is used as both a value and a type form in a call",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -130,6 +146,16 @@ declare_lint! {
|
||||||
/// A variable with two conflicting declarations likely indicates a mistake.
|
/// A variable with two conflicting declarations likely indicates a mistake.
|
||||||
/// Moreover, it could lead to incorrect or ill-defined type inference for
|
/// Moreover, it could lead to incorrect or ill-defined type inference for
|
||||||
/// other code that relies on these variables.
|
/// other code that relies on these variables.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// if b:
|
||||||
|
/// a: int
|
||||||
|
/// else:
|
||||||
|
/// a: str
|
||||||
|
///
|
||||||
|
/// a = 1
|
||||||
|
/// ```
|
||||||
pub(crate) static CONFLICTING_DECLARATIONS = {
|
pub(crate) static CONFLICTING_DECLARATIONS = {
|
||||||
summary: "detects conflicting declarations",
|
summary: "detects conflicting declarations",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -138,7 +164,24 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// ## What it does
|
||||||
|
/// Checks for class definitions where the metaclass of the class
|
||||||
|
/// being created would not be a subclass of the metaclasses of
|
||||||
|
/// all the class's bases.
|
||||||
|
///
|
||||||
|
/// ## Why is it bad?
|
||||||
|
/// Such a class definition raises a `TypeError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class M1(type): ...
|
||||||
|
/// class M2(type): ...
|
||||||
|
/// class A(metaclass=M1): ...
|
||||||
|
/// class B(metaclass=M2): ...
|
||||||
|
///
|
||||||
|
/// # TypeError: metaclass conflict
|
||||||
|
/// class C(A, B): ...
|
||||||
|
/// ```
|
||||||
pub(crate) static CONFLICTING_METACLASS = {
|
pub(crate) static CONFLICTING_METACLASS = {
|
||||||
summary: "detects conflicting metaclasses",
|
summary: "detects conflicting metaclasses",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -148,10 +191,23 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for class definitions with a cyclic inheritance chain.
|
/// Checks for class definitions in stub files that inherit
|
||||||
|
/// (directly or indirectly) from themselves.
|
||||||
///
|
///
|
||||||
/// ## Why is it bad?
|
/// ## Why is it bad?
|
||||||
/// TODO #14889
|
/// Although forward references are natively supported in stub files,
|
||||||
|
/// inheritance cycles are still disallowed, as it is impossible to
|
||||||
|
/// resolve a consistent [method resolution order] for a class that
|
||||||
|
/// inherits from itself.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// # foo.pyi
|
||||||
|
/// class A(B): ...
|
||||||
|
/// class B(A): ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||||
pub(crate) static CYCLIC_CLASS_DEFINITION = {
|
pub(crate) static CYCLIC_CLASS_DEFINITION = {
|
||||||
summary: "detects cyclic class definitions",
|
summary: "detects cyclic class definitions",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -182,7 +238,15 @@ declare_lint! {
|
||||||
/// Checks for class definitions with duplicate bases.
|
/// Checks for class definitions with duplicate bases.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Class definitions with duplicate bases raise a `TypeError` at runtime.
|
/// Class definitions with duplicate bases raise `TypeError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class A: ...
|
||||||
|
///
|
||||||
|
/// # TypeError: duplicate base class
|
||||||
|
/// class B(A, A): ...
|
||||||
|
/// ```
|
||||||
pub(crate) static DUPLICATE_BASE = {
|
pub(crate) static DUPLICATE_BASE = {
|
||||||
summary: "detects class definitions with duplicate bases",
|
summary: "detects class definitions with duplicate bases",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -278,10 +342,21 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for classes with an inconsistent method resolution order (MRO).
|
/// Checks for classes with an inconsistent [method resolution order] (MRO).
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Classes with an inconsistent MRO will raise a `TypeError` at runtime.
|
/// Classes with an inconsistent MRO will raise a `TypeError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class A: ...
|
||||||
|
/// class B(A): ...
|
||||||
|
///
|
||||||
|
/// # TypeError: Cannot create a consistent method resolution order
|
||||||
|
/// class C(A, B): ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
|
||||||
pub(crate) static INCONSISTENT_MRO = {
|
pub(crate) static INCONSISTENT_MRO = {
|
||||||
summary: "detects class definitions with an inconsistent MRO",
|
summary: "detects class definitions with an inconsistent MRO",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -296,6 +371,12 @@ declare_lint! {
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Using an out of bounds index will raise an `IndexError` at runtime.
|
/// Using an out of bounds index will raise an `IndexError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// t = (0, 1, 2)
|
||||||
|
/// t[3] # IndexError: tuple index out of range
|
||||||
|
/// ```
|
||||||
pub(crate) static INDEX_OUT_OF_BOUNDS = {
|
pub(crate) static INDEX_OUT_OF_BOUNDS = {
|
||||||
summary: "detects index out of bounds errors",
|
summary: "detects index out of bounds errors",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -344,7 +425,20 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// ## What it does
|
||||||
|
/// Checks for assignments where the type of the value
|
||||||
|
/// is not [assignable to] the type of the assignee.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Such assignments break the rules of the type system and
|
||||||
|
/// weaken a type checker's ability to accurately reason about your code.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// a: int = ''
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable
|
||||||
pub(crate) static INVALID_ASSIGNMENT = {
|
pub(crate) static INVALID_ASSIGNMENT = {
|
||||||
summary: "detects invalid assignments",
|
summary: "detects invalid assignments",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -355,14 +449,26 @@ declare_lint! {
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// TODO #14889
|
||||||
pub(crate) static INVALID_BASE = {
|
pub(crate) static INVALID_BASE = {
|
||||||
summary: "detects class definitions with an invalid base",
|
summary: "detects invalid bases in class definitions",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
default_level: Level::Error,
|
default_level: Level::Error,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// ## What it does
|
||||||
|
/// Checks for expressions used in `with` statements
|
||||||
|
/// that do not implement the context manager protocol.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Such a statement will raise `TypeError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// # TypeError: 'int' object does not support the context manager protocol
|
||||||
|
/// with 1:
|
||||||
|
/// print(2)
|
||||||
|
/// ```
|
||||||
pub(crate) static INVALID_CONTEXT_MANAGER = {
|
pub(crate) static INVALID_CONTEXT_MANAGER = {
|
||||||
summary: "detects expressions used in with statements that don't implement the context manager protocol",
|
summary: "detects expressions used in with statements that don't implement the context manager protocol",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -371,7 +477,21 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// ## What it does
|
||||||
|
/// Checks for declarations where the inferred type of an existing symbol
|
||||||
|
/// is not [assignable to] its post-hoc declared type.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Such declarations break the rules of the type system and
|
||||||
|
/// weaken a type checker's ability to accurately reason about your code.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// a = 1
|
||||||
|
/// a: str
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable
|
||||||
pub(crate) static INVALID_DECLARATION = {
|
pub(crate) static INVALID_DECLARATION = {
|
||||||
summary: "detects invalid declarations",
|
summary: "detects invalid declarations",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -541,10 +661,17 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for default values that can't be assigned to the parameter's annotated type.
|
/// Checks for default values that can't be
|
||||||
|
/// assigned to the parameter's annotated type.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// TODO #14889
|
/// This breaks the rules of the type system and
|
||||||
|
/// weakens a type checker's ability to accurately reason about your code.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// def f(a: int = ''): ...
|
||||||
|
/// ```
|
||||||
pub(crate) static INVALID_PARAMETER_DEFAULT = {
|
pub(crate) static INVALID_PARAMETER_DEFAULT = {
|
||||||
summary: "detects default values that can't be assigned to the parameter's annotated type",
|
summary: "detects default values that can't be assigned to the parameter's annotated type",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -645,6 +772,12 @@ declare_lint! {
|
||||||
/// `typing` or `typing_extensions`, but it can also be defined locally. If defined locally, it
|
/// `typing` or `typing_extensions`, but it can also be defined locally. If defined locally, it
|
||||||
/// must be assigned the value `False` at runtime; the type checker will consider its value to
|
/// must be assigned the value `False` at runtime; the type checker will consider its value to
|
||||||
/// be `True`. If annotated, it must be annotated as a type that can accept `bool` values.
|
/// be `True`. If annotated, it must be annotated as a type that can accept `bool` values.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// TYPE_CHECKING: str
|
||||||
|
/// TYPE_CHECKING = ''
|
||||||
|
/// ```
|
||||||
pub(crate) static INVALID_TYPE_CHECKING_CONSTANT = {
|
pub(crate) static INVALID_TYPE_CHECKING_CONSTANT = {
|
||||||
summary: "detects invalid `TYPE_CHECKING` constant assignments",
|
summary: "detects invalid `TYPE_CHECKING` constant assignments",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -654,10 +787,20 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for invalid type expressions.
|
/// Checks for expressions that are used as type expressions
|
||||||
|
/// but cannot validly be interpreted as such.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// TODO #14889
|
/// Such expressions cannot be understood by ty.
|
||||||
|
/// In some cases, they might raise errors at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// from typing import Annotated
|
||||||
|
///
|
||||||
|
/// a: type[1] # `1` is not a type
|
||||||
|
/// b: Annotated[int] # `Annotated` expects at least two arguments
|
||||||
|
/// ```
|
||||||
pub(crate) static INVALID_TYPE_FORM = {
|
pub(crate) static INVALID_TYPE_FORM = {
|
||||||
summary: "detects invalid type forms",
|
summary: "detects invalid type forms",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -666,7 +809,27 @@ declare_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// TODO #14889
|
/// ## What it does
|
||||||
|
/// Checks for constrained [type variables] with only one constraint.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// A constrained type variable must have at least two constraints.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// from typing import TypeVar
|
||||||
|
///
|
||||||
|
/// T = TypeVar('T', str) # invalid constrained TypeVar
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```python
|
||||||
|
/// T = TypeVar('T', str, int) # valid constrained TypeVar
|
||||||
|
/// # or
|
||||||
|
/// T = TypeVar('T', bound=str) # valid bound TypeVar
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [type variables]: https://docs.python.org/3/library/typing.html#typing.TypeVar
|
||||||
pub(crate) static INVALID_TYPE_VARIABLE_CONSTRAINTS = {
|
pub(crate) static INVALID_TYPE_VARIABLE_CONSTRAINTS = {
|
||||||
summary: "detects invalid type variable constraints",
|
summary: "detects invalid type variable constraints",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -812,6 +975,15 @@ declare_lint! {
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Attempting to access an unbound attribute will raise an `AttributeError` at runtime.
|
/// Attempting to access an unbound attribute will raise an `AttributeError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class A:
|
||||||
|
/// if b:
|
||||||
|
/// c = 0
|
||||||
|
///
|
||||||
|
/// A.c # AttributeError: type object 'A' has no attribute 'c'
|
||||||
|
/// ```
|
||||||
pub(crate) static POSSIBLY_UNBOUND_ATTRIBUTE = {
|
pub(crate) static POSSIBLY_UNBOUND_ATTRIBUTE = {
|
||||||
summary: "detects references to possibly unbound attributes",
|
summary: "detects references to possibly unbound attributes",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -826,6 +998,18 @@ declare_lint! {
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Importing an unbound module or name will raise a `ModuleNotFoundError`
|
/// Importing an unbound module or name will raise a `ModuleNotFoundError`
|
||||||
/// or `ImportError` at runtime.
|
/// or `ImportError` at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// # module.py
|
||||||
|
/// import datetime
|
||||||
|
///
|
||||||
|
/// if datetime.date.today().weekday() != 6:
|
||||||
|
/// a = 1
|
||||||
|
///
|
||||||
|
/// # main.py
|
||||||
|
/// from module import a # ImportError: cannot import name 'a' from 'module'
|
||||||
|
/// ```
|
||||||
pub(crate) static POSSIBLY_UNBOUND_IMPORT = {
|
pub(crate) static POSSIBLY_UNBOUND_IMPORT = {
|
||||||
summary: "detects possibly unbound imports",
|
summary: "detects possibly unbound imports",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -968,7 +1152,9 @@ declare_lint! {
|
||||||
/// Using `reveal_type` without importing it will raise a `NameError` at runtime.
|
/// Using `reveal_type` without importing it will raise a `NameError` at runtime.
|
||||||
///
|
///
|
||||||
/// ## Examples
|
/// ## Examples
|
||||||
/// TODO #14889
|
/// ```python
|
||||||
|
/// reveal_type(1) # NameError: name 'reveal_type' is not defined
|
||||||
|
/// ```
|
||||||
pub(crate) static UNDEFINED_REVEAL = {
|
pub(crate) static UNDEFINED_REVEAL = {
|
||||||
summary: "detects usages of `reveal_type` without importing it",
|
summary: "detects usages of `reveal_type` without importing it",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -1002,7 +1188,16 @@ declare_lint! {
|
||||||
/// Checks for unresolved attributes.
|
/// Checks for unresolved attributes.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Accessing an unbound attribute will raise an `AttributeError` at runtime. An unresolved attribute is not guaranteed to exist from the type alone, so this could also indicate that the object is not of the type that the user expects.
|
/// Accessing an unbound attribute will raise an `AttributeError` at runtime.
|
||||||
|
/// An unresolved attribute is not guaranteed to exist from the type alone,
|
||||||
|
/// so this could also indicate that the object is not of the type that the user expects.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class A: ...
|
||||||
|
///
|
||||||
|
/// A().foo # AttributeError: 'A' object has no attribute 'foo'
|
||||||
|
/// ```
|
||||||
pub(crate) static UNRESOLVED_ATTRIBUTE = {
|
pub(crate) static UNRESOLVED_ATTRIBUTE = {
|
||||||
summary: "detects references to unresolved attributes",
|
summary: "detects references to unresolved attributes",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -1015,8 +1210,13 @@ declare_lint! {
|
||||||
/// Checks for import statements for which the module cannot be resolved.
|
/// Checks for import statements for which the module cannot be resolved.
|
||||||
///
|
///
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Importing a module that cannot be resolved will raise an `ImportError`
|
/// Importing a module that cannot be resolved will raise a `ModuleNotFoundError`
|
||||||
/// at runtime.
|
/// at runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// import foo # ModuleNotFoundError: No module named 'foo'
|
||||||
|
/// ```
|
||||||
pub(crate) static UNRESOLVED_IMPORT = {
|
pub(crate) static UNRESOLVED_IMPORT = {
|
||||||
summary: "detects unresolved imports",
|
summary: "detects unresolved imports",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -1051,6 +1251,13 @@ declare_lint! {
|
||||||
/// ## Why is this bad?
|
/// ## Why is this bad?
|
||||||
/// Attempting to use an unsupported operator will raise a `TypeError` at
|
/// Attempting to use an unsupported operator will raise a `TypeError` at
|
||||||
/// runtime.
|
/// runtime.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
/// ```python
|
||||||
|
/// class A: ...
|
||||||
|
///
|
||||||
|
/// A() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A'
|
||||||
|
/// ```
|
||||||
pub(crate) static UNSUPPORTED_OPERATOR = {
|
pub(crate) static UNSUPPORTED_OPERATOR = {
|
||||||
summary: "detects binary, unary, or comparison expressions where the operands don't support the operator",
|
summary: "detects binary, unary, or comparison expressions where the operands don't support the operator",
|
||||||
status: LintStatus::preview("1.0.0"),
|
status: LintStatus::preview("1.0.0"),
|
||||||
|
@ -1081,6 +1288,11 @@ declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Makes sure that the argument of `static_assert` is statically known to be true.
|
/// Makes sure that the argument of `static_assert` is statically known to be true.
|
||||||
///
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// A `static_assert` call represents an explicit request from the user
|
||||||
|
/// for the type checker to emit an error if the argument cannot be verified
|
||||||
|
/// to evaluate to `True` in a boolean context.
|
||||||
|
///
|
||||||
/// ## Examples
|
/// ## Examples
|
||||||
/// ```python
|
/// ```python
|
||||||
/// from ty_extensions import static_assert
|
/// from ty_extensions import static_assert
|
||||||
|
@ -1098,15 +1310,24 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Makes sure that instance attribute accesses are valid.
|
/// Checks for assignments to class variables from instances
|
||||||
|
/// and assignments to instance variables from its class.
|
||||||
|
///
|
||||||
|
/// ## Why is this bad?
|
||||||
|
/// Incorrect assignments break the rules of the type system and
|
||||||
|
/// weaken a type checker's ability to accurately reason about your code.
|
||||||
///
|
///
|
||||||
/// ## Examples
|
/// ## Examples
|
||||||
/// ```python
|
/// ```python
|
||||||
/// class C:
|
/// class C:
|
||||||
/// var: ClassVar[int] = 1
|
/// class_var: ClassVar[int] = 1
|
||||||
|
/// instance_var: int
|
||||||
///
|
///
|
||||||
/// C.var = 3 # okay
|
/// C.class_var = 3 # okay
|
||||||
/// C().var = 3 # error: Cannot assign to class variable
|
/// C().class_var = 3 # error: Cannot assign to class variable
|
||||||
|
///
|
||||||
|
/// C().instance_var = 3 # okay
|
||||||
|
/// C.instance_var = 3 # error: Cannot assign to instance variable
|
||||||
/// ```
|
/// ```
|
||||||
pub(crate) static INVALID_ATTRIBUTE_ACCESS = {
|
pub(crate) static INVALID_ATTRIBUTE_ACCESS = {
|
||||||
summary: "Invalid attribute access",
|
summary: "Invalid attribute access",
|
||||||
|
|
|
@ -252,7 +252,7 @@
|
||||||
},
|
},
|
||||||
"conflicting-argument-forms": {
|
"conflicting-argument-forms": {
|
||||||
"title": "detects when an argument is used as both a value and a type form in a call",
|
"title": "detects when an argument is used as both a value and a type form in a call",
|
||||||
"description": "## What it does\nChecks whether an argument is used as both a value and a type form in a call",
|
"description": "## What it does\nChecks whether an argument is used as both a value and a type form in a call.\n\n## Why is this bad?\nSuch calls have confusing semantics and often indicate a logic error.\n\n## Examples\n```python\nfrom typing import reveal_type\nfrom ty_extensions import is_fully_static\n\nif flag:\n f = repr # Expects a value\nelse:\n f = is_fully_static # Expects a type form\n\nf(int) # error\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -262,7 +262,7 @@
|
||||||
},
|
},
|
||||||
"conflicting-declarations": {
|
"conflicting-declarations": {
|
||||||
"title": "detects conflicting declarations",
|
"title": "detects conflicting declarations",
|
||||||
"description": "## What it does\nChecks whether a variable has been declared as two conflicting types.\n\n## Why is this bad\nA variable with two conflicting declarations likely indicates a mistake.\nMoreover, it could lead to incorrect or ill-defined type inference for\nother code that relies on these variables.",
|
"description": "## What it does\nChecks whether a variable has been declared as two conflicting types.\n\n## Why is this bad\nA variable with two conflicting declarations likely indicates a mistake.\nMoreover, it could lead to incorrect or ill-defined type inference for\nother code that relies on these variables.\n\n## Examples\n```python\nif b:\n a: int\nelse:\n a: str\n\na = 1\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -272,7 +272,7 @@
|
||||||
},
|
},
|
||||||
"conflicting-metaclass": {
|
"conflicting-metaclass": {
|
||||||
"title": "detects conflicting metaclasses",
|
"title": "detects conflicting metaclasses",
|
||||||
"description": "TODO #14889",
|
"description": "## What it does\nChecks for class definitions where the metaclass of the class\nbeing created would not be a subclass of the metaclasses of\nall the class's bases.\n\n## Why is it bad?\nSuch a class definition raises a `TypeError` at runtime.\n\n## Examples\n```python\nclass M1(type): ...\nclass M2(type): ...\nclass A(metaclass=M1): ...\nclass B(metaclass=M2): ...\n\n# TypeError: metaclass conflict\nclass C(A, B): ...\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -282,7 +282,7 @@
|
||||||
},
|
},
|
||||||
"cyclic-class-definition": {
|
"cyclic-class-definition": {
|
||||||
"title": "detects cyclic class definitions",
|
"title": "detects cyclic class definitions",
|
||||||
"description": "## What it does\nChecks for class definitions with a cyclic inheritance chain.\n\n## Why is it bad?\nTODO #14889",
|
"description": "## What it does\nChecks for class definitions in stub files that inherit\n(directly or indirectly) from themselves.\n\n## Why is it bad?\nAlthough forward references are natively supported in stub files,\ninheritance cycles are still disallowed, as it is impossible to\nresolve a consistent [method resolution order] for a class that\ninherits from itself.\n\n## Examples\n```python\n# foo.pyi\nclass A(B): ...\nclass B(A): ...\n```\n\n[method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -302,7 +302,7 @@
|
||||||
},
|
},
|
||||||
"duplicate-base": {
|
"duplicate-base": {
|
||||||
"title": "detects class definitions with duplicate bases",
|
"title": "detects class definitions with duplicate bases",
|
||||||
"description": "## What it does\nChecks for class definitions with duplicate bases.\n\n## Why is this bad?\nClass definitions with duplicate bases raise a `TypeError` at runtime.",
|
"description": "## What it does\nChecks for class definitions with duplicate bases.\n\n## Why is this bad?\nClass definitions with duplicate bases raise `TypeError` at runtime.\n\n## Examples\n```python\nclass A: ...\n\n# TypeError: duplicate base class\nclass B(A, A): ...\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -352,7 +352,7 @@
|
||||||
},
|
},
|
||||||
"inconsistent-mro": {
|
"inconsistent-mro": {
|
||||||
"title": "detects class definitions with an inconsistent MRO",
|
"title": "detects class definitions with an inconsistent MRO",
|
||||||
"description": "## What it does\nChecks for classes with an inconsistent method resolution order (MRO).\n\n## Why is this bad?\nClasses with an inconsistent MRO will raise a `TypeError` at runtime.",
|
"description": "## What it does\nChecks for classes with an inconsistent [method resolution order] (MRO).\n\n## Why is this bad?\nClasses with an inconsistent MRO will raise a `TypeError` at runtime.\n\n## Examples\n```python\nclass A: ...\nclass B(A): ...\n\n# TypeError: Cannot create a consistent method resolution order\nclass C(A, B): ...\n```\n\n[method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -362,7 +362,7 @@
|
||||||
},
|
},
|
||||||
"index-out-of-bounds": {
|
"index-out-of-bounds": {
|
||||||
"title": "detects index out of bounds errors",
|
"title": "detects index out of bounds errors",
|
||||||
"description": "## What it does\nChecks for attempts to use an out of bounds index to get an item from\na container.\n\n## Why is this bad?\nUsing an out of bounds index will raise an `IndexError` at runtime.",
|
"description": "## What it does\nChecks for attempts to use an out of bounds index to get an item from\na container.\n\n## Why is this bad?\nUsing an out of bounds index will raise an `IndexError` at runtime.\n\n## Examples\n```python\nt = (0, 1, 2)\nt[3] # IndexError: tuple index out of range\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -382,7 +382,7 @@
|
||||||
},
|
},
|
||||||
"invalid-assignment": {
|
"invalid-assignment": {
|
||||||
"title": "detects invalid assignments",
|
"title": "detects invalid assignments",
|
||||||
"description": "TODO #14889",
|
"description": "## What it does\nChecks for assignments where the type of the value\nis not [assignable to] the type of the assignee.\n\n## Why is this bad?\nSuch assignments break the rules of the type system and\nweaken a type checker's ability to accurately reason about your code.\n\n## Examples\n```python\na: int = ''\n```\n\n[assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -392,7 +392,7 @@
|
||||||
},
|
},
|
||||||
"invalid-attribute-access": {
|
"invalid-attribute-access": {
|
||||||
"title": "Invalid attribute access",
|
"title": "Invalid attribute access",
|
||||||
"description": "## What it does\nMakes sure that instance attribute accesses are valid.\n\n## Examples\n```python\nclass C:\n var: ClassVar[int] = 1\n\nC.var = 3 # okay\nC().var = 3 # error: Cannot assign to class variable\n```",
|
"description": "## What it does\nChecks for assignments to class variables from instances\nand assignments to instance variables from its class.\n\n## Why is this bad?\nIncorrect assignments break the rules of the type system and\nweaken a type checker's ability to accurately reason about your code.\n\n## Examples\n```python\nclass C:\n class_var: ClassVar[int] = 1\n instance_var: int\n\nC.class_var = 3 # okay\nC().class_var = 3 # error: Cannot assign to class variable\n\nC().instance_var = 3 # okay\nC.instance_var = 3 # error: Cannot assign to instance variable\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -401,7 +401,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"invalid-base": {
|
"invalid-base": {
|
||||||
"title": "detects class definitions with an invalid base",
|
"title": "detects invalid bases in class definitions",
|
||||||
"description": "TODO #14889",
|
"description": "TODO #14889",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
@ -412,7 +412,7 @@
|
||||||
},
|
},
|
||||||
"invalid-context-manager": {
|
"invalid-context-manager": {
|
||||||
"title": "detects expressions used in with statements that don't implement the context manager protocol",
|
"title": "detects expressions used in with statements that don't implement the context manager protocol",
|
||||||
"description": "TODO #14889",
|
"description": "## What it does\nChecks for expressions used in `with` statements\nthat do not implement the context manager protocol.\n\n## Why is this bad?\nSuch a statement will raise `TypeError` at runtime.\n\n## Examples\n```python\n# TypeError: 'int' object does not support the context manager protocol\nwith 1:\n print(2)\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -422,7 +422,7 @@
|
||||||
},
|
},
|
||||||
"invalid-declaration": {
|
"invalid-declaration": {
|
||||||
"title": "detects invalid declarations",
|
"title": "detects invalid declarations",
|
||||||
"description": "TODO #14889",
|
"description": "## What it does\nChecks for declarations where the inferred type of an existing symbol\nis not [assignable to] its post-hoc declared type.\n\n## Why is this bad?\nSuch declarations break the rules of the type system and\nweaken a type checker's ability to accurately reason about your code.\n\n## Examples\n```python\na = 1\na: str\n```\n\n[assignable to]: https://typing.python.org/en/latest/spec/glossary.html#term-assignable",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -492,7 +492,7 @@
|
||||||
},
|
},
|
||||||
"invalid-parameter-default": {
|
"invalid-parameter-default": {
|
||||||
"title": "detects default values that can't be assigned to the parameter's annotated type",
|
"title": "detects default values that can't be assigned to the parameter's annotated type",
|
||||||
"description": "## What it does\nChecks for default values that can't be assigned to the parameter's annotated type.\n\n## Why is this bad?\nTODO #14889",
|
"description": "## What it does\nChecks for default values that can't be\nassigned to the parameter's annotated type.\n\n## Why is this bad?\nThis breaks the rules of the type system and\nweakens a type checker's ability to accurately reason about your code.\n\n## Examples\n```python\ndef f(a: int = ''): ...\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -552,7 +552,7 @@
|
||||||
},
|
},
|
||||||
"invalid-type-checking-constant": {
|
"invalid-type-checking-constant": {
|
||||||
"title": "detects invalid `TYPE_CHECKING` constant assignments",
|
"title": "detects invalid `TYPE_CHECKING` constant assignments",
|
||||||
"description": "## What it does\nChecks for a value other than `False` assigned to the `TYPE_CHECKING` variable, or an\nannotation not assignable from `bool`.\n\n## Why is this bad?\nThe name `TYPE_CHECKING` is reserved for a flag that can be used to provide conditional\ncode seen only by the type checker, and not at runtime. Normally this flag is imported from\n`typing` or `typing_extensions`, but it can also be defined locally. If defined locally, it\nmust be assigned the value `False` at runtime; the type checker will consider its value to\nbe `True`. If annotated, it must be annotated as a type that can accept `bool` values.",
|
"description": "## What it does\nChecks for a value other than `False` assigned to the `TYPE_CHECKING` variable, or an\nannotation not assignable from `bool`.\n\n## Why is this bad?\nThe name `TYPE_CHECKING` is reserved for a flag that can be used to provide conditional\ncode seen only by the type checker, and not at runtime. Normally this flag is imported from\n`typing` or `typing_extensions`, but it can also be defined locally. If defined locally, it\nmust be assigned the value `False` at runtime; the type checker will consider its value to\nbe `True`. If annotated, it must be annotated as a type that can accept `bool` values.\n\n## Examples\n```python\nTYPE_CHECKING: str\nTYPE_CHECKING = ''\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -562,7 +562,7 @@
|
||||||
},
|
},
|
||||||
"invalid-type-form": {
|
"invalid-type-form": {
|
||||||
"title": "detects invalid type forms",
|
"title": "detects invalid type forms",
|
||||||
"description": "## What it does\nChecks for invalid type expressions.\n\n## Why is this bad?\nTODO #14889",
|
"description": "## What it does\nChecks for expressions that are used as type expressions\nbut cannot validly be interpreted as such.\n\n## Why is this bad?\nSuch expressions cannot be understood by ty.\nIn some cases, they might raise errors at runtime.\n\n## Examples\n```python\nfrom typing import Annotated\n\na: type[1] # `1` is not a type\nb: Annotated[int] # `Annotated` expects at least two arguments\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -572,7 +572,7 @@
|
||||||
},
|
},
|
||||||
"invalid-type-variable-constraints": {
|
"invalid-type-variable-constraints": {
|
||||||
"title": "detects invalid type variable constraints",
|
"title": "detects invalid type variable constraints",
|
||||||
"description": "TODO #14889",
|
"description": "## What it does\nChecks for constrained [type variables] with only one constraint.\n\n## Why is this bad?\nA constrained type variable must have at least two constraints.\n\n## Examples\n```python\nfrom typing import TypeVar\n\nT = TypeVar('T', str) # invalid constrained TypeVar\n```\n\nUse instead:\n```python\nT = TypeVar('T', str, int) # valid constrained TypeVar\n# or\nT = TypeVar('T', bound=str) # valid bound TypeVar\n```\n\n[type variables]: https://docs.python.org/3/library/typing.html#typing.TypeVar",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -632,7 +632,7 @@
|
||||||
},
|
},
|
||||||
"possibly-unbound-attribute": {
|
"possibly-unbound-attribute": {
|
||||||
"title": "detects references to possibly unbound attributes",
|
"title": "detects references to possibly unbound attributes",
|
||||||
"description": "## What it does\nChecks for possibly unbound attributes.\n\n## Why is this bad?\nAttempting to access an unbound attribute will raise an `AttributeError` at runtime.",
|
"description": "## What it does\nChecks for possibly unbound attributes.\n\n## Why is this bad?\nAttempting to access an unbound attribute will raise an `AttributeError` at runtime.\n\n## Examples\n```python\nclass A:\n if b:\n c = 0\n\nA.c # AttributeError: type object 'A' has no attribute 'c'\n```",
|
||||||
"default": "warn",
|
"default": "warn",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -642,7 +642,7 @@
|
||||||
},
|
},
|
||||||
"possibly-unbound-import": {
|
"possibly-unbound-import": {
|
||||||
"title": "detects possibly unbound imports",
|
"title": "detects possibly unbound imports",
|
||||||
"description": "## What it does\nChecks for imports of symbols that may be unbound.\n\n## Why is this bad?\nImporting an unbound module or name will raise a `ModuleNotFoundError`\nor `ImportError` at runtime.",
|
"description": "## What it does\nChecks for imports of symbols that may be unbound.\n\n## Why is this bad?\nImporting an unbound module or name will raise a `ModuleNotFoundError`\nor `ImportError` at runtime.\n\n## Examples\n```python\n# module.py\nimport datetime\n\nif datetime.date.today().weekday() != 6:\n a = 1\n\n# main.py\nfrom module import a # ImportError: cannot import name 'a' from 'module'\n```",
|
||||||
"default": "warn",
|
"default": "warn",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -682,7 +682,7 @@
|
||||||
},
|
},
|
||||||
"static-assert-error": {
|
"static-assert-error": {
|
||||||
"title": "Failed static assertion",
|
"title": "Failed static assertion",
|
||||||
"description": "## What it does\nMakes sure that the argument of `static_assert` is statically known to be true.\n\n## Examples\n```python\nfrom ty_extensions import static_assert\n\nstatic_assert(1 + 1 == 3) # error: evaluates to `False`\n\nstatic_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known truthiness\n```",
|
"description": "## What it does\nMakes sure that the argument of `static_assert` is statically known to be true.\n\n## Why is this bad?\nA `static_assert` call represents an explicit request from the user\nfor the type checker to emit an error if the argument cannot be verified\nto evaluate to `True` in a boolean context.\n\n## Examples\n```python\nfrom ty_extensions import static_assert\n\nstatic_assert(1 + 1 == 3) # error: evaluates to `False`\n\nstatic_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known truthiness\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -732,7 +732,7 @@
|
||||||
},
|
},
|
||||||
"undefined-reveal": {
|
"undefined-reveal": {
|
||||||
"title": "detects usages of `reveal_type` without importing it",
|
"title": "detects usages of `reveal_type` without importing it",
|
||||||
"description": "## What it does\nChecks for calls to `reveal_type` without importing it.\n\n## Why is this bad?\nUsing `reveal_type` without importing it will raise a `NameError` at runtime.\n\n## Examples\nTODO #14889",
|
"description": "## What it does\nChecks for calls to `reveal_type` without importing it.\n\n## Why is this bad?\nUsing `reveal_type` without importing it will raise a `NameError` at runtime.\n\n## Examples\n```python\nreveal_type(1) # NameError: name 'reveal_type' is not defined\n```",
|
||||||
"default": "warn",
|
"default": "warn",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -762,7 +762,7 @@
|
||||||
},
|
},
|
||||||
"unresolved-attribute": {
|
"unresolved-attribute": {
|
||||||
"title": "detects references to unresolved attributes",
|
"title": "detects references to unresolved attributes",
|
||||||
"description": "## What it does\nChecks for unresolved attributes.\n\n## Why is this bad?\nAccessing an unbound attribute will raise an `AttributeError` at runtime. An unresolved attribute is not guaranteed to exist from the type alone, so this could also indicate that the object is not of the type that the user expects.",
|
"description": "## What it does\nChecks for unresolved attributes.\n\n## Why is this bad?\nAccessing an unbound attribute will raise an `AttributeError` at runtime.\nAn unresolved attribute is not guaranteed to exist from the type alone,\nso this could also indicate that the object is not of the type that the user expects.\n\n## Examples\n```python\nclass A: ...\n\nA().foo # AttributeError: 'A' object has no attribute 'foo'\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -772,7 +772,7 @@
|
||||||
},
|
},
|
||||||
"unresolved-import": {
|
"unresolved-import": {
|
||||||
"title": "detects unresolved imports",
|
"title": "detects unresolved imports",
|
||||||
"description": "## What it does\nChecks for import statements for which the module cannot be resolved.\n\n## Why is this bad?\nImporting a module that cannot be resolved will raise an `ImportError`\nat runtime.",
|
"description": "## What it does\nChecks for import statements for which the module cannot be resolved.\n\n## Why is this bad?\nImporting a module that cannot be resolved will raise a `ModuleNotFoundError`\nat runtime.\n\n## Examples\n```python\nimport foo # ModuleNotFoundError: No module named 'foo'\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
@ -802,7 +802,7 @@
|
||||||
},
|
},
|
||||||
"unsupported-operator": {
|
"unsupported-operator": {
|
||||||
"title": "detects binary, unary, or comparison expressions where the operands don't support the operator",
|
"title": "detects binary, unary, or comparison expressions where the operands don't support the operator",
|
||||||
"description": "## What it does\nChecks for binary expressions, comparisons, and unary expressions where\nthe operands don't support the operator.\n\n## Why is this bad?\nAttempting to use an unsupported operator will raise a `TypeError` at\nruntime.",
|
"description": "## What it does\nChecks for binary expressions, comparisons, and unary expressions where\nthe operands don't support the operator.\n\n## Why is this bad?\nAttempting to use an unsupported operator will raise a `TypeError` at\nruntime.\n\n## Examples\n```python\nclass A: ...\n\nA() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A'\n```",
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue