Created
February 3, 2016 10:05
-
-
Save Arseny-N/8c7f6201984975683bef to your computer and use it in GitHub Desktop.
Import a module and reimport it every time it changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from importlib import reload, import_module | |
from os import stat | |
class auto_import(object): | |
""" | |
auto_import(mod, pkg = None, brute = False, verbose=False) : | |
Description: | |
Import a module and reimport it every time it changes. | |
Useful in a REPL, when debugging some functions from a file. | |
Usage: | |
>> foo = auto_import('foo.py') | |
>> foo.bar() | |
... edit foo.py | |
>> foo.bar() # <-- reloaded | |
Options: | |
mod - file or module to import | |
pkg - package argument to importlib.import_module | |
brute - reload the module revery time a properyt is accessed | |
verbose - if set to 1 then print a message every time a module is reloaded | |
if set to 2 then print a message every time a property is accessed | |
""" | |
def __init__(self, mod, pkg = None, brute = False, verbose=False): | |
if mod[-3:] == ".py": | |
mod = mod[:-3] | |
self._module = import_module(mod, package = pkg) | |
self._cfg = { 'verbose' : verbose, 'brute' : brute } | |
self._reload(True) | |
def _do_reload(self): | |
module = reload(self._module) | |
is_not_special = lambda x: not (x[:2] == x[-2:] == '__') | |
bind_values = lambda x: (x, getattr(self._module, x)) | |
new_dict = dict(map(bind_values , filter(is_not_special, dir(module)))) | |
new_dict.update({ | |
'_module' : module, | |
'_cfg' : self._cfg, | |
'_reload' : self._reload, | |
'_do_reload' : self._do_reload, | |
}) | |
self.__dict__.clear() | |
self.__dict__.update(new_dict ) | |
def _reload(self, force=False): | |
if self._cfg['brute'] or force: | |
print("Reloading: brute option set to True or forced") \ | |
if self._cfg['verbose'] else None | |
self._do_reload() | |
return | |
attrs = dir(self._module) | |
file = self._module.__file__ if '__file__' in attrs else None | |
cached = self._module.__cached__ if '__cached__' in attrs else None | |
if None in [file, cached]: | |
print("Reloading: __file__ or __cache__ attributes not set") \ | |
if self._cfg['verbose'] else None | |
self._do_reload() | |
return | |
else: | |
ftime = stat(file).st_atime | |
ctime = stat(cached).st_atime | |
if ftime > ctime: | |
print("Reloading: cache is older then file") \ | |
if self._cfg['verbose'] else None | |
self._do_reload() | |
return | |
print('Not Relaoding') if self._cfg['verbose'] == 2 else None | |
def __getattribute__(self, item): | |
if item not in ['_module','_reload', '_do_reload', '__dict__', '_cfg']: | |
self._reload() | |
return super().__getattribute__(item) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment