Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__del__ isn't called when expected #277

Open
dlashua opened this issue Nov 27, 2021 · 3 comments
Open

__del__ isn't called when expected #277

dlashua opened this issue Nov 27, 2021 · 3 comments

Comments

@dlashua
Copy link
Contributor

dlashua commented Nov 27, 2021

The goal I'm trying to accomplish is a class that cleans up after itself when the object is no longer in use. Users (i.e: me) sometimes forget to clean up their own messes.

__del__ seemed to be the right way to implement this, but it isn't working as expected.

I have the following module (test_helpers.py):

class NoisyThing:

    def __init__(self, name):
        log.info(f'starting NoisyThing {name}')
        self.name = name
        self.counter = 0
        self.trigger_func = None

        self.startup()

    @pyscript_compile
    def __del__(self):
        self.trigger_func = None

    def startup(self):

        @time_trigger("period(now, 1sec, now + 30sec)")
        def be_noisy():
            self.counter = self.counter + 1
            log.info(f'{self.name} counter {self.counter}')

        self.trigger_func = be_noisy

If used like this, by reloading (just saving the file again with no changes) you can see by the log output the old object and trigger functions are not destroyed. Reloading test_helpers, however, does stop the noise:

from test_helpers import NoisyThing

a = NoisyThing('a')

Ideally, the above would work as the goal is to make NoisyThing clean up after itself. However, this (which doesn't accomplish the goal) also doesn't work:

from test_helpers import NoisyThing

a = NoisyThing('a')

@time_trigger('shutdown')
def shutdown():
    # without global a "name 'a' is not defined" NameError occurs
    global a
    del a

The only way to make it work is to call it directly:

from test_helpers import NoisyThing

a = NoisyThing('a')

@time_trigger('shutdown')
def shutdown():
    a.__del__()
@dlashua
Copy link
Contributor Author

dlashua commented Nov 27, 2021

Perhaps, when a context is reloaded/destroyed, all of the variables in that context could be iterated and explicitly deled.

Another solution (not for object destruction in general, but for handling trigger functions created like this) might be to have a pyscript method explicitly for registering trigger functions in the current context. This would allow me to replace the last line of startup with func.register(be_noisy).

Another solution (that might break other things?) is to have modules run in the context of whatever is calling it. That way they are destroyed when the calling script is destroyed, instead of being tied to the module itself.

@dlashua
Copy link
Contributor Author

dlashua commented Nov 27, 2021

It's also worth noting that returning the trigger functions doesn't clean up the mess either:

test_helpers.py

class NoisyThing:

    def __init__(self, name):
        log.info(f'starting NoisyThing {name}')
        self.name = name
        self.counter = 0

    def startup(self):
        @time_trigger("period(now, 1sec, now + 30sec)")
        def be_noisy():
            self.counter = self.counter + 1
            log.info(f'{self.name} counter {self.counter}')

        return be_noisy

test_script.py

from test_helpers import NoisyThing

a = NoisyThing('a')
a_triggers = a.startup()

@j-steve
Copy link

j-steve commented Jul 18, 2023

Like #281 I suspect this may've been caused by #457, so it could be fixed now that Craig has resolved that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants