python: Use importlib for python3.
[ashd.git] / python3 / ashd / wsgidir.py
index cc17b9b..16ca1b5 100644 (file)
@@ -37,7 +37,7 @@ must, of course, be importable). When writing such handler functions,
 you will probably want to use the getmod() function in this module.
 """
 
-import os, threading, types
+import os, threading, types, importlib
 from . import wsgiutil
 
 __all__ = ["application", "wmain", "getmod", "cachedmod"]
@@ -55,7 +55,7 @@ class cachedmod(object):
     Additional data attributes can be arbitrarily added for recording
     any meta-data about the module.
     """
-    def __init__(self, mod, mtime):
+    def __init__(self, mod = None, mtime = -1):
         self.lock = threading.Lock()
         self.mod = mod
         self.mtime = mtime
@@ -87,35 +87,30 @@ def getmod(path):
     about the module. See its documentation for details.
     """
     sb = os.stat(path)
-    cachelock.acquire()
-    try:
+    with cachelock:
         if path in modcache:
             entry = modcache[path]
-            if sb.st_mtime <= entry.mtime:
-                return entry
-        
-        f = open(path)
-        try:
-            text = f.read()
-        finally:
-            f.close()
-        code = compile(text, path, "exec")
-        mod = types.ModuleType(mangle(path))
-        mod.__file__ = path
-        exec(code, mod.__dict__)
-        entry = cachedmod(mod, sb.st_mtime)
-        modcache[path] = entry
+        else:
+            entry = cachedmod()
+            modcache[path] = entry
+    with entry.lock:
+        if entry.mod is None or sb.st_mtime > entry.mtime:
+            with open(path, "rb") as f:
+                text = f.read()
+            code = compile(text, path, "exec")
+            mod = types.ModuleType(mangle(path))
+            mod.__file__ = path
+            exec(code, mod.__dict__)
+            entry.mod = mod
+            entry.mtime = sb.st_mtime
         return entry
-    finally:
-        cachelock.release()
 
 def chain(env, startreq):
     path = env["SCRIPT_FILENAME"]
     mod = getmod(path)
     entry = None
     if mod is not None:
-        mod.lock.acquire()
-        try:
+        with mod.lock:
             if hasattr(mod, "entry"):
                 entry = mod.entry
             else:
@@ -124,8 +119,6 @@ def chain(env, startreq):
                 elif hasattr(mod.mod, "application"):
                     entry = mod.mod.application
                 mod.entry = entry
-        finally:
-            mod.lock.release()
     if entry is not None:
         return entry(env, startreq)
     return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "Invalid WSGI handler.")
@@ -136,7 +129,7 @@ def addext(ext, handler):
     p = handler.rindex('.')
     mname = handler[:p]
     hname = handler[p + 1:]
-    mod = __import__(mname, fromlist = ["dummy"])
+    mod = importlib.import_module(mname)
     exts[ext] = getattr(mod, hname)
 
 def application(env, startreq):