From 82ad8908c149a7cbaf3ce7b9d7697ea10ddce7ae Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 16 Mar 2026 23:44:16 +0100 Subject: [PATCH 1/8] Allow errors for unsound Self definitions on non-final classes --- conformance/tests/generics_self_advanced.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/conformance/tests/generics_self_advanced.py b/conformance/tests/generics_self_advanced.py index ab389081..e26ed667 100644 --- a/conformance/tests/generics_self_advanced.py +++ b/conformance/tests/generics_self_advanced.py @@ -40,6 +40,9 @@ def method2(self) -> None: @classmethod def method3(cls) -> None: assert_type(cls, type[Self]) - assert_type(cls.a, list[Self]) - assert_type(cls.a[0], Self) + # Allow type checkers to error here, since Self definitions on + # non-final classes are unsound. + a = cls.a # E? + assert_type(a, list[Self]) + assert_type(a[0], Self) assert_type(cls.method1(), Self) From 41d15d50264b596a1ac9066d5f2112e360c4c5b5 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 30 Mar 2026 14:57:49 +0200 Subject: [PATCH 2/8] Update zuban and run results --- conformance/results/results.html | 8 ++++---- .../results/zuban/dataclasses_hash.toml | 18 +++++++----------- .../results/zuban/generics_self_advanced.toml | 11 ++--------- .../results/zuban/typeforms_typeform.toml | 8 +------- conformance/results/zuban/version.toml | 2 +- 5 files changed, 15 insertions(+), 32 deletions(-) diff --git a/conformance/results/results.html b/conformance/results/results.html index 2c21be32..50efb127 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -176,7 +176,7 @@

Python Type System Conformance Test Results

pyright 1.1.408
-
zuban 0.6.1
+
zuban 0.6.2
pyrefly 0.56.0
@@ -227,7 +227,7 @@

Python Type System Conformance Test Results

     typeforms_typeform
Partial

Does not support assigning Union and GenericAlias objects to their runtime types.

Unsupported -
Partial

TypeForm[Any] is not considered equivalent to itself.

+Pass Unsupported Unsupported @@ -345,7 +345,7 @@

Python Type System Conformance Test Results

     generics_self_advanced
Partial

Does not infer the type of an unannotated `self` parameter to be type `Self`.

Does not retain `Self` when calling method that returns `Self`.

Does not infer the type of an unannotated `cls` parameter to be type `type[Self]`.

Does not retain `Self` when accessing attribute through `type[Self]`.

Pass -
Partial

Doesn't allow accessing `Self` in a classmethod

+Pass
Pass*

Treats attributes not initialized on the class as instance-only

Pass @@ -837,7 +837,7 @@

Python Type System Conformance Test Results

     dataclasses_hash
Unsupported

Does not synthesize `__hash__ = None` as a class attribute for unhashable dataclasses.

Does not report when an unhashable dataclass has `__hash__` called directly on an instance.

Does not report when dataclass is not compatible with Hashable protocol.

Pass -
Partial

Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses.

+Pass Pass
Partial

Understands the `Hashable` protocol as equivalent to `object`.

