Skip to content

Instantly share code, notes, and snippets.

@reszelaz
Created July 15, 2021 21:18
Show Gist options
  • Save reszelaz/389fa8d262b5206879e98b0518d4be10 to your computer and use it in GitHub Desktop.
Save reszelaz/389fa8d262b5206879e98b0518d4be10 to your computer and use it in GitHub Desktop.
Demonstrate cycle reference creation when final enumeration over a generator yields a bound method.
"""
When line
yield {"hook": normal_hook}
is commented:
> In hook()
> After run_macro
> In Macro.__del__()
> In CTScan.__del__()
When line
yield {"hook": normal_hook}
is NOT commented:
> In hook()
> In normal_hook()
> In Macro.__del__()
> In CTScan.__del__()
> After run_macro
"""
from taurus.core.util.event import CallableRef
def normal_hook():
print("In normal_hook()")
class CTScan:
def __init__(self, generator):
self._generator = CallableRef(generator)
def __del__(self):
print("In CTScan.__del__()")
@property
def generator(self):
"""Generator of steps or waypoints used in this scan."""
return self._generator()
@property
def steps(self):
if not hasattr(self, "_steps"):
self._steps = enumerate(self.generator())
return self._steps
def scan(self):
for i, waypoint in enumerate(self.generator()):
waypoint["hook"]()
class Macro:
def __del__(self):
print("In Macro.__del__()")
def hook(self):
print("In hook()")
def generator(self):
yield {"hook": self.hook}
# yield {"hook": normal_hook}
def run(self):
self.gscan = CTScan(self.generator)
self.gscan.scan()
def run_macro():
macro = Macro()
macro.run()
if __name__ == "__main__":
run_macro()
print("After run_macro")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment