diff --git a/CHANGELOG.md b/CHANGELOG.md index 46fdc3fc0..ba149c704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## 0.0.32 + +Released on 2026-04-20. + +### Bug fixes + +- Fix panic when `__get__` uses `Concatenate` `self`-type and wraps a `__call__` ([#24692](https://github.com/astral-sh/ruff/pull/24692)) +- Avoid panicking on overloaded `Callable` type context ([#24661](https://github.com/astral-sh/ruff/pull/24661)) +- Expand class bases in per-base lint checks ([#24695](https://github.com/astral-sh/ruff/pull/24695), [#24699](https://github.com/astral-sh/ruff/pull/24699)) +- Fix stack overflow for binary operator inference involving recursive types ([#24551](https://github.com/astral-sh/ruff/pull/24551)) + +### LSP server + +- Dim out unreachable code in IDEs ([#24580](https://github.com/astral-sh/ruff/pull/24580)) +- Do not suggest argument completion when typing the value of a keyword argument ([#24669](https://github.com/astral-sh/ruff/pull/24669)) +- Retrieve the docstring from the overload implementation if an `@overload`-decorated function has no docstring ([#23920](https://github.com/astral-sh/ruff/pull/23920)) + +### Core type checking + +- Allow `if` statements in TypedDict bodies ([#24702](https://github.com/astral-sh/ruff/pull/24702)) +- Disallow `@disjoint_base` on TypedDicts and Protocols ([#24671](https://github.com/astral-sh/ruff/pull/24671)) +- Do not consider a subclass of a `@dataclass_transform`-decorated class to have dataclass-like semantics if it has `type` in its MRO ([#24679](https://github.com/astral-sh/ruff/pull/24679)) +- Reject using properties with `Never` setters or deleters ([#24510](https://github.com/astral-sh/ruff/pull/24510)) +- Sync vendored typeshed stubs ([#24646](https://github.com/astral-sh/ruff/pull/24646)). [Typeshed diff](https://github.com/python/typeshed/compare/f8f0794d0fe249c06dc9f31a004d85be6cca6ced...c03c2b926422c82ab680d27f3ad2491845000802) + +### Diagnostics + +- Show error context for assignability diagnostics ([#24309](https://github.com/astral-sh/ruff/pull/24309)) +- Use partially qualified names when reporting diagnostics regarding bad calls to methods ([#24560](https://github.com/astral-sh/ruff/pull/24560)) +- Reduce source code context window to zero ([#24689](https://github.com/astral-sh/ruff/pull/24689)) +- Merge same-file annotations if there is only a single line separating them ([#24694](https://github.com/astral-sh/ruff/pull/24694)) + +### Performance + +- Memoize binary operator return types ([#24700](https://github.com/astral-sh/ruff/pull/24700)) +- Gate protocol compatibility on member count ([#24684](https://github.com/astral-sh/ruff/pull/24684)) + +### Contributors + +- [@JelleZijlstra](https://github.com/JelleZijlstra) +- [@kc0506](https://github.com/kc0506) +- [@denyszhak](https://github.com/denyszhak) +- [@carljm](https://github.com/carljm) +- [@dcreager](https://github.com/dcreager) +- [@AlexWaygood](https://github.com/AlexWaygood) +- [@dylwil3](https://github.com/dylwil3) +- [@charliermarsh](https://github.com/charliermarsh) +- [@sharkdp](https://github.com/sharkdp) +- [@ibraheemdev](https://github.com/ibraheemdev) + ## 0.0.31 Released on 2026-04-15. diff --git a/dist-workspace.toml b/dist-workspace.toml index 0d7bb2020..9cca479b5 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -1,7 +1,7 @@ [workspace] members = ["cargo:./ruff"] packages = ["ty"] -version = "0.0.31" +version = "0.0.32" # Config for 'dist' [dist] diff --git a/docs/installation.md b/docs/installation.md index b8de2c1bc..50375868d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -71,7 +71,7 @@ ty includes a standalone installer. Request a specific version by including it in the URL: ```console - $ curl -LsSf https://astral.sh/ty/0.0.31/install.sh | sh + $ curl -LsSf https://astral.sh/ty/0.0.32/install.sh | sh ``` === "Windows" @@ -87,7 +87,7 @@ ty includes a standalone installer. Request a specific version by including it in the URL: ```pwsh-session - PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/ty/0.0.31/install.ps1 | iex" + PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/ty/0.0.32/install.ps1 | iex" ``` !!! tip @@ -163,7 +163,7 @@ COPY --from=ghcr.io/astral-sh/ty:latest /ty /bin/ The following tags are available: - `ghcr.io/astral-sh/ty:latest` -- `ghcr.io/astral-sh/ty:{major}.{minor}.{patch}`, e.g., `ghcr.io/astral-sh/ty:0.0.31` +- `ghcr.io/astral-sh/ty:{major}.{minor}.{patch}`, e.g., `ghcr.io/astral-sh/ty:0.0.32` - `ghcr.io/astral-sh/ty:{major}.{minor}`, e.g., `ghcr.io/astral-sh/ty:0.0` (the latest patch version) diff --git a/docs/reference/rules.md b/docs/reference/rules.md index 08ad691f7..1c28473a8 100644 --- a/docs/reference/rules.md +++ b/docs/reference/rules.md @@ -8,7 +8,7 @@ Default level: error · Added in 0.0.13 · Related issues · -View source +View source @@ -49,7 +49,7 @@ class Derived(Base): # Error: `Derived` does not implement `method` Default level: warn · Added in 0.0.1-alpha.20 · Related issues · -View source +View source @@ -90,7 +90,7 @@ class SubProto(BaseProto, Protocol): Default level: error · Added in 0.0.14 · Related issues · -View source +View source @@ -126,7 +126,7 @@ def _(x: int): Default level: error · Preview (since 0.0.16) · Related issues · -View source +View source @@ -175,7 +175,7 @@ Foo.method() # Error: cannot call abstract classmethod Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -199,7 +199,7 @@ Calling a non-callable object will raise a `TypeError` at runtime. Default level: error · Added in 0.0.7 · Related issues · -View source +View source @@ -230,7 +230,7 @@ def f(x: object): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -262,7 +262,7 @@ f(int) # error Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -293,7 +293,7 @@ a = 1 Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -325,7 +325,7 @@ class C(A, B): ... Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -357,7 +357,7 @@ class B(A): ... Default level: error · Added in 0.0.1-alpha.29 · Related issues · -View source +View source @@ -385,7 +385,7 @@ type B = A Default level: error · Added in 0.0.15 · Related issues · -View source +View source @@ -417,7 +417,7 @@ class Example: Default level: warn · Added in 0.0.1-alpha.16 · Related issues · -View source +View source @@ -444,7 +444,7 @@ old_func() # emits [deprecated] diagnostic Default level: ignore · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -473,7 +473,7 @@ false positives it can produce. Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -500,7 +500,7 @@ class B(A, A): ... Default level: error · Added in 0.0.1-alpha.12 · Related issues · -View source +View source @@ -538,7 +538,7 @@ class A: # Crash at runtime Default level: error · Added in 0.0.14 · Related issues · -View source +View source @@ -609,7 +609,7 @@ def foo() -> "intt\b": ... Default level: error · Added in 0.0.20 · Related issues · -View source +View source @@ -641,7 +641,7 @@ def my_function() -> int: Default level: error · Added in 0.0.15 · Related issues · -View source +View source @@ -736,7 +736,7 @@ def test(): -> "Literal[5]": Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -766,7 +766,7 @@ class C(A, B): ... Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -792,7 +792,7 @@ t[3] # IndexError: tuple index out of range Default level: warn · Added in 0.0.1-alpha.33 · Related issues · -View source +View source @@ -826,7 +826,7 @@ class MyClass: ... Default level: error · Added in 0.0.1-alpha.12 · Related issues · -View source +View source @@ -915,7 +915,7 @@ an atypical memory layout. Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -942,7 +942,7 @@ func("foo") # error: [invalid-argument-type] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -970,7 +970,7 @@ a: int = '' Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1004,7 +1004,7 @@ C.instance_var = 3 # error: Cannot assign to instance variable Default level: error · Added in 0.0.1-alpha.19 · Related issues · -View source +View source @@ -1040,7 +1040,7 @@ asyncio.run(main()) Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1064,7 +1064,7 @@ class A(42): ... # error: [invalid-base] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1091,7 +1091,7 @@ with 1: Default level: error · Added in 0.0.12 · Related issues · -View source +View source @@ -1128,7 +1128,7 @@ class Foo(NamedTuple): Default level: error · Added in 0.0.13 · Related issues · -View source +View source @@ -1160,7 +1160,7 @@ class A: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1189,7 +1189,7 @@ a: str Default level: warn · Added in 0.0.20 · Related issues · -View source +View source @@ -1238,7 +1238,7 @@ class Pet(Enum): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1282,7 +1282,7 @@ except ZeroDivisionError: Default level: error · Added in 0.0.1-alpha.28 · Related issues · -View source +View source @@ -1324,7 +1324,7 @@ class D(A): Default level: error · Added in 0.0.1-alpha.35 · Related issues · -View source +View source @@ -1368,7 +1368,7 @@ class NonFrozenChild(FrozenBase): # Error raised here Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1406,7 +1406,7 @@ class D(Generic[U, T]): ... Default level: error · Added in 0.0.12 · Related issues · -View source +View source @@ -1485,7 +1485,7 @@ a = 20 / 0 # type: ignore Default level: error · Added in 0.0.1-alpha.17 · Related issues · -View source +View source @@ -1524,7 +1524,7 @@ carol = Person(name="Carol", aeg=25) # typo! Default level: warn · Added in 0.0.15 · Related issues · -View source +View source @@ -1585,7 +1585,7 @@ def f(x, y, /): # Python 3.8+ syntax Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1620,7 +1620,7 @@ def f(t: TypeVar("U")): ... Default level: error · Added in 0.0.18 · Related issues · -View source +View source @@ -1648,7 +1648,7 @@ match x: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1682,7 +1682,7 @@ class B(metaclass=f): ... Default level: error · Added in 0.0.1-alpha.20 · Related issues · -View source +View source @@ -1789,7 +1789,7 @@ Correct use of `@override` is enforced by ty's [`invalid-explicit-override`](#in Default level: error · Added in 0.0.1-alpha.19 · Related issues · -View source +View source @@ -1843,7 +1843,7 @@ AttributeError: Cannot overwrite NamedTuple attribute _asdict Default level: warn · Added in 0.0.31 · Related issues · -View source +View source @@ -1884,7 +1884,7 @@ admin[0] # "Alice" Default level: error · Added in 0.0.1-alpha.27 · Related issues · -View source +View source @@ -1914,7 +1914,7 @@ Baz = NewType("Baz", int | str) # error: invalid base for `typing.NewType` Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1964,7 +1964,7 @@ def foo(x: int) -> int: ... Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -1990,7 +1990,7 @@ def f(a: int = ''): ... Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2021,7 +2021,7 @@ P2 = ParamSpec("S2") # error: ParamSpec name must match the variable it's assig Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2055,7 +2055,7 @@ TypeError: Protocols can only inherit from other protocols, got Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2104,7 +2104,7 @@ def g(): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2133,7 +2133,7 @@ def func() -> int: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2229,7 +2229,7 @@ class C: ... Default level: error · Added in 0.0.10 · Related issues · -View source +View source @@ -2275,7 +2275,7 @@ class MyClass: Default level: error · Added in 0.0.1-alpha.6 · Related issues · -View source +View source @@ -2302,7 +2302,7 @@ NewAlias = TypeAliasType(get_name(), int) # error: TypeAliasType name mus Default level: error · Added in 0.0.1-alpha.29 · Related issues · -View source +View source @@ -2349,7 +2349,7 @@ Bar[int] # error: too few arguments Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2379,7 +2379,7 @@ TYPE_CHECKING = '' Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2409,7 +2409,7 @@ b: Annotated[int] # `Annotated` expects at least two arguments Default level: error · Added in 0.0.1-alpha.11 · Related issues · -View source +View source @@ -2443,7 +2443,7 @@ f(10) # Error Default level: error · Added in 0.0.1-alpha.11 · Related issues · -View source +View source @@ -2477,7 +2477,7 @@ class C: Default level: error · Added in 0.0.15 · Related issues · -View source +View source @@ -2508,7 +2508,7 @@ def g[U, T: U](): ... # error: [invalid-type-variable-bound] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2555,7 +2555,7 @@ U = TypeVar('U', list[int], int) # valid constrained Type Default level: error · Added in 0.0.16 · Related issues · -View source +View source @@ -2587,7 +2587,7 @@ U = TypeVar("U", int, str, default=bytes) # error: [invalid-type-variable-defau Default level: error · Added in 0.0.28 · Related issues · -View source +View source @@ -2618,7 +2618,7 @@ class Child(Base): Default level: error · Added in 0.0.14 · Related issues · -View source +View source @@ -2653,7 +2653,7 @@ def f(x: dict): Default level: error · Added in 0.0.9 · Related issues · -View source +View source @@ -2684,7 +2684,7 @@ class Foo(TypedDict): Default level: error · Added in 0.0.25 · Related issues · -View source +View source @@ -2715,7 +2715,7 @@ def gen() -> Iterator[int]: Default level: error · Added in 0.0.14 · Related issues · -View source +View source @@ -2770,7 +2770,7 @@ def h(arg2: type): Default level: error · Added in 0.0.15 · Related issues · -View source +View source @@ -2813,7 +2813,7 @@ def g(arg: object): Default level: warn · Added in 0.0.30 · Related issues · -View source +View source @@ -2851,7 +2851,7 @@ Movie = TypedDict("Film", {"title": str}) # error: [mismatched-type-name] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2876,7 +2876,7 @@ func() # TypeError: func() missing 1 required positional argument: 'x' Default level: error · Added in 0.0.1-alpha.20 · Related issues · -View source +View source @@ -2909,7 +2909,7 @@ alice["age"] # KeyError Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2938,7 +2938,7 @@ func("string") # error: [no-matching-overload] Default level: error · Added in 0.0.30 · Related issues · -View source +View source @@ -2971,7 +2971,7 @@ class Sub(Super): ... # error: [non-callable-init-subclass] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -2997,7 +2997,7 @@ for i in 34: # TypeError: 'int' object is not iterable Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3021,7 +3021,7 @@ Subscripting an object that does not support it will raise a `TypeError` at runt Default level: error · Added in 0.0.1-alpha.29 · Related issues · -View source +View source @@ -3054,7 +3054,7 @@ class B(A): Default level: error · Added in 0.0.16 · Related issues · -View source +View source @@ -3087,7 +3087,7 @@ class B(A): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3114,7 +3114,7 @@ f(1, x=2) # Error raised here Default level: error · Added in 0.0.1-alpha.22 · Related issues · -View source +View source @@ -3141,7 +3141,7 @@ f(x=1) # Error raised here Default level: ignore · Added in 0.0.1-alpha.22 · Related issues · -View source +View source @@ -3174,7 +3174,7 @@ A.c # AttributeError: type object 'A' has no attribute 'c' Default level: warn · Added in 0.0.1-alpha.22 · Related issues · -View source +View source @@ -3206,7 +3206,7 @@ A()[0] # TypeError: 'A' object is not subscriptable Default level: ignore · Added in 0.0.1-alpha.22 · Related issues · -View source +View source @@ -3243,7 +3243,7 @@ from module import a # ImportError: cannot import name 'a' from 'module' Default level: warn · Added in 0.0.23 · Related issues · -View source +View source @@ -3270,7 +3270,7 @@ html.parser # AttributeError: module 'html' has no attribute 'parser' Default level: ignore · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3334,7 +3334,7 @@ def test(): -> "int": Default level: warn · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3361,7 +3361,7 @@ cast(int, f()) # Redundant Default level: warn · Added in 0.0.18 · Related issues · -View source +View source @@ -3393,7 +3393,7 @@ class C: Default level: error · Added in 0.0.20 · Related issues · -View source +View source @@ -3427,7 +3427,7 @@ class Outer[T]: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3457,7 +3457,7 @@ static_assert(int(2.0 * 3.0) == 6) # error: does not have a statically known tr Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3486,7 +3486,7 @@ class B(A): ... # Error raised here Default level: error · Added in 0.0.1-alpha.30 · Related issues · -View source +View source @@ -3520,7 +3520,7 @@ class F(NamedTuple): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3547,7 +3547,7 @@ f("foo") # Error raised here Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3575,7 +3575,7 @@ def _(x: int): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3621,7 +3621,7 @@ class A: Default level: error · Added in 0.0.20 · Related issues · -View source +View source @@ -3658,7 +3658,7 @@ class C(Generic[T]): Default level: warn · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3682,7 +3682,7 @@ reveal_type(1) # NameError: name 'reveal_type' is not defined Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3709,7 +3709,7 @@ f(x=1, y=2) # Error raised here Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3737,7 +3737,7 @@ A().foo # AttributeError: 'A' object has no attribute 'foo' Default level: warn · Added in 0.0.1-alpha.15 · Related issues · -View source +View source @@ -3795,7 +3795,7 @@ def g(): Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3820,7 +3820,7 @@ import foo # ModuleNotFoundError: No module named 'foo' Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3845,7 +3845,7 @@ print(x) # NameError: name 'x' is not defined Default level: warn · Added in 0.0.1-alpha.7 · Related issues · -View source +View source @@ -3884,7 +3884,7 @@ class D(C): ... # error: [unsupported-base] Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3921,7 +3921,7 @@ b1 < b2 < b1 # exception raised here Default level: ignore · Added in 0.0.12 · Related issues · -View source +View source @@ -3961,7 +3961,7 @@ def factory(base: type[Base]) -> type: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source @@ -3989,7 +3989,7 @@ A() + A() # TypeError: unsupported operand type(s) for +: 'A' and 'A' Default level: warn · Preview (since 0.0.21) · Related issues · -View source +View source @@ -4095,7 +4095,7 @@ to `false`. Default level: warn · Added in 0.0.1-alpha.22 · Related issues · -View source +View source @@ -4158,7 +4158,7 @@ def foo(x: int | str) -> int | str: Default level: error · Added in 0.0.1-alpha.1 · Related issues · -View source +View source diff --git a/pyproject.toml b/pyproject.toml index 72b9edbc3..d8a0aa7a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ty" -version = "0.0.31" +version = "0.0.32" requires-python = ">=3.8" dependencies = [] description = "An extremely fast Python type checker, written in Rust." diff --git a/ruff b/ruff index ee9088eeb..3e9ed60c7 160000 --- a/ruff +++ b/ruff @@ -1 +1 @@ -Subproject commit ee9088eebf068f4b3a14f5ee34607f72d3513186 +Subproject commit 3e9ed60c72ae05871879ac56e7dd4666cfda93a3 diff --git a/uv.lock b/uv.lock index c3f43991d..a221810fb 100644 --- a/uv.lock +++ b/uv.lock @@ -624,7 +624,7 @@ wheels = [ [[package]] name = "ty" -version = "0.0.31" +version = "0.0.32" source = { editable = "." } [package.dev-dependencies]