diff --git a/conformance/results/zuban/dataclasses_hash.toml b/conformance/results/zuban/dataclasses_hash.toml index 52f7a8fa..05447588 100644 --- a/conformance/results/zuban/dataclasses_hash.toml +++ b/conformance/results/zuban/dataclasses_hash.toml @@ -1,17 +1,13 @@ -conformance_automated = "Fail" -conformant = "Partial" -notes = """ -Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses. -""" +conformance_automated = "Pass" errors_diff = """ -Line 14: Unexpected errors ['dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] -Line 36: Unexpected errors ['dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] """ output = """ -dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc] -dataclasses_hash.py:17: error: "DC1" has no attribute "__hash__" [attr-defined] +dataclasses_hash.py:17: error: "None" not callable [operator] dataclasses_hash.py:18: error: Incompatible types in assignment (expression has type "DC1", variable has type "Hashable") [assignment] -dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc] -dataclasses_hash.py:39: error: "DC3" has no attribute "__hash__" [attr-defined] +dataclasses_hash.py:18: note: Following member(s) of "DC1" have conflicts: +dataclasses_hash.py:18: note: __hash__: expected "Callable[[], int]", got "None" +dataclasses_hash.py:39: error: "None" not callable [operator] dataclasses_hash.py:40: error: Incompatible types in assignment (expression has type "DC3", variable has type "Hashable") [assignment] +dataclasses_hash.py:40: note: Following member(s) of "DC3" have conflicts: +dataclasses_hash.py:40: note: __hash__: expected "Callable[[], int]", got "None" """ diff --git a/conformance/results/zuban/generics_self_advanced.toml b/conformance/results/zuban/generics_self_advanced.toml index a6a7caad..89efb221 100644 --- a/conformance/results/zuban/generics_self_advanced.toml +++ b/conformance/results/zuban/generics_self_advanced.toml @@ -1,13 +1,6 @@ -conformant = "Partial" -notes = """ -Doesn't allow accessing `Self` in a classmethod -""" -conformance_automated = "Fail" +conformance_automated = "Pass" errors_diff = """ -Line 43: Unexpected errors ['generics_self_advanced.py:43: error: Access to generic instance variables via class is ambiguous [misc]'] -Line 44: Unexpected errors ['generics_self_advanced.py:44: error: Access to generic instance variables via class is ambiguous [misc]'] """ output = """ -generics_self_advanced.py:43: error: Access to generic instance variables via class is ambiguous [misc] -generics_self_advanced.py:44: error: Access to generic instance variables via class is ambiguous [misc] +generics_self_advanced.py:45: error: Access to generic instance variables via class is ambiguous [misc] """ diff --git a/conformance/results/zuban/typeforms_typeform.toml b/conformance/results/zuban/typeforms_typeform.toml index 5c7da90b..67d99387 100644 --- a/conformance/results/zuban/typeforms_typeform.toml +++ b/conformance/results/zuban/typeforms_typeform.toml @@ -1,15 +1,9 @@ -conformant = "Partial" -notes = """ -TypeForm[Any] is not considered equivalent to itself. -""" -conformance_automated = "Fail" +conformance_automated = "Pass" errors_diff = """ -Line 41: Unexpected errors ['typeforms_typeform.py:41: error: Expression is of type "typing.TypeForm(Any)", not "typing.TypeForm(Any)" [misc]'] """ output = """ typeforms_typeform.py:23: error: Incompatible types in assignment (expression has type "typing.TypeForm(str | int)", variable has type "typing.TypeForm(str | None)") [assignment] typeforms_typeform.py:24: error: Incompatible types in assignment (expression has type "type[list[str | None]]", variable has type "typing.TypeForm(str | None)") [assignment] -typeforms_typeform.py:41: error: Expression is of type "typing.TypeForm(Any)", not "typing.TypeForm(Any)" [misc] typeforms_typeform.py:59: error: Invalid syntax [syntax] typeforms_typeform.py:67: error: Invalid type comment or annotation [valid-type] typeforms_typeform.py:68: error: Syntax error in type annotation [valid-type] diff --git a/conformance/results/zuban/version.toml b/conformance/results/zuban/version.toml index edcd1bf5..fe45d003 100644 --- a/conformance/results/zuban/version.toml +++ b/conformance/results/zuban/version.toml @@ -1 +1 @@ -version = "zuban 0.6.1" +version = "zuban 0.6.2" From cd0cee630da68ca69724e1b6ac5fff1b3d8d42d1 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 30 Mar 2026 15:08:48 +0200 Subject: [PATCH 3/8] Upgrade zuban in uv lock --- conformance/uv.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/conformance/uv.lock b/conformance/uv.lock index 8f158171..3bcec030 100644 --- a/conformance/uv.lock +++ b/conformance/uv.lock @@ -187,19 +187,19 @@ wheels = [ [[package]] name = "zuban" -version = "0.6.1" +version = "0.6.2" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/91/2e3f5f095ff45c8052e320b99359ec03b266df1eedd3ea4ab4a2d68b134d/zuban-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bf3ed1b85cedafaf51e51527bdc2ae089db121546aaa96a252beb0708a7f4306", size = 11186573, upload-time = "2026-02-25T02:04:49.434Z" }, - { url = "https://files.pythonhosted.org/packages/77/44/fc318d17c500ba0b1733b8d661d33acb117aaf6b20d9e2a74ce7a33de18d/zuban-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e9e310e27eaa6c2184f3b50fbea6cd3cc0776549868837145d3156352156bb6c", size = 10925136, upload-time = "2026-02-25T02:04:52.562Z" }, - { url = "https://files.pythonhosted.org/packages/46/86/56a04bea43584b01d438b943bf1501b33a71db746183ab9b5cfa3818a2de/zuban-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1d78ad0af5b4b44d4201e1f1add0b5495da813593b57ecfb39a5a526f998602", size = 27757976, upload-time = "2026-02-25T02:04:56.017Z" }, - { url = "https://files.pythonhosted.org/packages/83/9f/c5cd3d5c130603116b1614e013a1feac2ee7a804622aa5830a35d97b1dc5/zuban-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a9d86ac6f23cf020978a94e47054af92ac3c26a7f884c27eb4fb28361a907bd6", size = 27883668, upload-time = "2026-02-25T02:04:59.839Z" }, - { url = "https://files.pythonhosted.org/packages/f8/09/5da69bc26fdce24b1a89c0e35d7134cd60960374e7aa48851b2d989447ad/zuban-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66ede8809b0231b050d543004ac27dd031dc9053839337006fad18157e3e5440", size = 29237524, upload-time = "2026-02-25T02:05:03.86Z" }, - { url = "https://files.pythonhosted.org/packages/d3/6d/a7b8a8531495e64e27a8c4a25bfd7865f7d94c82c1d549c103bc5bf3bbc1/zuban-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:859e8917ed579e9018de6f6e4bb8a2ec6204df95bcf9ff9165c3067257ff3f05", size = 30224734, upload-time = "2026-02-25T02:05:07.586Z" }, - { url = "https://files.pythonhosted.org/packages/04/9a/0b963861ea2e594ab3669245825dde90ff3a25d6a916a48007be3b0f7db9/zuban-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a07738374ddfca72fdf925cd275a3216a6fe8373bf91b49931c1c9f87561b729", size = 28034025, upload-time = "2026-02-25T02:05:12.99Z" }, - { url = "https://files.pythonhosted.org/packages/21/5d/5c588e77087fc649e84b409ac11c8b8ba48ee49a554531647af5b044a6c1/zuban-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:619815ac6cb9f48c9891cd4150cf3bce70a79c9a15fc349a0f860a3d9e44acf9", size = 28484806, upload-time = "2026-02-25T02:05:16.224Z" }, - { url = "https://files.pythonhosted.org/packages/3e/0b/4c67a559c0f9d405ca87685b65b16243e555c1d3c3c613d6fbb284c9b16a/zuban-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f912f2db095e5715b757c31d73cef3509ba6da5ba99295d36b166420e9884992", size = 29355542, upload-time = "2026-02-25T02:05:20.097Z" }, - { url = "https://files.pythonhosted.org/packages/65/a2/8a38a910f40a090effbcc65e0272a7d33b16149b452f74a67b5537ba5f2f/zuban-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80a9f18aa327378846258b06277f9f7bba7127513aa591ad8b9b28bb48f4e3b8", size = 28658304, upload-time = "2026-02-25T02:05:24.106Z" }, - { url = "https://files.pythonhosted.org/packages/1c/50/65a34b02e162845155efea4f393761634f7f39311d3b59249c9c7f3f53f7/zuban-0.6.1-py3-none-win32.whl", hash = "sha256:7737d566cb4202ea5c37e1f03397dcfbd437d1f33e6ee4090a0d2941383531c5", size = 9734143, upload-time = "2026-02-25T02:05:27.409Z" }, - { url = "https://files.pythonhosted.org/packages/37/45/2724c34fa769cf2cb29c9c178166b1689e936f810eb55f799e87a6acb248/zuban-0.6.1-py3-none-win_amd64.whl", hash = "sha256:9494dac40d4a23f92d7833e8fb15e8925e2c5d2561bc4edb18277ff35bea5ac8", size = 10490401, upload-time = "2026-02-25T02:05:29.817Z" }, + { url = "https://files.pythonhosted.org/packages/10/29/2d9f68f875155dfc58cb2542bad9bce60c680bf77b883a17cefd2c7b1399/zuban-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:392a24f4542b36e06b6ea8ff8a66b9bcf073fac380f6fedf5ead6d239a089b1b", size = 11274171, upload-time = "2026-03-16T23:11:13.516Z" }, + { url = "https://files.pythonhosted.org/packages/0f/83/77cf8a9568e21653c79ca6acbd35575ef3bc82251d1f604bb4c32bea98df/zuban-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5637981d19c503325bc2fd24b92af218733ee618de2f5217fa2523ca918b3a88", size = 10985794, upload-time = "2026-03-16T23:11:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/23/22/2f7579439acbea7a28d8bbeb361225ddb9502406a892da9a94e73fadd522/zuban-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8097a716499ff7b3ac927b8e4c5425b9cfff5cd0b4e644a03e24d1a7c625d048", size = 28440118, upload-time = "2026-03-16T23:11:21.496Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/e714bbbf1783b76687a39c1ed7764b96c395221c103be91c0b63a4e249da/zuban-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ecf4b0c0e682f76f6403d68457d9085cc01dbbc56d402d925d931e82b36d9b5f", size = 28715022, upload-time = "2026-03-16T23:11:25.409Z" }, + { url = "https://files.pythonhosted.org/packages/24/b0/cd98c1c2797353a9fd8d10393ba018255e18a23ba47f505a538c32ea923c/zuban-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b1488ed63733d813d9be81b0c2bc888a329b31c4a03cb2cf462c7f0db052fef", size = 29943854, upload-time = "2026-03-16T23:11:29.391Z" }, + { url = "https://files.pythonhosted.org/packages/70/ee/d1ddcf7e7ea098eb33cc1d5b6b38a2688375f27207bdc80929a3abb8251e/zuban-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5b48be20d805b41ac224feeabd1b421a53e55b6cc10f2f3011139c1f625c583", size = 30939082, upload-time = "2026-03-16T23:11:34.003Z" }, + { url = "https://files.pythonhosted.org/packages/fb/45/c477ee9e281a334cfe7cf0375e1cf5e0433e80ade4cc7165ff9a9b756256/zuban-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:14d30ece874c9ca5b99ef57064b778edc834404e9d350af0c54eaf36d7eb6396", size = 28712077, upload-time = "2026-03-16T23:11:37.711Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/a962d8aacaf177356bfd698418d10a12fddd8d1c300e5cbd994ff62f80c2/zuban-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:3c144cd9436d39a3bebe50302c2eb600be403d22a85ae3ef41f061768e96d17e", size = 29336825, upload-time = "2026-03-16T23:11:41.965Z" }, + { url = "https://files.pythonhosted.org/packages/bd/35/09450daba51442632b51b70ef95a94356482fcfdd0127e70ed0f45be2a83/zuban-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ff52b183e752646baea76c0fb1e06e247c47e437d0d37f1386e07504dc2e4c29", size = 30047009, upload-time = "2026-03-16T23:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/a4/73/796d8e3789dadc84020a7a67d65cf13facca9807d40852adae8041032f41/zuban-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0e265fb4c38efc78e4ed79dc1b9b7adb034d70fa51f963c9ac609af1fbe2f855", size = 29316703, upload-time = "2026-03-16T23:11:50.81Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2a/508617bda8277472cf403ecb73ae3b9227820dc2ff2a3a023eaed8512d5b/zuban-0.6.2-py3-none-win32.whl", hash = "sha256:4a129511f9f6080ba7d4153f111b5e6c2214a3eef945730ce466658903c324b8", size = 9742656, upload-time = "2026-03-16T23:11:54.231Z" }, + { url = "https://files.pythonhosted.org/packages/d0/25/dae184c1b6d7fbdc43e906254fef2577d23899669b58de865fcb0fe150f5/zuban-0.6.2-py3-none-win_amd64.whl", hash = "sha256:7db193c8b1456977ca2dfa2291c93a376e17f465a69018a06d0ecc8655464fff", size = 10464125, upload-time = "2026-03-16T23:11:57.267Z" }, ] From ae0d7a1bfcda3f37fc7ccb8a179f7ee47b516157 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 30 Mar 2026 15:10:53 +0200 Subject: [PATCH 4/8] Rerun mypy conformance tests --- conformance/results/mypy/generics_self_advanced.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conformance/results/mypy/generics_self_advanced.toml b/conformance/results/mypy/generics_self_advanced.toml index 92f52334..173c94ff 100644 --- a/conformance/results/mypy/generics_self_advanced.toml +++ b/conformance/results/mypy/generics_self_advanced.toml @@ -9,12 +9,12 @@ output = """ generics_self_advanced.py:35: error: Expression is of type "ChildB", not "Self" [assert-type] generics_self_advanced.py:38: error: Expression is of type "ChildB", not "Self" [assert-type] generics_self_advanced.py:42: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type] -generics_self_advanced.py:45: error: Expression is of type "ChildB", not "Self" [assert-type] +generics_self_advanced.py:48: error: Expression is of type "ChildB", not "Self" [assert-type] """ conformance_automated = "Fail" errors_diff = """ Line 35: Unexpected errors ['generics_self_advanced.py:35: error: Expression is of type "ChildB", not "Self" [assert-type]'] Line 38: Unexpected errors ['generics_self_advanced.py:38: error: Expression is of type "ChildB", not "Self" [assert-type]'] Line 42: Unexpected errors ['generics_self_advanced.py:42: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type]'] -Line 45: Unexpected errors ['generics_self_advanced.py:45: error: Expression is of type "ChildB", not "Self" [assert-type]'] +Line 48: Unexpected errors ['generics_self_advanced.py:48: error: Expression is of type "ChildB", not "Self" [assert-type]'] """ From ac4622f19692014f5eed15ed0e11a7c4e2537588 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 30 Mar 2026 21:44:02 +0200 Subject: [PATCH 5/8] Allow type checkers to generate an error when list[Self] instance variables are accessed --- conformance/results/mypy/generics_self_advanced.toml | 12 ++++++------ .../results/zuban/generics_self_advanced.toml | 2 +- conformance/tests/generics_self_advanced.py | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/conformance/results/mypy/generics_self_advanced.toml b/conformance/results/mypy/generics_self_advanced.toml index 173c94ff..4581356b 100644 --- a/conformance/results/mypy/generics_self_advanced.toml +++ b/conformance/results/mypy/generics_self_advanced.toml @@ -7,14 +7,14 @@ Does not retain `Self` when accessing attribute through `type[Self]`. """ output = """ generics_self_advanced.py:35: error: Expression is of type "ChildB", not "Self" [assert-type] -generics_self_advanced.py:38: error: Expression is of type "ChildB", not "Self" [assert-type] -generics_self_advanced.py:42: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type] -generics_self_advanced.py:48: error: Expression is of type "ChildB", not "Self" [assert-type] +generics_self_advanced.py:41: error: Expression is of type "ChildB", not "Self" [assert-type] +generics_self_advanced.py:45: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type] +generics_self_advanced.py:51: error: Expression is of type "ChildB", not "Self" [assert-type] """ conformance_automated = "Fail" errors_diff = """ Line 35: Unexpected errors ['generics_self_advanced.py:35: error: Expression is of type "ChildB", not "Self" [assert-type]'] -Line 38: Unexpected errors ['generics_self_advanced.py:38: error: Expression is of type "ChildB", not "Self" [assert-type]'] -Line 42: Unexpected errors ['generics_self_advanced.py:42: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type]'] -Line 48: Unexpected errors ['generics_self_advanced.py:48: error: Expression is of type "ChildB", not "Self" [assert-type]'] +Line 41: Unexpected errors ['generics_self_advanced.py:41: error: Expression is of type "ChildB", not "Self" [assert-type]'] +Line 45: Unexpected errors ['generics_self_advanced.py:45: error: Expression is of type "type[ChildB]", not "type[Self]" [assert-type]'] +Line 51: Unexpected errors ['generics_self_advanced.py:51: error: Expression is of type "ChildB", not "Self" [assert-type]'] """ diff --git a/conformance/results/zuban/generics_self_advanced.toml b/conformance/results/zuban/generics_self_advanced.toml index 89efb221..ff36318b 100644 --- a/conformance/results/zuban/generics_self_advanced.toml +++ b/conformance/results/zuban/generics_self_advanced.toml @@ -2,5 +2,5 @@ conformance_automated = "Pass" errors_diff = """ """ output = """ -generics_self_advanced.py:45: error: Access to generic instance variables via class is ambiguous [misc] +generics_self_advanced.py:48: error: Access to generic instance variables via class is ambiguous [misc] """ diff --git a/conformance/tests/generics_self_advanced.py b/conformance/tests/generics_self_advanced.py index e26ed667..acf680c2 100644 --- a/conformance/tests/generics_self_advanced.py +++ b/conformance/tests/generics_self_advanced.py @@ -33,8 +33,11 @@ class ChildB(ParentB): def method2(self) -> None: assert_type(self, Self) - assert_type(self.a, list[Self]) - assert_type(self.a[0], Self) + # Allow type checkers to error here, since Self definitions on + # non-final classes are unsound. + a = self.a # E? + assert_type(a, list[Self]) + assert_type(a[0], Self) assert_type(self.method1(), Self) @classmethod From e42167e57c1e4474a793b3a7cc1140eef357fda9 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 31 Mar 2026 11:09:09 +0200 Subject: [PATCH 6/8] Revert "Upgrade zuban in uv lock" This reverts commit cd0cee630da68ca69724e1b6ac5fff1b3d8d42d1. --- conformance/uv.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/conformance/uv.lock b/conformance/uv.lock index 3bcec030..8f158171 100644 --- a/conformance/uv.lock +++ b/conformance/uv.lock @@ -187,19 +187,19 @@ wheels = [ [[package]] name = "zuban" -version = "0.6.2" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/29/2d9f68f875155dfc58cb2542bad9bce60c680bf77b883a17cefd2c7b1399/zuban-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:392a24f4542b36e06b6ea8ff8a66b9bcf073fac380f6fedf5ead6d239a089b1b", size = 11274171, upload-time = "2026-03-16T23:11:13.516Z" }, - { url = "https://files.pythonhosted.org/packages/0f/83/77cf8a9568e21653c79ca6acbd35575ef3bc82251d1f604bb4c32bea98df/zuban-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5637981d19c503325bc2fd24b92af218733ee618de2f5217fa2523ca918b3a88", size = 10985794, upload-time = "2026-03-16T23:11:17.828Z" }, - { url = "https://files.pythonhosted.org/packages/23/22/2f7579439acbea7a28d8bbeb361225ddb9502406a892da9a94e73fadd522/zuban-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8097a716499ff7b3ac927b8e4c5425b9cfff5cd0b4e644a03e24d1a7c625d048", size = 28440118, upload-time = "2026-03-16T23:11:21.496Z" }, - { url = "https://files.pythonhosted.org/packages/03/1f/e714bbbf1783b76687a39c1ed7764b96c395221c103be91c0b63a4e249da/zuban-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ecf4b0c0e682f76f6403d68457d9085cc01dbbc56d402d925d931e82b36d9b5f", size = 28715022, upload-time = "2026-03-16T23:11:25.409Z" }, - { url = "https://files.pythonhosted.org/packages/24/b0/cd98c1c2797353a9fd8d10393ba018255e18a23ba47f505a538c32ea923c/zuban-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b1488ed63733d813d9be81b0c2bc888a329b31c4a03cb2cf462c7f0db052fef", size = 29943854, upload-time = "2026-03-16T23:11:29.391Z" }, - { url = "https://files.pythonhosted.org/packages/70/ee/d1ddcf7e7ea098eb33cc1d5b6b38a2688375f27207bdc80929a3abb8251e/zuban-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5b48be20d805b41ac224feeabd1b421a53e55b6cc10f2f3011139c1f625c583", size = 30939082, upload-time = "2026-03-16T23:11:34.003Z" }, - { url = "https://files.pythonhosted.org/packages/fb/45/c477ee9e281a334cfe7cf0375e1cf5e0433e80ade4cc7165ff9a9b756256/zuban-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:14d30ece874c9ca5b99ef57064b778edc834404e9d350af0c54eaf36d7eb6396", size = 28712077, upload-time = "2026-03-16T23:11:37.711Z" }, - { url = "https://files.pythonhosted.org/packages/ab/df/a962d8aacaf177356bfd698418d10a12fddd8d1c300e5cbd994ff62f80c2/zuban-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:3c144cd9436d39a3bebe50302c2eb600be403d22a85ae3ef41f061768e96d17e", size = 29336825, upload-time = "2026-03-16T23:11:41.965Z" }, - { url = "https://files.pythonhosted.org/packages/bd/35/09450daba51442632b51b70ef95a94356482fcfdd0127e70ed0f45be2a83/zuban-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ff52b183e752646baea76c0fb1e06e247c47e437d0d37f1386e07504dc2e4c29", size = 30047009, upload-time = "2026-03-16T23:11:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/a4/73/796d8e3789dadc84020a7a67d65cf13facca9807d40852adae8041032f41/zuban-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0e265fb4c38efc78e4ed79dc1b9b7adb034d70fa51f963c9ac609af1fbe2f855", size = 29316703, upload-time = "2026-03-16T23:11:50.81Z" }, - { url = "https://files.pythonhosted.org/packages/ea/2a/508617bda8277472cf403ecb73ae3b9227820dc2ff2a3a023eaed8512d5b/zuban-0.6.2-py3-none-win32.whl", hash = "sha256:4a129511f9f6080ba7d4153f111b5e6c2214a3eef945730ce466658903c324b8", size = 9742656, upload-time = "2026-03-16T23:11:54.231Z" }, - { url = "https://files.pythonhosted.org/packages/d0/25/dae184c1b6d7fbdc43e906254fef2577d23899669b58de865fcb0fe150f5/zuban-0.6.2-py3-none-win_amd64.whl", hash = "sha256:7db193c8b1456977ca2dfa2291c93a376e17f465a69018a06d0ecc8655464fff", size = 10464125, upload-time = "2026-03-16T23:11:57.267Z" }, + { url = "https://files.pythonhosted.org/packages/a7/91/2e3f5f095ff45c8052e320b99359ec03b266df1eedd3ea4ab4a2d68b134d/zuban-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bf3ed1b85cedafaf51e51527bdc2ae089db121546aaa96a252beb0708a7f4306", size = 11186573, upload-time = "2026-02-25T02:04:49.434Z" }, + { url = "https://files.pythonhosted.org/packages/77/44/fc318d17c500ba0b1733b8d661d33acb117aaf6b20d9e2a74ce7a33de18d/zuban-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e9e310e27eaa6c2184f3b50fbea6cd3cc0776549868837145d3156352156bb6c", size = 10925136, upload-time = "2026-02-25T02:04:52.562Z" }, + { url = "https://files.pythonhosted.org/packages/46/86/56a04bea43584b01d438b943bf1501b33a71db746183ab9b5cfa3818a2de/zuban-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1d78ad0af5b4b44d4201e1f1add0b5495da813593b57ecfb39a5a526f998602", size = 27757976, upload-time = "2026-02-25T02:04:56.017Z" }, + { url = "https://files.pythonhosted.org/packages/83/9f/c5cd3d5c130603116b1614e013a1feac2ee7a804622aa5830a35d97b1dc5/zuban-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a9d86ac6f23cf020978a94e47054af92ac3c26a7f884c27eb4fb28361a907bd6", size = 27883668, upload-time = "2026-02-25T02:04:59.839Z" }, + { url = "https://files.pythonhosted.org/packages/f8/09/5da69bc26fdce24b1a89c0e35d7134cd60960374e7aa48851b2d989447ad/zuban-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66ede8809b0231b050d543004ac27dd031dc9053839337006fad18157e3e5440", size = 29237524, upload-time = "2026-02-25T02:05:03.86Z" }, + { url = "https://files.pythonhosted.org/packages/d3/6d/a7b8a8531495e64e27a8c4a25bfd7865f7d94c82c1d549c103bc5bf3bbc1/zuban-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:859e8917ed579e9018de6f6e4bb8a2ec6204df95bcf9ff9165c3067257ff3f05", size = 30224734, upload-time = "2026-02-25T02:05:07.586Z" }, + { url = "https://files.pythonhosted.org/packages/04/9a/0b963861ea2e594ab3669245825dde90ff3a25d6a916a48007be3b0f7db9/zuban-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a07738374ddfca72fdf925cd275a3216a6fe8373bf91b49931c1c9f87561b729", size = 28034025, upload-time = "2026-02-25T02:05:12.99Z" }, + { url = "https://files.pythonhosted.org/packages/21/5d/5c588e77087fc649e84b409ac11c8b8ba48ee49a554531647af5b044a6c1/zuban-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:619815ac6cb9f48c9891cd4150cf3bce70a79c9a15fc349a0f860a3d9e44acf9", size = 28484806, upload-time = "2026-02-25T02:05:16.224Z" }, + { url = "https://files.pythonhosted.org/packages/3e/0b/4c67a559c0f9d405ca87685b65b16243e555c1d3c3c613d6fbb284c9b16a/zuban-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f912f2db095e5715b757c31d73cef3509ba6da5ba99295d36b166420e9884992", size = 29355542, upload-time = "2026-02-25T02:05:20.097Z" }, + { url = "https://files.pythonhosted.org/packages/65/a2/8a38a910f40a090effbcc65e0272a7d33b16149b452f74a67b5537ba5f2f/zuban-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:80a9f18aa327378846258b06277f9f7bba7127513aa591ad8b9b28bb48f4e3b8", size = 28658304, upload-time = "2026-02-25T02:05:24.106Z" }, + { url = "https://files.pythonhosted.org/packages/1c/50/65a34b02e162845155efea4f393761634f7f39311d3b59249c9c7f3f53f7/zuban-0.6.1-py3-none-win32.whl", hash = "sha256:7737d566cb4202ea5c37e1f03397dcfbd437d1f33e6ee4090a0d2941383531c5", size = 9734143, upload-time = "2026-02-25T02:05:27.409Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/2724c34fa769cf2cb29c9c178166b1689e936f810eb55f799e87a6acb248/zuban-0.6.1-py3-none-win_amd64.whl", hash = "sha256:9494dac40d4a23f92d7833e8fb15e8925e2c5d2561bc4edb18277ff35bea5ac8", size = 10490401, upload-time = "2026-02-25T02:05:29.817Z" }, ] From ae4d34dc750839e69a7f42156311f3c7d9f9a370 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 31 Mar 2026 11:09:57 +0200 Subject: [PATCH 7/8] Revert "Update zuban and run results" This reverts commit 41d15d50264b596a1ac9066d5f2112e360c4c5b5. --- conformance/results/results.html | 8 ++++---- .../results/zuban/dataclasses_hash.toml | 18 +++++++++++------- .../results/zuban/generics_self_advanced.toml | 8 +++++++- .../results/zuban/typeforms_typeform.toml | 8 +++++++- conformance/results/zuban/version.toml | 2 +- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/conformance/results/results.html b/conformance/results/results.html index 50efb127..2c21be32 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -176,7 +176,7 @@

