diff --git a/labscript_utils/device_registry/_device_registry.py b/labscript_utils/device_registry/_device_registry.py index 0c64cb2..e5a122a 100644 --- a/labscript_utils/device_registry/_device_registry.py +++ b/labscript_utils/device_registry/_device_registry.py @@ -1,3 +1,4 @@ +import importlib.machinery import os import importlib import warnings @@ -6,11 +7,6 @@ from labscript_utils import dedent from labscript_utils.labconfig import LabConfig -# deal with removal of imp from python 3.12 -try: - import _imp as imp -except ImportError: - import imp """This file contains the machinery for registering and looking up what BLACS tab and runviewer parser classes belong to a particular labscript device. "labscript device" @@ -253,20 +249,19 @@ def register_classes(labscript_device_name, BLACS_tab=None, runviewer_parser=Non def populate_registry(): """Walk the labscript_devices folder looking for files called register_classes.py, - and run them (i.e. import them). These files are expected to make calls to + and run them. These files are expected to make calls to register_classes() to inform us of what BLACS tabs and runviewer classes correspond to their labscript device classes.""" - # We import the register_classes modules as a direct submodule of labscript_devices. - # But they cannot all have the same name, so we import them as - # labscript_devices._register_classes_script_ with increasing number. - module_num = 0 + # We execute the register_classes modules as a direct submodule of labscript_devices. for devices_dir in LABSCRIPT_DEVICES_DIRS: for folder, _, filenames in os.walk(devices_dir): if 'register_classes.py' in filenames: # The module name is the path to the file, relative to the labscript suite # install directory: - # Open the file using the import machinery, and import it as module_name. - fp, pathname, desc = imp.find_module('register_classes', [folder]) - module_name = 'labscript_devices._register_classes_%d' % module_num - _ = imp.load_module(module_name, fp, pathname, desc) - module_num += 1 + # Open the file using the import machinery, and run it + spec = importlib.machinery.PathFinder.find_spec('register_classes', [folder]) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + # fully importing module would require adding to sys.modules + # and each import would need to have unique names + # but we just need to run the registering code, not actually import the module diff --git a/labscript_utils/modulewatcher.py b/labscript_utils/modulewatcher.py index d9029dd..ec1cdb1 100644 --- a/labscript_utils/modulewatcher.py +++ b/labscript_utils/modulewatcher.py @@ -17,12 +17,6 @@ import site import sysconfig -# deal with removal of imp from python 3.12 -try: - import _imp as imp -except ImportError: - import imp - # Directories in which the standard library and installed packages may be located. # Modules in these locations will be whitelisted: @@ -63,16 +57,8 @@ def mainloop(self): while True: time.sleep(1) with self.lock: - # Acquire the import lock so that we don't unload modules whilst an - # import is in progess: - imp.acquire_lock() - try: - if self.check(): - self.unload() - finally: - # We're done mucking around with the cached modules, normal imports - # in other threads may resume: - imp.release_lock() + if self.check(): + self.unload() def check(self): unload_required = False @@ -138,3 +124,32 @@ def unload(self): # code holds references to sys.meta_path, and to preserve order, since order # is relevant. sys.meta_path[:] = self.meta_whitelist + +if __name__ == "__main__": + + from pathlib import Path + import time + + dict1 = {'t': 5, 'val': 10} + dict2 = {'t': 5, 'val': 11} + + print('ModuleWatcher instatiated in debug mode') + module_watcher = ModuleWatcher(debug=True) + + # import a local module + import labscript_utils.dict_diff + print('imported labscript_utils.dict_diff') + print(labscript_utils.dict_diff.dict_diff(dict1, dict2)) + print('used dict_diff function, waiting 2 seconds for module watcher to update') + time.sleep(2) + + # now pretend it has been updated + ex_mod = Path('dict_diff.py') + ex_mod.touch() + print('dict_diff module touched, waiting 2 seconds for ModuleWatcher to notice') + time.sleep(2) + + print(labscript_utils.dict_diff.dict_diff(dict1, dict2)) + print('Used dict_diff again, waiting 2 seconds for ModuleWatcher to not do anything') + time.sleep(2) + \ No newline at end of file