aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/namespaces.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2016-10-23 09:25:03 -0400
committerJason R. Coombs <jaraco@jaraco.com>2016-10-23 09:25:03 -0400
commitd5494571842c63e4b1903d8f455727e408464ff5 (patch)
tree979b84e6221b98d6e04c8621550da6422e5f8c0d /setuptools/namespaces.py
parentd382def1367e9d9b288e9b04b6f2da5987052b5b (diff)
downloadexternal_python_setuptools-d5494571842c63e4b1903d8f455727e408464ff5.tar.gz
external_python_setuptools-d5494571842c63e4b1903d8f455727e408464ff5.tar.bz2
external_python_setuptools-d5494571842c63e4b1903d8f455727e408464ff5.zip
Extract namespace handling into a separate module and mix-in class.
Diffstat (limited to 'setuptools/namespaces.py')
-rwxr-xr-xsetuptools/namespaces.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/setuptools/namespaces.py b/setuptools/namespaces.py
new file mode 100755
index 00000000..13829521
--- /dev/null
+++ b/setuptools/namespaces.py
@@ -0,0 +1,63 @@
+import os
+from distutils import log
+
+from setuptools.extern.six.moves import map
+
+
+class Installer:
+
+ def install_namespaces(self):
+ nsp = self._get_all_ns_packages()
+ if not nsp:
+ return
+ filename, ext = os.path.splitext(self.target)
+ filename += '-nspkg.pth'
+ self.outputs.append(filename)
+ log.info("Installing %s", filename)
+ lines = map(self._gen_nspkg_line, nsp)
+
+ if self.dry_run:
+ # always generate the lines, even in dry run
+ list(lines)
+ return
+
+ with open(filename, 'wt') as f:
+ f.writelines(lines)
+
+ _nspkg_tmpl = (
+ "import sys, types, os",
+ "pep420 = sys.version_info > (3, 3)",
+ "p = os.path.join(sys._getframe(1).f_locals['sitedir'], *%(pth)r)",
+ "ie = os.path.exists(os.path.join(p,'__init__.py'))",
+ "m = not ie and not pep420 and "
+ "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))",
+ "mp = (m or []) and m.__dict__.setdefault('__path__',[])",
+ "(p not in mp) and mp.append(p)",
+ )
+ "lines for the namespace installer"
+
+ _nspkg_tmpl_multi = (
+ 'm and setattr(sys.modules[%(parent)r], %(child)r, m)',
+ )
+ "additional line(s) when a parent package is indicated"
+
+ @classmethod
+ def _gen_nspkg_line(cls, pkg):
+ # ensure pkg is not a unicode string under Python 2.7
+ pkg = str(pkg)
+ pth = tuple(pkg.split('.'))
+ tmpl_lines = cls._nspkg_tmpl
+ parent, sep, child = pkg.rpartition('.')
+ if parent:
+ tmpl_lines += cls._nspkg_tmpl_multi
+ return ';'.join(tmpl_lines) % locals() + '\n'
+
+ def _get_all_ns_packages(self):
+ """Return sorted list of all package namespaces"""
+ nsp = set()
+ for pkg in self.distribution.namespace_packages or []:
+ pkg = pkg.split('.')
+ while pkg:
+ nsp.add('.'.join(pkg))
+ pkg.pop()
+ return sorted(nsp)