Package: refreshable
#doitlive - Tools for livecoding performances in Python.#doitlive allows you to “refresh” a class by reloading the source in analmost-sane andalmost-safe way. It also provides facilities for
catching and handling common errors that come up with livecoding, such
as undeclared variables.It works under the philosophy that it’s better to have weird behavior
than to crash.Besides livecoding, it can also be used as a tool for debugging or
experimenting – you can tweak algorithms as they run.Projectshttps://github.com/zbanks/beetlehttps://github.com/ervanalb/beat-off/tree/livehttps://github.com/zbanks/aurorahttps://github.com/zbanks/peebleshttps://github.com/ervanalb/noiseInstallationInstall from pip:pip install refreshableOr install the latest(ha!)from git:git clone https://github.com/zbanks/doitlive.git
cd doitlive
python setup.py installrefreshable.SafeRefreshableMixinProvides a.refresh()method to reload a classAdding theSafeRefreshMixinto a class allows you to “refresh” the
class using the.refresh()method. This method reloads the python
file the class came from and replaces all methods andclassvariables
(notinstance variables!) with the versions from the new file.The refresh is “safe” because it tries very hard to keep the program
running. On each refresh, a snapshot of the class is saved to form a
history. If an error is encountered while performing the refresh, the
state is reverted.In general, you can wrap calls to methods of your refreshed class in a
try block that catches all errors and call.revert()on failure.Additionally,DEFAULTSandAUTO_NONEprovide options for
handling missing attributes (preventingAttributeErrors).UsageYou can configure the behavior by setting the following class variables:STATICS: List of variable names (strings) that are not
refreshed.DEFAULTS: Dictionary of variable names -> values. If anAttributeErroris caught, and the attribute is inDEFAULTS,
the attribute is populated from the dictionary. This can be useful if
you need to initialize a new state variable.AUTO_NONE: IfTrue, catchAttributeErrorsand set the
attribute toNoneif the attribute is not inDEFAULTS.Additionally, there are the.pre_refresh()and.post_refresh()hooks which can be overridden.Once initialized, instances have the following methods:.init_defaults(): Initialize attributes from theDEFAULTSdict..refresh(): Attempt to reload the class from disk..revert(): Revert the changes from the previous.refresh()..purge(): Remove the state history. Each call to.refresh()takes a snapshot of the class. If you refresh often w/ a big class,
this can get large.Limitations.refresh()assumes all methods are bound (take aselfparameter). As a result, static/class methods (methods declared with@staticmethod, or@classmethod) will not be refreshed
properly. These method names should be added toSTATICSand they
will not be refreshed.This framework was designed around the singleton model with one
instance of the given refreshed class. It hasn’t been extensively
tested with multiple instances, and may cause weird behavior around
class variables.The__main__module cannot be reloaded, so the class must exist
in an imported module.refreshable.SafeRefreshableLoopRun a function in a loop while making the parent class refreshable.The function.step()is called repeatedly while the loop is running.
You can start the loop in one of two ways:.start(): Run the loop in a thread..run(): (the target of the thread) Run the loop “inline”.The loop can also be paused with.stop()and unpaused with.restart().If you subclass, make sure you callthreading.Thread.__init__As with the SafeRefreshMixin, you can set the following class variables:STATICS: List of variable names (strings) that are not
refreshed.DEFAULTS: Dictionary of variable names -> values. If anAttributeErroris caught, and the attribute is inDEFAULTS,
the attribute is populated from the dictionary. This can be useful if
you need to initialize a new state variable.AUTO_NONE: IfTrue, catchAttributeErrorsand set the
attribute toNoneif the attribute is not inDEFAULTS.And call the following methods:.refresh(): Attempt to reload the class from disk..revert(): Revert the changes from the previous.refresh()..purge(): Remove the state history. Each call to.refresh()takes a snapshot of the class. If you refresh often w/ a big class,
this can get large.Additionally, there are the.pre_refresh()and.post_refresh()hooks which can be overridden.TestingTest it out by runningpython run_test.pyand modifyingtest.py.