|
10 | 10 | import keyword |
11 | 11 | import logging |
12 | 12 | import sys |
| 13 | +import weakref |
13 | 14 |
|
14 | 15 | import yaml |
15 | 16 |
|
@@ -697,6 +698,7 @@ async def call(self, ast_ctx, *args, **kwargs): |
697 | 698 | self.exception_long = None |
698 | 699 | prev_func = ast_ctx.curr_func |
699 | 700 | ast_ctx.curr_func = self |
| 701 | + del args, kwargs |
700 | 702 | for arg1 in self.func_def.body: |
701 | 703 | val = await self.try_aeval(ast_ctx, arg1) |
702 | 704 | if isinstance(val, EvalReturn): |
@@ -767,19 +769,19 @@ async def __call__(self, *args, **kwargs): |
767 | 769 | class EvalFuncVarClassInst(EvalFuncVar): |
768 | 770 | """Class for a callable pyscript class instance function.""" |
769 | 771 |
|
770 | | - def __init__(self, func, ast_ctx, class_inst): |
| 772 | + def __init__(self, func, ast_ctx, class_inst_weak): |
771 | 773 | """Initialize instance with given EvalFunc function.""" |
772 | 774 | super().__init__(func) |
773 | 775 | self.ast_ctx = ast_ctx |
774 | | - self.class_inst = class_inst |
| 776 | + self.class_inst_weak = class_inst_weak |
775 | 777 |
|
776 | 778 | async def call(self, ast_ctx, *args, **kwargs): |
777 | 779 | """Call the EvalFunc function.""" |
778 | | - return await self.func.call(ast_ctx, self.class_inst, *args, **kwargs) |
| 780 | + return await self.func.call(ast_ctx, self.class_inst_weak(), *args, **kwargs) |
779 | 781 |
|
780 | 782 | async def __call__(self, *args, **kwargs): |
781 | 783 | """Call the function using our saved ast ctx and class instance.""" |
782 | | - return await self.func.call(self.ast_ctx, self.class_inst, *args, **kwargs) |
| 784 | + return await self.func.call(self.ast_ctx, self.class_inst_weak(), *args, **kwargs) |
783 | 785 |
|
784 | 786 |
|
785 | 787 | class AstEval: |
@@ -1771,11 +1773,17 @@ async def call_func(self, func, func_name, *args, **kwargs): |
1771 | 1773 | return await func.call(self, *args, **kwargs) |
1772 | 1774 | if inspect.isclass(func) and hasattr(func, "__init__evalfunc_wrap__"): |
1773 | 1775 | inst = func() |
| 1776 | + # |
| 1777 | + # we use weak references when we bind the method calls to the instance inst; |
| 1778 | + # otherwise these self references cause the object to not be deleted until |
| 1779 | + # it is later garbage collected |
| 1780 | + # |
| 1781 | + inst_weak = weakref.ref(inst) |
1774 | 1782 | for name in inst.__dir__(): |
1775 | 1783 | value = getattr(inst, name) |
1776 | 1784 | if type(value) is not EvalFuncVar: |
1777 | 1785 | continue |
1778 | | - setattr(inst, name, EvalFuncVarClassInst(value.get_func(), value.get_ast_ctx(), inst)) |
| 1786 | + setattr(inst, name, EvalFuncVarClassInst(value.get_func(), value.get_ast_ctx(), inst_weak)) |
1779 | 1787 | if getattr(func, "__init__evalfunc_wrap__") is not None: |
1780 | 1788 | # |
1781 | 1789 | # since our __init__ function is async, call the renamed one |
|
0 commit comments