Python Type System Conformance Test Results

pyright 1.1.408
-
zuban 0.6.2
+
zuban 0.6.1
pyrefly 0.56.0
@@ -227,7 +227,7 @@

Python Type System Conformance Test Results

     typeforms_typeform
Partial

Does not support assigning Union and GenericAlias objects to their runtime types.

Unsupported -Pass +
Partial

TypeForm[Any] is not considered equivalent to itself.

Unsupported Unsupported @@ -345,7 +345,7 @@

Python Type System Conformance Test Results

     generics_self_advanced
Partial

Does not infer the type of an unannotated `self` parameter to be type `Self`.

Does not retain `Self` when calling method that returns `Self`.

Does not infer the type of an unannotated `cls` parameter to be type `type[Self]`.

Does not retain `Self` when accessing attribute through `type[Self]`.

Pass -Pass +
Partial

Doesn't allow accessing `Self` in a classmethod

Pass*

Treats attributes not initialized on the class as instance-only

Pass @@ -837,7 +837,7 @@

Python Type System Conformance Test Results

     dataclasses_hash
Unsupported

Does not synthesize `__hash__ = None` as a class attribute for unhashable dataclasses.

Does not report when an unhashable dataclass has `__hash__` called directly on an instance.

Does not report when dataclass is not compatible with Hashable protocol.

