From cce8669b0f6915ad67927c3cc52c330ff8320e0b Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Wed, 1 Oct 2025 18:27:01 +0000 Subject: [PATCH 01/25] [mypyc] fix: reject invalid `mypyc_attr` args --- mypyc/irbuild/prepare.py | 2 +- mypyc/irbuild/util.py | 50 +++++++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index 20f2aeef8e6e..e4f43b38b0dc 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -357,7 +357,7 @@ def prepare_class_def( ir = mapper.type_to_ir[cdef.info] info = cdef.info - attrs, attrs_lines = get_mypyc_attrs(cdef) + attrs, attrs_lines = get_mypyc_attrs(cdef, path, errors) if attrs.get("allow_interpreted_subclasses") is True: ir.allow_interpreted_subclasses = True if attrs.get("serializable") is True: diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index eca2cac7e9db..d7866e7b6367 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -2,7 +2,9 @@ from __future__ import annotations -from typing import Any +from typing import Any, Final, FrozenSet, Literal, TypedDict + +from typing_extensions import NotRequired from mypy.nodes import ( ARG_NAMED, @@ -31,7 +33,18 @@ from mypy.types import FINAL_DECORATOR_NAMES from mypyc.errors import Errors -DATACLASS_DECORATORS = {"dataclasses.dataclass", "attr.s", "attr.attrs"} +MYPYC_ATTRS: Final[FrozenSet["MypycAttr"]] = frozenset(["native_class", "allow_interpreted_subclasses", "serializable"]) + +DATACLASS_DECORATORS: Final = frozenset(["dataclasses.dataclass", "attr.s", "attr.attrs"]) + + +MypycAttr = Literal["native_class", "allow_interpreted_subclasses", "serializable"] + +class MypycAttrs(TypedDict): + native_class: NotRequired[bool] + allow_interpreted_subclasses: NotRequired[bool] + serializable: NotRequired[bool] + free_list_len: NotRequired[int] def is_final_decorator(d: Expression) -> bool: @@ -111,22 +124,37 @@ def get_mypyc_attr_call(d: Expression) -> CallExpr | None: return d return None - -def get_mypyc_attrs(stmt: ClassDef | Decorator) -> tuple[dict[str, Any], dict[str, int]]: + +def get_mypyc_attrs( + stmt: ClassDef | Decorator, + path: str, + errors: Errors, +) -> tuple[MypycAttrs, dict[MypycAttr, int]]: """Collect all the mypyc_attr attributes on a class definition or a function.""" - attrs: dict[str, Any] = {} - lines: dict[str, int] = {} + attrs: MypycAttrs = {} + lines: dict[MypycAttr, int] = {} + + def record_unsupported_key(key: str) -> None: + errors.error(f"{key} is not a supported `mypyc_attrs` key.", path, line) + errors.note(f"supported keys: {', '.join(map(repr, sorted(MYPYC_ATTRS)))}", path, line) + for dec in stmt.decorators: - d = get_mypyc_attr_call(dec) - if d: + if d := get_mypyc_attr_call(dec): + line = d.line for name, arg in zip(d.arg_names, d.args): if name is None: if isinstance(arg, StrExpr): - attrs[arg.value] = True - lines[arg.value] = d.line + key = arg.value + if key in MYPYC_ATTRS: + attrs[key] = True + lines[key] = line + else: + record_unsupported_key(key) + elif name not in MYPYC_ATTRS: + record_unsupported_key(name) else: attrs[name] = get_mypyc_attr_literal(arg) - lines[name] = d.line + lines[name] = line return attrs, lines From d4631ac34edda5fc6013186ea19650d6126f6681 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:32:13 +0000 Subject: [PATCH 02/25] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypyc/irbuild/util.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index d7866e7b6367..00e66e99d779 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -3,7 +3,6 @@ from __future__ import annotations from typing import Any, Final, FrozenSet, Literal, TypedDict - from typing_extensions import NotRequired from mypy.nodes import ( @@ -33,13 +32,16 @@ from mypy.types import FINAL_DECORATOR_NAMES from mypyc.errors import Errors -MYPYC_ATTRS: Final[FrozenSet["MypycAttr"]] = frozenset(["native_class", "allow_interpreted_subclasses", "serializable"]) +MYPYC_ATTRS: Final[FrozenSet[MypycAttr]] = frozenset( + ["native_class", "allow_interpreted_subclasses", "serializable"] +) DATACLASS_DECORATORS: Final = frozenset(["dataclasses.dataclass", "attr.s", "attr.attrs"]) MypycAttr = Literal["native_class", "allow_interpreted_subclasses", "serializable"] + class MypycAttrs(TypedDict): native_class: NotRequired[bool] allow_interpreted_subclasses: NotRequired[bool] @@ -124,11 +126,9 @@ def get_mypyc_attr_call(d: Expression) -> CallExpr | None: return d return None - + def get_mypyc_attrs( - stmt: ClassDef | Decorator, - path: str, - errors: Errors, + stmt: ClassDef | Decorator, path: str, errors: Errors ) -> tuple[MypycAttrs, dict[MypycAttr, int]]: """Collect all the mypyc_attr attributes on a class definition or a function.""" attrs: MypycAttrs = {} From 0cc6c5dc7064abf16608f7b7c7a4638fa1edd723 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:44:23 -0400 Subject: [PATCH 03/25] fix: add key 'free_list_len' --- mypyc/irbuild/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 00e66e99d779..7e7eec0b56af 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -33,13 +33,13 @@ from mypyc.errors import Errors MYPYC_ATTRS: Final[FrozenSet[MypycAttr]] = frozenset( - ["native_class", "allow_interpreted_subclasses", "serializable"] + ["native_class", "allow_interpreted_subclasses", "serializable", "free_list_len"] ) DATACLASS_DECORATORS: Final = frozenset(["dataclasses.dataclass", "attr.s", "attr.attrs"]) -MypycAttr = Literal["native_class", "allow_interpreted_subclasses", "serializable"] +MypycAttr = Literal["native_class", "allow_interpreted_subclasses", "serializable", "free_list_len"] class MypycAttrs(TypedDict): From 4aefb1b99e75b66c8628e25f8b4b578323070bc5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 18:45:45 +0000 Subject: [PATCH 04/25] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypyc/irbuild/util.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 7e7eec0b56af..3530b32e00f9 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -39,7 +39,9 @@ DATACLASS_DECORATORS: Final = frozenset(["dataclasses.dataclass", "attr.s", "attr.attrs"]) -MypycAttr = Literal["native_class", "allow_interpreted_subclasses", "serializable", "free_list_len"] +MypycAttr = Literal[ + "native_class", "allow_interpreted_subclasses", "serializable", "free_list_len" +] class MypycAttrs(TypedDict): From 3c2711280609d4851c8876aa936fd2d0e3ca2c90 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:52:04 -0400 Subject: [PATCH 05/25] fix mypy errs --- mypyc/irbuild/util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 3530b32e00f9..fd339386b075 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -1,8 +1,9 @@ +# mypy: disable-error-code="literal-required" """Various utilities that don't depend on other modules in mypyc.irbuild.""" from __future__ import annotations -from typing import Any, Final, FrozenSet, Literal, TypedDict +from typing import Any, Final, FrozenSet, Literal, TypedDict, cast from typing_extensions import NotRequired from mypy.nodes import ( @@ -146,7 +147,7 @@ def record_unsupported_key(key: str) -> None: for name, arg in zip(d.arg_names, d.args): if name is None: if isinstance(arg, StrExpr): - key = arg.value + key = cast(MypycAttr, arg.value) if key in MYPYC_ATTRS: attrs[key] = True lines[key] = line From c2f3d36c0dfe12fd24fa4a839a2d050c15ec58ca Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:01:06 -0400 Subject: [PATCH 06/25] Update util.py --- mypyc/irbuild/util.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index fd339386b075..2adddc105c4f 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -137,27 +137,28 @@ def get_mypyc_attrs( attrs: MypycAttrs = {} lines: dict[MypycAttr, int] = {} - def record_unsupported_key(key: str) -> None: - errors.error(f"{key} is not a supported `mypyc_attrs` key.", path, line) - errors.note(f"supported keys: {', '.join(map(repr, sorted(MYPYC_ATTRS)))}", path, line) + def set_mypyc_attr(key: MypycAttr, value: Any, line: int) -> None: + if key in MYPYC_ATTRS: + attrs[key] = value + lines[key] = line + else: + errors.error(f"{key} is not a supported `mypyc_attrs` key.", path, line) + errors.note(f"supported keys: {', '.join(map(repr, sorted(MYPYC_ATTRS)))}", path, line) for dec in stmt.decorators: if d := get_mypyc_attr_call(dec): line = d.line + + key: MypycAttr for name, arg in zip(d.arg_names, d.args): if name is None: if isinstance(arg, StrExpr): - key = cast(MypycAttr, arg.value) - if key in MYPYC_ATTRS: - attrs[key] = True - lines[key] = line - else: - record_unsupported_key(key) - elif name not in MYPYC_ATTRS: - record_unsupported_key(name) + set_mypyc_attr(arg.value, True, line) + else: + errors.error("All `mypyc_attr` positional arguments must be string literals.", path, line) else: - attrs[name] = get_mypyc_attr_literal(arg) - lines[name] = line + arg_value = get_mypyc_attr_literal(arg) + set_mypyc_attr(name, arg_value, line) return attrs, lines From 0e1c740372757c954bc2b4973f2e41c36883df05 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:01:37 -0400 Subject: [PATCH 07/25] Update util.py --- mypyc/irbuild/util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 2adddc105c4f..8fdb3d8be9b1 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -149,7 +149,6 @@ def set_mypyc_attr(key: MypycAttr, value: Any, line: int) -> None: if d := get_mypyc_attr_call(dec): line = d.line - key: MypycAttr for name, arg in zip(d.arg_names, d.args): if name is None: if isinstance(arg, StrExpr): From 0de2627a82351a583b56bc6c7198406b3bffb2c7 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:01:59 -0400 Subject: [PATCH 08/25] Update util.py --- mypyc/irbuild/util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 8fdb3d8be9b1..7ff2fb976872 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -1,4 +1,3 @@ -# mypy: disable-error-code="literal-required" """Various utilities that don't depend on other modules in mypyc.irbuild.""" from __future__ import annotations @@ -148,7 +147,6 @@ def set_mypyc_attr(key: MypycAttr, value: Any, line: int) -> None: for dec in stmt.decorators: if d := get_mypyc_attr_call(dec): line = d.line - for name, arg in zip(d.arg_names, d.args): if name is None: if isinstance(arg, StrExpr): From 4a88449f4c469505ea049e01c0d306d6abeb7d9a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 19:02:25 +0000 Subject: [PATCH 09/25] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypyc/irbuild/util.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 7ff2fb976872..5937aef9f084 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Final, FrozenSet, Literal, TypedDict, cast +from typing import Any, Final, FrozenSet, Literal, TypedDict from typing_extensions import NotRequired from mypy.nodes import ( @@ -152,7 +152,11 @@ def set_mypyc_attr(key: MypycAttr, value: Any, line: int) -> None: if isinstance(arg, StrExpr): set_mypyc_attr(arg.value, True, line) else: - errors.error("All `mypyc_attr` positional arguments must be string literals.", path, line) + errors.error( + "All `mypyc_attr` positional arguments must be string literals.", + path, + line, + ) else: arg_value = get_mypyc_attr_literal(arg) set_mypyc_attr(name, arg_value, line) From 7932b81e40526d51d64c9f32168eb15f3d9ca74e Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:07:37 -0400 Subject: [PATCH 10/25] Update util.py --- mypyc/irbuild/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 5937aef9f084..3e47b872cc2e 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Final, FrozenSet, Literal, TypedDict +from typing import Any, Final, Literal, TypedDict from typing_extensions import NotRequired from mypy.nodes import ( @@ -32,7 +32,7 @@ from mypy.types import FINAL_DECORATOR_NAMES from mypyc.errors import Errors -MYPYC_ATTRS: Final[FrozenSet[MypycAttr]] = frozenset( +MYPYC_ATTRS: Final[MypycAttr] = frozenset( ["native_class", "allow_interpreted_subclasses", "serializable", "free_list_len"] ) From 593c5eee115b91c0944aae710c504bb67b87a0f4 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:10:40 -0400 Subject: [PATCH 11/25] Update util.py --- mypyc/irbuild/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 3e47b872cc2e..2c628eb0d24c 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -32,7 +32,7 @@ from mypy.types import FINAL_DECORATOR_NAMES from mypyc.errors import Errors -MYPYC_ATTRS: Final[MypycAttr] = frozenset( +MYPYC_ATTRS: Final[frozenset[MypycAttr]] = frozenset( ["native_class", "allow_interpreted_subclasses", "serializable", "free_list_len"] ) From 9d12459af2f27baaaea45e00adddb6579ee09c3e Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:11:13 -0400 Subject: [PATCH 12/25] fix mypy err --- mypyc/irbuild/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 2c628eb0d24c..d8cd390863e0 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -136,7 +136,7 @@ def get_mypyc_attrs( attrs: MypycAttrs = {} lines: dict[MypycAttr, int] = {} - def set_mypyc_attr(key: MypycAttr, value: Any, line: int) -> None: + def set_mypyc_attr(key: str, value: Any, line: int) -> None: if key in MYPYC_ATTRS: attrs[key] = value lines[key] = line From f7468d9b5a322eed5ec01f82d7f5e26889fea3aa Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 1 Oct 2025 15:18:50 -0400 Subject: [PATCH 13/25] fix mypy err --- mypyc/irbuild/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index d8cd390863e0..fcabc1bdfc50 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any, Final, Literal, TypedDict +from typing import Any, Final, Literal, TypedDict, cast from typing_extensions import NotRequired from mypy.nodes import ( @@ -138,6 +138,7 @@ def get_mypyc_attrs( def set_mypyc_attr(key: str, value: Any, line: int) -> None: if key in MYPYC_ATTRS: + key = cast(MypycAttr, key) attrs[key] = value lines[key] = line else: From 71473d38a5ffc54f42d89887d75ca1c1df44fe4c Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 13:44:52 -0400 Subject: [PATCH 14/25] Update util.py --- mypyc/irbuild/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index fcabc1bdfc50..0221ac177ede 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -142,7 +142,7 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: attrs[key] = value lines[key] = line else: - errors.error(f"{key} is not a supported `mypyc_attrs` key.", path, line) + errors.error(f"{key!r} is not a supported `mypyc_attr`", path, line) errors.note(f"supported keys: {', '.join(map(repr, sorted(MYPYC_ATTRS)))}", path, line) for dec in stmt.decorators: From 123b74055987ef38d565bc081f070a4f4f06c623 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 13:47:10 -0400 Subject: [PATCH 15/25] test error message --- mypyc/test-data/irbuild-classes.test | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index a98b3a7d3dcf..6510b5a3ce64 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2686,3 +2686,14 @@ L0: r6 = PyObject_VectorcallMethod(r3, r5, 9223372036854775812, 0) keep_alive r2, self, key, val return 1 + +[case testInvalidMypycAttr] +@mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: 'invalid_arg' is not a supported `mypyc_attr` +class InvalidArg: + pass +@mypyc_attr(invalid_kwarg=True) # E: 'invalid_kwarg' is not a supported `mypyc_attr` +class InvalidKwarg: + pass +@mypyc_attr(str()) # E: All `mypyc_attr` args must be string literals. +class InvalidLiteral: + pass From 3e98dce5cc9a89a9e7dc5bbd4c994fe14848192b Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:04:10 -0400 Subject: [PATCH 16/25] Update irbuild-classes.test --- mypyc/test-data/irbuild-classes.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 6510b5a3ce64..f1c239ea7467 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2688,6 +2688,8 @@ L0: return 1 [case testInvalidMypycAttr] +from mypy_extensions import mypyc_attr + @mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: 'invalid_arg' is not a supported `mypyc_attr` class InvalidArg: pass From dfe19bb0f3d8beb3cc3fecafeee3c7e24b0dc6e3 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 15:10:20 -0400 Subject: [PATCH 17/25] add note to tests --- mypyc/test-data/irbuild-classes.test | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index f1c239ea7467..40b49038f12f 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2690,12 +2690,15 @@ L0: [case testInvalidMypycAttr] from mypy_extensions import mypyc_attr -@mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: 'invalid_arg' is not a supported `mypyc_attr` +@mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: 'invalid_arg' is not a supported `mypyc_attr` \ + # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidArg: pass -@mypyc_attr(invalid_kwarg=True) # E: 'invalid_kwarg' is not a supported `mypyc_attr` +@mypyc_attr(invalid_kwarg=True) # E: 'invalid_kwarg' is not a supported `mypyc_attr` \ + # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidKwarg: pass -@mypyc_attr(str()) # E: All `mypyc_attr` args must be string literals. +@mypyc_attr(str()) # E: All `mypyc_attr` args must be string literals. \ + # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidLiteral: pass From 16fb0f3a830bfd7d7612dffbfb838c51a16fe322 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 15:12:34 -0400 Subject: [PATCH 18/25] Update irbuild-classes.test --- mypyc/test-data/irbuild-classes.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 40b49038f12f..6edea9cb51dc 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2698,7 +2698,7 @@ class InvalidArg: # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidKwarg: pass -@mypyc_attr(str()) # E: All `mypyc_attr` args must be string literals. \ +@mypyc_attr(str()) # E: All `mypyc_attr` positional arguments must be string literals. \ # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidLiteral: pass From b220df57d79c920ff450291928fe46462c7929c0 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 3 Oct 2025 15:39:20 -0400 Subject: [PATCH 19/25] Update irbuild-classes.test --- mypyc/test-data/irbuild-classes.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 6edea9cb51dc..3c2adb027119 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2698,7 +2698,6 @@ class InvalidArg: # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' class InvalidKwarg: pass -@mypyc_attr(str()) # E: All `mypyc_attr` positional arguments must be string literals. \ - # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' +@mypyc_attr(str()) # E: All `mypyc_attr` positional arguments must be string literals. class InvalidLiteral: pass From 8caceb912e6ce23570d23364a8ba47395592447a Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:00:21 -0400 Subject: [PATCH 20/25] use double quotes --- mypyc/irbuild/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 0221ac177ede..7d9cf458e97b 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -142,8 +142,8 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: attrs[key] = value lines[key] = line else: - errors.error(f"{key!r} is not a supported `mypyc_attr`", path, line) - errors.note(f"supported keys: {', '.join(map(repr, sorted(MYPYC_ATTRS)))}", path, line) + errors.error(f'"{key}" is not a supported "mypyc_attr"', path, line) + errors.note(f"supported keys: {'", "'.join(sorted(MYPYC_ATTRS))}", path, line) for dec in stmt.decorators: if d := get_mypyc_attr_call(dec): From e6670cf85cd17247daeab22efbfb76bb7dbd7a37 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:08:21 -0400 Subject: [PATCH 21/25] another double quote --- mypyc/irbuild/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 7d9cf458e97b..33fac4e332f7 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -154,7 +154,7 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: set_mypyc_attr(arg.value, True, line) else: errors.error( - "All `mypyc_attr` positional arguments must be string literals.", + 'All "mypyc_attr" positional arguments must be string literals.', path, line, ) From c66354273f8517b0e2c4e1abbc81e6907f487445 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:31:05 -0400 Subject: [PATCH 22/25] Update util.py --- mypyc/irbuild/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 33fac4e332f7..81d3840ee7fb 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -143,7 +143,8 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: lines[key] = line else: errors.error(f'"{key}" is not a supported "mypyc_attr"', path, line) - errors.note(f"supported keys: {'", "'.join(sorted(MYPYC_ATTRS))}", path, line) + supported_keys = ','.join(f'"{key}"' for key in sorted(MYPYC_ATTRS)) + errors.note(f"supported keys: {supported_keys}", path, line) for dec in stmt.decorators: if d := get_mypyc_attr_call(dec): From 2a0bfbdf12465533f49cc2d6bb61014e6bb435eb Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:32:28 -0400 Subject: [PATCH 23/25] Update irbuild-classes.test --- mypyc/test-data/irbuild-classes.test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 3c2adb027119..64364cf91ef8 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -2690,14 +2690,14 @@ L0: [case testInvalidMypycAttr] from mypy_extensions import mypyc_attr -@mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: 'invalid_arg' is not a supported `mypyc_attr` \ - # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' +@mypyc_attr("allow_interpreted_subclasses", "invalid_arg") # E: "invalid_arg" is not a supported "mypyc_attr" \ + # N: supported keys: "allow_interpreted_subclasses", "free_list_len", "native_class", "serializable" class InvalidArg: pass -@mypyc_attr(invalid_kwarg=True) # E: 'invalid_kwarg' is not a supported `mypyc_attr` \ - # N: supported keys: 'allow_interpreted_subclasses', 'free_list_len', 'native_class', 'serializable' +@mypyc_attr(invalid_kwarg=True) # E: "invalid_kwarg" is not a supported "mypyc_attr" \ + # N: supported keys: "allow_interpreted_subclasses", "free_list_len", "native_class", "serializable" class InvalidKwarg: pass -@mypyc_attr(str()) # E: All `mypyc_attr` positional arguments must be string literals. +@mypyc_attr(str()) # E: All "mypyc_attr" positional arguments must be string literals. class InvalidLiteral: pass From ac891b92229be224db82aac147cd551d61b523ce Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 17:32:41 +0000 Subject: [PATCH 24/25] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypyc/irbuild/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 81d3840ee7fb..9842665a3d0c 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -143,7 +143,7 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: lines[key] = line else: errors.error(f'"{key}" is not a supported "mypyc_attr"', path, line) - supported_keys = ','.join(f'"{key}"' for key in sorted(MYPYC_ATTRS)) + supported_keys = ",".join(f'"{key}"' for key in sorted(MYPYC_ATTRS)) errors.note(f"supported keys: {supported_keys}", path, line) for dec in stmt.decorators: From 0c23635153780d6453247b5f54829459b3727b1f Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:45:49 -0400 Subject: [PATCH 25/25] Update util.py --- mypyc/irbuild/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/util.py b/mypyc/irbuild/util.py index 9842665a3d0c..3028e940f7f9 100644 --- a/mypyc/irbuild/util.py +++ b/mypyc/irbuild/util.py @@ -143,8 +143,8 @@ def set_mypyc_attr(key: str, value: Any, line: int) -> None: lines[key] = line else: errors.error(f'"{key}" is not a supported "mypyc_attr"', path, line) - supported_keys = ",".join(f'"{key}"' for key in sorted(MYPYC_ATTRS)) - errors.note(f"supported keys: {supported_keys}", path, line) + supported_keys = '", "'.join(sorted(MYPYC_ATTRS)) + errors.note(f'supported keys: "{supported_keys}"', path, line) for dec in stmt.decorators: if d := get_mypyc_attr_call(dec):