Skip to content

Commit 3d2f437

Browse files
authored
Fix crash with custom ErrorCodes (#15327)
A class marked with `allow_interpreted_subclasses=True` implicitly supports serialization while also allowing it to be subclassed by pure Python code. Fixes #15255 https://mypyc.readthedocs.io/en/latest/differences_from_python.html#pickling-and-copying-objects https://mypyc.readthedocs.io/en/latest/native_classes.html#inheritance
1 parent 3e03484 commit 3d2f437

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

mypy/errorcodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
sub_code_map: dict[str, set[str]] = defaultdict(set)
1515

1616

17-
@mypyc_attr(serializable=True)
17+
@mypyc_attr(allow_interpreted_subclasses=True)
1818
class ErrorCode:
1919
def __init__(
2020
self,

test-data/unit/check-custom-plugin.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,3 +1014,15 @@ reveal_type(MyClass.foo_staticmethod) # N: Revealed type is "def (builtins.int)
10141014
[file mypy.ini]
10151015
\[mypy]
10161016
plugins=<ROOT>/test-data/unit/plugins/add_classmethod.py
1017+
1018+
[case testCustomErrorCodePlugin]
1019+
# flags: --config-file tmp/mypy.ini --show-error-codes
1020+
def main() -> int:
1021+
return 2
1022+
1023+
main() # E: Custom error [custom]
1024+
reveal_type(1) # N: Revealed type is "Literal[1]?"
1025+
1026+
[file mypy.ini]
1027+
\[mypy]
1028+
plugins=<ROOT>/test-data/unit/plugins/custom_errorcode.py
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from mypy.errorcodes import ErrorCode
2+
from mypy.plugin import Plugin
3+
from mypy.types import AnyType, TypeOfAny
4+
5+
CUSTOM_ERROR = ErrorCode(code="custom", description="", category="Custom")
6+
7+
8+
class CustomErrorCodePlugin(Plugin):
9+
def get_function_hook(self, fullname):
10+
if fullname.endswith(".main"):
11+
return self.emit_error
12+
return None
13+
14+
def emit_error(self, ctx):
15+
ctx.api.fail("Custom error", ctx.context, code=CUSTOM_ERROR)
16+
return AnyType(TypeOfAny.from_error)
17+
18+
19+
def plugin(version):
20+
return CustomErrorCodePlugin

0 commit comments

Comments
 (0)