Pass -Pass +
Partial

Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses.

Pass
Partial

Understands the `Hashable` protocol as equivalent to `object`.

diff --git a/conformance/results/zuban/dataclasses_hash.toml b/conformance/results/zuban/dataclasses_hash.toml index 05447588..52f7a8fa 100644 --- a/conformance/results/zuban/dataclasses_hash.toml +++ b/conformance/results/zuban/dataclasses_hash.toml @@ -1,13 +1,17 @@ -conformance_automated = "Pass" +conformance_automated = "Fail" +conformant = "Partial" +notes = """ +Does not synthesize a `__hash__ = None` class attribute for unhashable dataclasses. +""" errors_diff = """ +Line 14: Unexpected errors ['dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] +Line 36: Unexpected errors ['dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc]'] """ output = """ -dataclasses_hash.py:17: error: "None" not callable [operator] +dataclasses_hash.py:14: error: Expression is of type "Callable[[object], int]", not "None" [misc] +dataclasses_hash.py:17: error: "DC1" has no attribute "__hash__" [attr-defined] dataclasses_hash.py:18: error: Incompatible types in assignment (expression has type "DC1", variable has type "Hashable") [assignment] -dataclasses_hash.py:18: note: Following member(s) of "DC1" have conflicts: -dataclasses_hash.py:18: note: __hash__: expected "Callable[[], int]", got "None" -dataclasses_hash.py:39: error: "None" not callable [operator] +dataclasses_hash.py:36: error: Expression is of type "Callable[[object], int]", not "None" [misc] +dataclasses_hash.py:39: error: "DC3" has no attribute "__hash__" [attr-defined] dataclasses_hash.py:40: error: Incompatible types in assignment (expression has type "DC3", variable has type "Hashable") [assignment] -dataclasses_hash.py:40: note: Following member(s) of "DC3" have conflicts: -dataclasses_hash.py:40: note: __hash__: expected "Callable[[], int]", got "None" """ diff --git a/conformance/results/zuban/generics_self_advanced.toml b/conformance/results/zuban/generics_self_advanced.toml index ff36318b..325d9ebf 100644 --- a/conformance/results/zuban/generics_self_advanced.toml +++ b/conformance/results/zuban/generics_self_advanced.toml @@ -1,5 +1,11 @@ -conformance_automated = "Pass" +conformant = "Partial" +notes = """ +Doesn't allow accessing `Self` in a classmethod +""" +conformance_automated = "Fail" errors_diff = """ +Line 43: Unexpected errors ['generics_self_advanced.py:43: error: Access to generic instance variables via class is ambiguous [misc]'] +Line 44: Unexpected errors ['generics_self_advanced.py:44: error: Access to generic instance variables via class is ambiguous [misc]'] """ output = """ generics_self_advanced.py:48: error: Access to generic instance variables via class is ambiguous [misc] diff --git a/conformance/results/zuban/typeforms_typeform.toml b/conformance/results/zuban/typeforms_typeform.toml index 67d99387..5c7da90b 100644 --- a/conformance/results/zuban/typeforms_typeform.toml +++ b/conformance/results/zuban/typeforms_typeform.toml @@ -1,9 +1,15 @@ -conformance_automated = "Pass" +conformant = "Partial" +notes = """ +TypeForm[Any] is not considered equivalent to itself. +""" +conformance_automated = "Fail" errors_diff = """ +Line 41: Unexpected errors ['typeforms_typeform.py:41: error: Expression is of type "typing.TypeForm(Any)", not "typing.TypeForm(Any)" [misc]'] """ output = """ typeforms_typeform.py:23: error: Incompatible types in assignment (expression has type "typing.TypeForm(str | int)", variable has type "typing.TypeForm(str | None)") [assignment] typeforms_typeform.py:24: error: Incompatible types in assignment (expression has type "type[list[str | None]]", variable has type "typing.TypeForm(str | None)") [assignment] +typeforms_typeform.py:41: error: Expression is of type "typing.TypeForm(Any)", not "typing.TypeForm(Any)" [misc] typeforms_typeform.py:59: error: Invalid syntax [syntax] typeforms_typeform.py:67: error: Invalid type comment or annotation [valid-type] typeforms_typeform.py:68: error: Syntax error in type annotation [valid-type] diff --git a/conformance/results/zuban/version.toml b/conformance/results/zuban/version.toml index fe45d003..edcd1bf5 100644 --- a/conformance/results/zuban/version.toml +++ b/conformance/results/zuban/version.toml @@ -1 +1 @@ -version = "zuban 0.6.2" +version = "zuban 0.6.1" From a5f148af2de0b418e6256300a2fa47c32f7ac852 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 31 Mar 2026 11:11:24 +0200 Subject: [PATCH 8/8] Run the results again for Zuban --- conformance/results/results.html | 2 +- conformance/results/zuban/generics_self_advanced.toml | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/conformance/results/results.html b/conformance/results/results.html index 2c21be32..b28c048b 100644 --- a/conformance/results/results.html +++ b/conformance/results/results.html @@ -345,7 +345,7 @@

