File tree Expand file tree Collapse file tree 4 files changed +72
-5
lines changed Expand file tree Collapse file tree 4 files changed +72
-5
lines changed Original file line number Diff line number Diff line change @@ -205,10 +205,6 @@ def generate_class_reuse(
205205 TODO: Generalize to support a free list with up to N objects.
206206 """
207207 assert cl .reuse_freed_instance
208-
209- # The free list implementation doesn't support class hierarchies
210- assert cl .is_final_class or cl .children == []
211-
212208 context = c_emitter .context
213209 name = cl .name_prefix (c_emitter .names ) + "_free_instance"
214210 struct_name = cl .struct_name (c_emitter .names )
Original file line number Diff line number Diff line change @@ -363,6 +363,12 @@ def prepare_class_def(
363363 line = attrs_lines ["free_list_len" ]
364364 if ir .is_trait :
365365 errors .error ('"free_list_len" can\' t be used with traits' , path , line )
366+ if ir .allow_interpreted_subclasses :
367+ errors .error (
368+ '"free_list_len" can\' t be used in a class that allows interpreted subclasses' ,
369+ path ,
370+ line ,
371+ )
366372 if free_list_len == 1 :
367373 ir .reuse_freed_instance = True
368374 else :
Original file line number Diff line number Diff line change @@ -1754,3 +1754,7 @@ class FreeListError:
17541754@mypyc_attr(free_list_len=1) # E: "free_list_len" can't be used with traits
17551755class NonNative:
17561756 pass
1757+
1758+ @mypyc_attr(free_list_len=1, allow_interpreted_subclasses=True) # E: "free_list_len" can't be used in a class that allows interpreted subclasses
1759+ class InterpSub:
1760+ pass
Original file line number Diff line number Diff line change @@ -3802,7 +3802,7 @@ from mypy_extensions import mypyc_attr
38023802
38033803a = []
38043804
3805- @mypyc_attr(free_list =1)
3805+ @mypyc_attr(free_list_len =1)
38063806class Foo:
38073807 def __init__(self, x: int) -> None:
38083808 self.x = x
@@ -3830,3 +3830,64 @@ def test_alloc() -> None:
38303830 y = Foo(5)
38313831 assert x.x == 4
38323832 assert y.x == 5
3833+
3834+ @mypyc_attr(free_list_len=1)
3835+ class Base:
3836+ def __init__(self, x: str) -> None:
3837+ self.x = x
3838+
3839+ class Deriv(Base):
3840+ def __init__(self, x: str, y: str) -> None:
3841+ super().__init__(x)
3842+ self.y = y
3843+
3844+ @mypyc_attr(free_list_len=1)
3845+ class Deriv2(Base):
3846+ def __init__(self, x: str, y: str) -> None:
3847+ super().__init__(x)
3848+ self.y = y
3849+
3850+ def test_inheritance() -> None:
3851+ x: Base | None
3852+ y: Base | None
3853+ x = Base('x' + str())
3854+ y = Base('y' + str())
3855+ y = None
3856+ d = Deriv('a' + str(), 'b' + str())
3857+ assert type(d) is Deriv
3858+ assert d.x == 'a'
3859+ assert d.y == 'b'
3860+ assert x.x == 'x'
3861+ y = Base('z' + str())
3862+ assert d.x == 'a'
3863+ assert d.y == 'b'
3864+ assert y.x == 'z'
3865+ x = None
3866+ y = None
3867+
3868+ def test_inheritance_2() -> None:
3869+ x: Base | None
3870+ y: Base | None
3871+ d: Deriv2 | None
3872+ x = Base('x' + str())
3873+ y = Base('y' + str())
3874+ y = None
3875+ d = Deriv2('a' + str(), 'b' + str())
3876+ assert type(d) is Deriv2
3877+ assert d.x == 'a'
3878+ assert d.y == 'b'
3879+ assert x.x == 'x'
3880+ d = None
3881+ d = Deriv2('c' + str(), 'd' + str())
3882+ assert type(d) is Deriv2
3883+ assert d.x == 'c'
3884+ assert d.y == 'd'
3885+ assert x.x == 'x'
3886+ y = Base('z' + str())
3887+ assert type(y) is Base
3888+ assert d.x == 'c'
3889+ assert d.y == 'd'
3890+ assert y.x == 'z'
3891+ x = None
3892+ y = None
3893+ d = None
You can’t perform that action at this time.
0 commit comments