Changeset d321747 in sasmodels for sasmodels/custom/__init__.py
- Timestamp:
- Oct 1, 2018 7:20:17 PM (6 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- c11d09f
- Parents:
- a5bcd61
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/custom/__init__.py
r91bd550 rd321747 12 12 import sys 13 13 import os 14 from os.path import basename, splitext 14 from os.path import basename, splitext, join as joinpath, exists, dirname 15 15 16 16 try: … … 18 18 from importlib.util import spec_from_file_location, module_from_spec # type: ignore 19 19 def load_module_from_path(fullname, path): 20 # type: (str, str) -> "module" 20 21 """load module from *path* as *fullname*""" 21 22 spec = spec_from_file_location(fullname, os.path.expanduser(path)) … … 27 28 import imp 28 29 def load_module_from_path(fullname, path): 30 # type: (str, str) -> "module" 29 31 """load module from *path* as *fullname*""" 30 32 # Clear out old definitions, if any … … 37 39 return module 38 40 39 _MODULE_CACHE = {} 40 _MODULE_DEPENDS = {} 41 _MODULE_DEPENDS_STACK = [] 41 _MODULE_CACHE = {} # type: Dict[str, Tuple("module", int)] 42 _MODULE_DEPENDS = {} # type: Dict[str, List[str]] 43 _MODULE_DEPENDS_STACK = [] # type: List[str] 42 44 def load_custom_kernel_module(path): 45 # type: str -> "module" 43 46 """load SAS kernel from *path* as *sasmodels.custom.modelname*""" 44 47 # Pull off the last .ext if it exists; there may be others … … 46 49 path = os.path.expanduser(path) 47 50 48 # reload module if necessary51 # Reload module if necessary. 49 52 if need_reload(path): 50 # Push to the next dependency level 51 _MODULE_DEPENDS_STACK.append(path) 53 # Assume the module file is the only dependency 52 54 _MODULE_DEPENDS[path] = set([path]) 53 55 54 # Load module into the 'sasmodels.custom' name space. 55 # If this triggers any submodule loads then they will be added 56 # as dependencies below when _MODULE_DEPENDS_STACK is not empty. 56 # Load the module while pushing it onto the dependency stack. If 57 # this triggers any submodules, then they will add their dependencies 58 # to this module as the "working_on" parent. Pop the stack when the 59 # module is loaded. 60 _MODULE_DEPENDS_STACK.append(path) 57 61 module = load_module_from_path('sasmodels.custom.'+name, path) 58 59 # Pop the dependency level60 62 _MODULE_DEPENDS_STACK.pop() 61 63 62 # TODO: include external C code in the dependencies 63 # If we had the model info structure we could do the following: 64 # _MODEL_DEPENDS[path].extend(generate.model_sources(info)) 65 # but at this point all we have is the module. Don't want to 66 # repeat the logic in modelinfo.make_model_info. 64 # Include external C code in the dependencies. We are looking 65 # for module.source and assuming that it is a list of C source files 66 # relative to the module itself. Any files that do not exist, 67 # such as those in the standard libraries, will be ignored. 68 # TODO: look in builtin module path for standard c sources 69 # TODO: share code with generate.model_sources 70 c_sources = getattr(module, 'source', None) 71 if isinstance(c_sources, (list, tuple)): 72 _MODULE_DEPENDS[path].update(_find_sources(path, c_sources)) 67 73 68 # Cache the module with the newest timestamp74 # Cache the module, and tag it with the newest timestamp 69 75 timestamp = max(os.path.getmtime(f) for f in _MODULE_DEPENDS[path]) 70 76 _MODULE_CACHE[path] = module, timestamp … … 73 79 # [os.path.basename(p) for p in _MODULE_DEPENDS[path]]) 74 80 81 # Add path and all its dependence to the parent module, if there is one. 75 82 if _MODULE_DEPENDS_STACK: 76 # Add child and all its dependence to the parent module77 83 working_on = _MODULE_DEPENDS_STACK[-1] 78 84 _MODULE_DEPENDS[working_on].update(_MODULE_DEPENDS[path]) … … 81 87 82 88 def need_reload(path): 89 # type: str -> bool 90 """ 91 Return True if any path dependencies have a timestamp newer than the time 92 when the path was most recently loaded. 93 """ 83 94 # TODO: fails if a dependency has a modification time in the future 84 95 # If the newest dependency has a time stamp in the future, then this … … 92 103 _, cache_time = _MODULE_CACHE.get(path, (None, -1)) 93 104 depends = _MODULE_DEPENDS.get(path, [path]) 105 #print("reload", any(cache_time < os.path.getmtime(p) for p in depends)) 106 #for f in depends: print(">>> ", f, os.path.getmtime(f)) 94 107 return any(cache_time < os.path.getmtime(p) for p in depends) 108 109 def _find_sources(path, source_list): 110 # type: (str, List[str]) -> List[str] 111 """ 112 Return a list of the sources relative to base file; ignore any that 113 are not found. 114 """ 115 root = dirname(path) 116 found = [] 117 for source_name in source_list: 118 source_path = joinpath(root, source_name) 119 if exists(source_path): 120 found.append(source_path) 121 return found
Note: See TracChangeset
for help on using the changeset viewer.