Skip to content

Commit

Permalink
feat: persist_type for stable type identity across hot-reloads
Browse files Browse the repository at this point in the history
  • Loading branch information
blepabyte committed Nov 21, 2024
1 parent 4a099dd commit 545cb44
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
22 changes: 22 additions & 0 deletions maxray/inators/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,25 @@ def line_at_endpoint(self):
R = Rewriter()

S = Statefool()

_TYPE_PERSIST = {}


def persist_type(cls):
"""
Because each reload completely redefines all classes that were defined inline, isinstance checks will be broken, and method definition updates won't propagate.
"""
# TODO: could this be auto-patched?

if cls.__qualname__ in _TYPE_PERSIST:
merge_cls = _TYPE_PERSIST[cls.__qualname__]
# TypeError: __class__ assignment only supported for mutable types or ModuleType subclasses
# merge_cls.__class__ = cls

merge_cls.__bases__ = (cls,)
return merge_cls
else:
wrap_cls = type(cls.__name__, (cls,), {})
wrap_cls.__qualname__ = cls.__qualname__
_TYPE_PERSIST[cls.__qualname__] = wrap_cls
return wrap_cls
37 changes: 36 additions & 1 deletion tests/test_inator_lib.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from maxray.inators.core import IterScope
from maxray.inators.core import IterScope, persist_type

from dataclasses import dataclass

import pytest


Expand Down Expand Up @@ -137,3 +140,35 @@ def robust_it(gen):
assert True
case _:
assert False, ih.result()


def test_type_identity_on_reload():
@persist_type
@dataclass(frozen=True)
class Foo:
x: int

def oof(self):
return 1 + self.x

qn1 = Foo.__qualname__
i1 = Foo(2)
assert i1.oof() == 3

@persist_type
@dataclass(frozen=True)
class Foo:
x: int

def oof(self):
return 2 + self.x

qn2 = Foo.__qualname__
i2 = Foo(2)

assert qn1 == qn2
assert i1 == i2
assert type(i1) is type(i2)
assert i1.oof() == i2.oof() == 4
assert i1 in {i2}
assert i2 in {i1}

0 comments on commit 545cb44

Please sign in to comment.