Commit af4cec25 authored by PJ Eby's avatar PJ Eby

Add experimental support for merging non-empty namespace packages. This

lets you have one distribution containing a non-empty __init__.py for the
package, as long as you call 'declare_namespace()' from that __init__.py
and all other __init__.py files for the namespace package, and do *not*
declare it as a namespace package in setup() (so that it won't be
automatically imported if it's on sys.path, the way empty namespace
packages are.)

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041202
parent 98ab5c90
...@@ -13,7 +13,7 @@ The package resource API is designed to work with normal filesystem packages, ...@@ -13,7 +13,7 @@ The package resource API is designed to work with normal filesystem packages,
method. method.
""" """
import sys, os, zipimport, time, re, imp import sys, os, zipimport, time, re, imp, new
from sets import ImmutableSet from sets import ImmutableSet
...@@ -1412,7 +1412,6 @@ def register_namespace_handler(importer_type, namespace_handler): ...@@ -1412,7 +1412,6 @@ def register_namespace_handler(importer_type, namespace_handler):
""" """
_namespace_handlers[importer_type] = namespace_handler _namespace_handlers[importer_type] = namespace_handler
def _handle_ns(packageName, path_item): def _handle_ns(packageName, path_item):
"""Ensure that named package includes a subpath of path_item (if needed)""" """Ensure that named package includes a subpath of path_item (if needed)"""
importer = get_importer(path_item) importer = get_importer(path_item)
...@@ -1421,18 +1420,19 @@ def _handle_ns(packageName, path_item): ...@@ -1421,18 +1420,19 @@ def _handle_ns(packageName, path_item):
loader = importer.find_module(packageName) loader = importer.find_module(packageName)
if loader is None: if loader is None:
return None return None
module = sys.modules.get(packageName)
module = sys.modules.get(packageName) or loader.load_module(packageName) if module is None:
if not hasattr(module,'__path__'): module = sys.modules[packageName] = new.module(packageName)
module.__path__ = []
elif not hasattr(module,'__path__'):
raise TypeError("Not a package:", packageName) raise TypeError("Not a package:", packageName)
handler = _find_adapter(_namespace_handlers, importer) handler = _find_adapter(_namespace_handlers, importer)
subpath = handler(importer,path_item,packageName,module) subpath = handler(importer,path_item,packageName,module)
if subpath is not None: if subpath is not None:
module.__path__.append(subpath) module.__path__.append(subpath)
loader.load_module(packageName)
return subpath return subpath
def declare_namespace(packageName): def declare_namespace(packageName):
"""Declare that package 'packageName' is a namespace package""" """Declare that package 'packageName' is a namespace package"""
...@@ -1451,16 +1451,16 @@ def declare_namespace(packageName): ...@@ -1451,16 +1451,16 @@ def declare_namespace(packageName):
except AttributeError: except AttributeError:
raise TypeError("Not a package:", parent) raise TypeError("Not a package:", parent)
for path_item in path:
# Ensure all the parent's path items are reflected in the child,
# if they apply
_handle_ns(packageName, path_item)
# Track what packages are namespaces, so when new path items are added, # Track what packages are namespaces, so when new path items are added,
# they can be updated # they can be updated
_namespace_packages.setdefault(parent,[]).append(packageName) _namespace_packages.setdefault(parent,[]).append(packageName)
_namespace_packages.setdefault(packageName,[]) _namespace_packages.setdefault(packageName,[])
for path_item in path:
# Ensure all the parent's path items are reflected in the child,
# if they apply
_handle_ns(packageName, path_item)
finally: finally:
imp.release_lock() imp.release_lock()
...@@ -1478,9 +1478,9 @@ def file_ns_handler(importer, path_item, packageName, module): ...@@ -1478,9 +1478,9 @@ def file_ns_handler(importer, path_item, packageName, module):
"""Compute an ns-package subpath for a filesystem or zipfile importer""" """Compute an ns-package subpath for a filesystem or zipfile importer"""
subpath = os.path.join(path_item, packageName.split('.')[-1]) subpath = os.path.join(path_item, packageName.split('.')[-1])
normalized = os.path.normpath(os.path.normcase(subpath)) normalized = normalize_path(subpath)
for item in module.__path__: for item in module.__path__:
if os.path.normpath(os.path.normcase(item))==normalized: if normalize_path(item)==normalized:
break break
else: else:
# Only return the path if it's not already there # Only return the path if it's not already there
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment