Merge branch 'master' into timeheap
[ashd.git] / python3 / ashd / wsgidir.py
index fc7e9ab..9fc3649 100644 (file)
@@ -58,6 +58,20 @@ class cachedmod(object):
         self.mod = mod
         self.mtime = mtime
 
+class current(object):
+    def __init__(self):
+        self.cond = threading.Condition()
+        self.current = True
+    def wait(self, timeout=None):
+        with self.cond:
+            self.cond.wait(timeout)
+    def uncurrent(self):
+        with self.cond:
+            self.current = False
+            self.cond.notify_all()
+    def __bool__(self):
+        return self.current
+
 modcache = {}
 cachelock = threading.Lock()
 
@@ -97,10 +111,39 @@ def getmod(path):
             code = compile(text, path, "exec")
             mod = types.ModuleType(mangle(path))
             mod.__file__ = path
-            exec(code, mod.__dict__)
-            entry[1] = cachedmod(mod, sb.st_mtime)
+            mod.__current__ = current()
+            try:
+                exec(code, mod.__dict__)
+            except:
+                mod.__current__.uncurrent()
+                raise
+            else:
+                if entry[1] is not None:
+                    entry[1].mod.__current__.uncurrent()
+                entry[1] = cachedmod(mod, sb.st_mtime)
         return entry[1]
 
+def importlocal(filename):
+    import inspect
+    cf = inspect.currentframe()
+    if cf is None: raise ImportError("could not get current frame")
+    if cf.f_back is None: raise ImportError("could not get caller frame")
+    cfile = cf.f_back.f_code.co_filename
+    if not os.path.exists(cfile):
+        raise ImportError("caller is not in a proper file")
+    path = os.path.realpath(os.path.join(os.path.dirname(cfile), filename))
+    if '.' not in os.path.basename(path):
+        for ext in [".pyl", ".py"]:
+            if os.path.exists(path + ext):
+                path += ext
+                break
+        else:
+            raise ImportError("could not resolve file: " + filename)
+    else:
+        if not os.path.exists(cfile):
+            raise ImportError("no such file: " + filename)
+    return getmod(path).mod
+
 class handler(object):
     def __init__(self):
         self.lock = threading.Lock()