diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2016-10-23 09:25:03 -0400 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2016-10-23 09:25:03 -0400 |
commit | d5494571842c63e4b1903d8f455727e408464ff5 (patch) | |
tree | 979b84e6221b98d6e04c8621550da6422e5f8c0d /setuptools/namespaces.py | |
parent | d382def1367e9d9b288e9b04b6f2da5987052b5b (diff) | |
download | external_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-x | setuptools/namespaces.py | 63 |
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) |