Skip to content

Commit

Permalink
Fix crash with custom ErrorCodes (#15327)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cdce8p authored May 31, 2023
1 parent 3e03484 commit 3d2f437
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
sub_code_map: dict[str, set[str]] = defaultdict(set)


@mypyc_attr(serializable=True)
@mypyc_attr(allow_interpreted_subclasses=True)
class ErrorCode:
def __init__(
self,
Expand Down
12 changes: 12 additions & 0 deletions test-data/unit/check-custom-plugin.test
Original file line number Diff line number Diff line change
Expand Up @@ -1014,3 +1014,15 @@ reveal_type(MyClass.foo_staticmethod) # N: Revealed type is "def (builtins.int)
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/add_classmethod.py

[case testCustomErrorCodePlugin]
# flags: --config-file tmp/mypy.ini --show-error-codes
def main() -> int:
return 2

main() # E: Custom error [custom]
reveal_type(1) # N: Revealed type is "Literal[1]?"

[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/custom_errorcode.py
20 changes: 20 additions & 0 deletions test-data/unit/plugins/custom_errorcode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from mypy.errorcodes import ErrorCode
from mypy.plugin import Plugin
from mypy.types import AnyType, TypeOfAny

CUSTOM_ERROR = ErrorCode(code="custom", description="", category="Custom")


class CustomErrorCodePlugin(Plugin):
def get_function_hook(self, fullname):
if fullname.endswith(".main"):
return self.emit_error
return None

def emit_error(self, ctx):
ctx.api.fail("Custom error", ctx.context, code=CUSTOM_ERROR)
return AnyType(TypeOfAny.from_error)


def plugin(version):
return CustomErrorCodePlugin

0 comments on commit 3d2f437

Please sign in to comment.