|
200 | 200 | "OverrideOptions": { |
201 | 201 | "type": "object", |
202 | 202 | "properties": { |
| 203 | + "analysis": { |
| 204 | + "anyOf": [ |
| 205 | + { |
| 206 | + "$ref": "#/definitions/AnalysisOptions" |
| 207 | + }, |
| 208 | + { |
| 209 | + "type": "null" |
| 210 | + } |
| 211 | + ] |
| 212 | + }, |
203 | 213 | "exclude": { |
204 | 214 | "description": "A list of file and directory patterns to exclude from this override.\n\nPatterns follow a syntax similar to `.gitignore`.\nExclude patterns take precedence over include patterns within the same override.\n\nIf not specified, defaults to `[]` (excludes no files).", |
205 | 215 | "anyOf": [ |
|
512 | 522 | } |
513 | 523 | ] |
514 | 524 | }, |
| 525 | + "ineffective-final": { |
| 526 | + "title": "detects calls to `final()` that type checkers cannot interpret", |
| 527 | + "description": "## What it does\nChecks for calls to `final()` that type checkers cannot interpret.\n\n## Why is this bad?\nThe `final()` function is designed to be used as a decorator. When called directly\nas a function (e.g., `final(type(...))`), type checkers will not understand the\napplication of `final` and will not prevent subclassing.\n\n## Example\n\n```python\nfrom typing import final\n\n# Incorrect: type checkers will not prevent subclassing\nMyClass = final(type(\"MyClass\", (), {}))\n\n# Correct: use `final` as a decorator\n@final\nclass MyClass: ...\n```", |
| 528 | + "default": "warn", |
| 529 | + "oneOf": [ |
| 530 | + { |
| 531 | + "$ref": "#/definitions/Level" |
| 532 | + } |
| 533 | + ] |
| 534 | + }, |
515 | 535 | "instance-layout-conflict": { |
516 | 536 | "title": "detects class definitions that raise `TypeError` due to instance layout conflict", |
517 | 537 | "description": "## What it does\nChecks for classes definitions which will fail at runtime due to\n\"instance memory layout conflicts\".\n\nThis error is usually caused by attempting to combine multiple classes\nthat define non-empty `__slots__` in a class's [Method Resolution Order]\n(MRO), or by attempting to combine multiple builtin classes in a class's\nMRO.\n\n## Why is this bad?\nInheriting from bases with conflicting instance memory layouts\nwill lead to a `TypeError` at runtime.\n\nAn instance memory layout conflict occurs when CPython cannot determine\nthe memory layout instances of a class should have, because the instance\nmemory layout of one of its bases conflicts with the instance memory layout\nof one or more of its other bases.\n\nFor example, if a Python class defines non-empty `__slots__`, this will\nimpact the memory layout of instances of that class. Multiple inheritance\nfrom more than one different class defining non-empty `__slots__` is not\nallowed:\n\n```python\nclass A:\n __slots__ = (\"a\", \"b\")\n\nclass B:\n __slots__ = (\"a\", \"b\") # Even if the values are the same\n\n# TypeError: multiple bases have instance lay-out conflict\nclass C(A, B): ...\n```\n\nAn instance layout conflict can also be caused by attempting to use\nmultiple inheritance with two builtin classes, due to the way that these\nclasses are implemented in a CPython C extension:\n\n```python\nclass A(int, float): ... # TypeError: multiple bases have instance lay-out conflict\n```\n\nNote that pure-Python classes with no `__slots__`, or pure-Python classes\nwith empty `__slots__`, are always compatible:\n\n```python\nclass A: ...\nclass B:\n __slots__ = ()\nclass C:\n __slots__ = (\"a\", \"b\")\n\n# fine\nclass D(A, B, C): ...\n```\n\n## Known problems\nClasses that have \"dynamic\" definitions of `__slots__` (definitions do not consist\nof string literals, or tuples of string literals) are not currently considered disjoint\nbases by ty.\n\nAdditionally, this check is not exhaustive: many C extensions (including several in\nthe standard library) define classes that use extended memory layouts and thus cannot\ncoexist in a single MRO. Since it is currently not possible to represent this fact in\nstub files, having a full knowledge of these classes is also impossible. When it comes\nto classes that do not define `__slots__` at the Python level, therefore, ty, currently\nonly hard-codes a number of cases where it knows that a class will produce instances with\nan atypical memory layout.\n\n## Further reading\n- [CPython documentation: `__slots__`](https://docs.python.org/3/reference/datamodel.html#slots)\n- [CPython documentation: Method Resolution Order](https://docs.python.org/3/glossary.html#term-method-resolution-order)\n\n[Method Resolution Order]: https://docs.python.org/3/glossary.html#term-method-resolution-order", |
|
582 | 602 | } |
583 | 603 | ] |
584 | 604 | }, |
| 605 | + "invalid-dataclass": { |
| 606 | + "title": "detects invalid `@dataclass` applications", |
| 607 | + "description": "## What it does\nChecks for invalid applications of the `@dataclass` decorator.\n\n## Why is this bad?\nApplying `@dataclass` to a class that inherits from `NamedTuple`, `TypedDict`,\n`Enum`, or `Protocol` is invalid:\n\n- `NamedTuple` and `TypedDict` classes will raise an exception at runtime when\n instantiating the class.\n- `Enum` classes with `@dataclass` are [explicitly not supported].\n- `Protocol` classes define interfaces and cannot be instantiated.\n\n## Examples\n```python\nfrom dataclasses import dataclass\nfrom typing import NamedTuple\n\n@dataclass # error: [invalid-dataclass]\nclass Foo(NamedTuple):\n x: int\n```\n\n[explicitly not supported]: https://docs.python.org/3/howto/enum.html#dataclass-support", |
| 608 | + "default": "error", |
| 609 | + "oneOf": [ |
| 610 | + { |
| 611 | + "$ref": "#/definitions/Level" |
| 612 | + } |
| 613 | + ] |
| 614 | + }, |
| 615 | + "invalid-dataclass-override": { |
| 616 | + "title": "detects dataclasses with `frozen=True` that have a custom `__setattr__` or `__delattr__` implementation", |
| 617 | + "description": "## What it does\nChecks for dataclass definitions that have both `frozen=True` and a custom `__setattr__` or\n`__delattr__` method defined.\n\n## Why is this bad?\nFrozen dataclasses synthesize `__setattr__` and `__delattr__` methods which raise a\n`FrozenInstanceError` to emulate immutability.\n\nOverriding either of these methods raises a runtime error.\n\n## Examples\n```python\nfrom dataclasses import dataclass\n\n@dataclass(frozen=True)\nclass A:\n def __setattr__(self, name: str, value: object) -> None: ...\n```", |
| 618 | + "default": "error", |
| 619 | + "oneOf": [ |
| 620 | + { |
| 621 | + "$ref": "#/definitions/Level" |
| 622 | + } |
| 623 | + ] |
| 624 | + }, |
585 | 625 | "invalid-declaration": { |
586 | 626 | "title": "detects invalid declarations", |
587 | 627 | "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", |
|
632 | 672 | } |
633 | 673 | ] |
634 | 674 | }, |
| 675 | + "invalid-generic-enum": { |
| 676 | + "title": "detects generic enum classes", |
| 677 | + "description": "## What it does\nChecks for enum classes that are also generic.\n\n## Why is this bad?\nEnum classes cannot be generic. Python does not support generic enums:\nattempting to create one will either result in an immediate `TypeError`\nat runtime, or will create a class that cannot be specialized in the way\nthat a normal generic class can.\n\n## Examples\n```python\nfrom enum import Enum\nfrom typing import Generic, TypeVar\n\nT = TypeVar(\"T\")\n\n# error: enum class cannot be generic (class creation fails with `TypeError`)\nclass E[T](Enum):\n A = 1\n\n# error: enum class cannot be generic (class creation fails with `TypeError`)\nclass F(Enum, Generic[T]):\n A = 1\n\n# error: enum class cannot be generic -- the class creation does not immediately fail...\nclass G(Generic[T], Enum):\n A = 1\n\n# ...but this raises `KeyError`:\nx: G[int]\n```\n\n## References\n- [Python documentation: Enum](https://docs.python.org/3/library/enum.html)", |
| 678 | + "default": "error", |
| 679 | + "oneOf": [ |
| 680 | + { |
| 681 | + "$ref": "#/definitions/Level" |
| 682 | + } |
| 683 | + ] |
| 684 | + }, |
635 | 685 | "invalid-ignore-comment": { |
636 | 686 | "title": "detects ignore comments that use invalid syntax", |
637 | 687 | "description": "## What it does\nChecks for `type: ignore` and `ty: ignore` comments that are syntactically incorrect.\n\n## Why is this bad?\nA syntactically incorrect ignore comment is probably a mistake and is useless.\n\n## Examples\n```py\na = 20 / 0 # type: ignoree\n```\n\nUse instead:\n\n```py\na = 20 / 0 # type: ignore\n```", |
|
1152 | 1202 | } |
1153 | 1203 | ] |
1154 | 1204 | }, |
| 1205 | + "unsupported-dynamic-base": { |
| 1206 | + "title": "detects dynamic class bases that are unsupported as ty could not feasibly calculate the class's MRO", |
| 1207 | + "description": "## What it does\nChecks for dynamic class definitions (using `type()`) that have bases\nwhich are unsupported by ty.\n\nThis is equivalent to [`unsupported-base`] but applies to classes created\nvia `type()` rather than `class` statements.\n\n## Why is this bad?\nIf a dynamically created class has a base that is an unsupported type\nsuch as `type[T]`, ty will not be able to resolve the\n[method resolution order] (MRO) for the class. This may lead to an inferior\nunderstanding of your codebase and unpredictable type-checking behavior.\n\n## Default level\nThis rule is disabled by default because it will not cause a runtime error,\nand may be noisy on codebases that use `type()` in highly dynamic ways.\n\n## Examples\n```python\ndef factory(base: type[Base]) -> type:\n # `base` has type `type[Base]`, not `type[Base]` itself\n return type(\"Dynamic\", (base,), {}) # error: [unsupported-dynamic-base]\n```\n\n[method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order\n[`unsupported-base`]: https://docs.astral.sh/ty/rules/unsupported-base", |
| 1208 | + "default": "ignore", |
| 1209 | + "oneOf": [ |
| 1210 | + { |
| 1211 | + "$ref": "#/definitions/Level" |
| 1212 | + } |
| 1213 | + ] |
| 1214 | + }, |
1155 | 1215 | "unsupported-operator": { |
1156 | 1216 | "title": "detects binary, unary, or comparison expressions where the operands don't support the operator", |
1157 | 1217 | "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```", |
|
1163 | 1223 | ] |
1164 | 1224 | }, |
1165 | 1225 | "unused-ignore-comment": { |
1166 | | - "title": "detects unused `type: ignore` comments", |
1167 | | - "description": "## What it does\nChecks for `type: ignore` or `ty: ignore` directives that are no longer applicable.\n\n## Why is this bad?\nA `type: ignore` directive that no longer matches any diagnostic violations is likely\nincluded by mistake, and should be removed to avoid confusion.\n\n## Examples\n```py\na = 20 / 2 # ty: ignore[division-by-zero]\n```\n\nUse instead:\n\n```py\na = 20 / 2\n```", |
1168 | | - "default": "ignore", |
| 1226 | + "title": "detects unused `ty: ignore` and `type: ignore` comments", |
| 1227 | + "description": "## What it does\nChecks for `ty: ignore` or `type: ignore` directives that are no longer applicable.\n\n## Why is this bad?\nA `ty: ignore` directive that no longer matches any diagnostic violations is likely\nincluded by mistake, and should be removed to avoid confusion.\n\n## Examples\n```py\na = 20 / 2 # ty: ignore[division-by-zero]\n```\n\nUse instead:\n\n```py\na = 20 / 2\n```\n\n## Options\nSet [`analysis.respect-type-ignore-comments`](https://docs.astral.sh/ty/reference/configuration/#respect-type-ignore-comments)\nto `false` to prevent this rule from reporting unused `type: ignore` comments.", |
| 1228 | + "default": "warn", |
1169 | 1229 | "oneOf": [ |
1170 | 1230 | { |
1171 | 1231 | "$ref": "#/definitions/Level" |
|
0 commit comments