[Python-checkins] peps: [PEP 451] Add namespace package support to example code and explain more about

eric.snow python-checkins at python.org
Tue Oct 29 06:00:43 CET 2013


http://hg.python.org/peps/rev/e8e5abad7e5c
changeset:   5232:e8e5abad7e5c
user:        Eric Snow <ericsnowcurrently at gmail.com>
date:        Mon Oct 28 22:56:35 2013 -0600
summary:
  [PEP 451] Add namespace package support to example code and explain more about reloading.

files:
  pep-0451.txt |  89 +++++++++++++++++++++++++++++++--------
  1 files changed, 69 insertions(+), 20 deletions(-)


diff --git a/pep-0451.txt b/pep-0451.txt
--- a/pep-0451.txt
+++ b/pep-0451.txt
@@ -295,6 +295,8 @@
   over its module execution functionality.
 * importlib.abc.Loader.create_module(spec) (optional) will return the
   module to use for loading.
+* importlib.abc.Loader.supports_reload(name) (optional) will return True
+  (the default) if the loader supports reloading the module.
 
 For modules:
 
@@ -445,27 +447,31 @@
 Here is an outline of what the import machinery does during loading,
 adjusted to take advantage of the module's spec and the new loader API::
 
-   module = None
-   if hasattr(spec.loader, 'create_module'):
-       module = spec.loader.create_module(spec)
-   if module is None:
-       module = ModuleType(spec.name)
-   # The import-related module attributes get set here:
-   _init_module_attrs(spec, module)
 
-   if not hasattr(spec.loader, 'exec_module'):
-       module = spec.loader.load_module(spec.name)
-   else:
-       sys.modules[spec.name] = module
-       try:
-           spec.loader.exec_module(module)
-       except BaseException:
-           try:
-               del sys.modules[spec.name]
-           except KeyError:
-               pass
-           raise
-   module_to_return = sys.modules[spec.name]
+    module = None
+    if spec.loader is not None and hasattr(spec.loader, 'create_module'):
+        module = spec.loader.create_module(spec)
+    if module is None:
+        module = ModuleType(spec.name)
+    # The import-related module attributes get set here:
+    _init_module_attrs(spec, module)
+
+    if spec.loader is None and spec.submodule_search_locations is not None:
+        # namespace package
+        sys.modules[spec.name] = module
+    elif not hasattr(spec.loader, 'exec_module'):
+        module = spec.loader.load_module(spec.name)
+    else:
+        sys.modules[spec.name] = module
+        try:
+            spec.loader.exec_module(module)
+        except BaseException:
+            try:
+                del sys.modules[spec.name]
+            except KeyError:
+                pass
+            raise
+    module_to_return = sys.modules[spec.name]
 
 These steps are exactly what Loader.load_module() is already
 expected to do.  Loaders will thus be simplified since they will only
@@ -479,6 +485,42 @@
 their own if they are doing this.
 
 
+How Reloading Will Work
+=======================
+
+Here is the corresponding outline for reload()::
+
+    _RELOADING = {}
+
+    def reload(module):
+        try:
+            name = module.__spec__.name
+        except AttributeError:
+            name = module.__name__
+        spec = find_spec(name)
+
+        if sys.modules.get(name) is not module:
+            raise ImportError
+        if spec in _RELOADING:
+            return _RELOADING[name]
+        _RELOADING[name] = module
+        try:
+            if spec.loader is None:
+                # namespace loader
+                _init_module_attrs(spec, module)
+                return module
+            if not spec.loader.supports_reload(name):
+                raise ImportError
+            if spec.parent and spec.parent not in sys.modules:
+                raise ImportError
+
+            _init_module_attrs(spec, module)
+            spec.loader.exec_module(module)
+            return sys.modules[name]
+        finally:
+            del _RELOADING[name]
+
+
 ModuleSpec
 ==========
 
@@ -749,6 +791,13 @@
    module attributes.  The fact that load_module() does is a design flaw
    that this proposal aims to correct.
 
+**Loader.supports_reload(name)**
+
+In cases where a module should not be reloaded, Loaders should implement
+supports_reload() and have it return False.  If the method is defined
+and returns a false value, importlib.reload() will raise an ImportError.
+Otherwise reloading proceeds as normal.
+
 Other changes:
 
 PEP 420 introduced the optional module_repr() loader method to limit

-- 
Repository URL: http://hg.python.org/peps


More information about the Python-checkins mailing list