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(
205
205
TODO: Generalize to support a free list with up to N objects.
206
206
"""
207
207
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
-
212
208
context = c_emitter .context
213
209
name = cl .name_prefix (c_emitter .names ) + "_free_instance"
214
210
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(
363
363
line = attrs_lines ["free_list_len" ]
364
364
if ir .is_trait :
365
365
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
+ )
366
372
if free_list_len == 1 :
367
373
ir .reuse_freed_instance = True
368
374
else :
Original file line number Diff line number Diff line change @@ -1754,3 +1754,7 @@ class FreeListError:
1754
1754
@mypyc_attr(free_list_len=1) # E: "free_list_len" can't be used with traits
1755
1755
class NonNative:
1756
1756
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
3802
3802
3803
3803
a = []
3804
3804
3805
- @mypyc_attr(free_list =1)
3805
+ @mypyc_attr(free_list_len =1)
3806
3806
class Foo:
3807
3807
def __init__(self, x: int) -> None:
3808
3808
self.x = x
@@ -3830,3 +3830,64 @@ def test_alloc() -> None:
3830
3830
y = Foo(5)
3831
3831
assert x.x == 4
3832
3832
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