Python Type System Conformance Test Results

     generics_self_advanced
Partial

Does not infer the type of an unannotated `self` parameter to be type `Self`.

Does not retain `Self` when calling method that returns `Self`.

Does not infer the type of an unannotated `cls` parameter to be type `type[Self]`.

Does not retain `Self` when accessing attribute through `type[Self]`.

Pass -
Partial

Doesn't allow accessing `Self` in a classmethod

+Pass
Pass*

Treats attributes not initialized on the class as instance-only

Pass diff --git a/conformance/results/zuban/generics_self_advanced.toml b/conformance/results/zuban/generics_self_advanced.toml index 325d9ebf..ff36318b 100644 --- a/conformance/results/zuban/generics_self_advanced.toml +++ b/conformance/results/zuban/generics_self_advanced.toml @@ -1,11 +1,5 @@ -conformant = "Partial" -notes = """ -Doesn't allow accessing `Self` in a classmethod -""" -conformance_automated = "Fail" +conformance_automated = "Pass" errors_diff = """ -Line 43: Unexpected errors ['generics_self_advanced.py:43: error: Access to generic instance variables via class is ambiguous [misc]'] -Line 44: Unexpected errors ['generics_self_advanced.py:44: error: Access to generic instance variables via class is ambiguous [misc]'] """ output = """ generics_self_advanced.py:48: error: Access to generic instance variables via class is ambiguous [misc]