Commit 67aefd1b authored by Jason R. Coombs's avatar Jason R. Coombs

Merge branch 'develop-nspkg-always' into issue250-module_from_spec

parents acd94990 3dd506f0
......@@ -9,10 +9,11 @@ from setuptools.extern import six
from pkg_resources import Distribution, PathMetadata, normalize_path
from setuptools.command.easy_install import easy_install
from setuptools import namespaces
import setuptools
class develop(easy_install):
class develop(namespaces.DevelopInstaller, easy_install):
"""Set up package for development"""
description = "install package in 'development mode'"
......@@ -30,6 +31,7 @@ class develop(easy_install):
if self.uninstall:
self.multi_version = True
self.uninstall_link()
self.uninstall_namespaces()
else:
self.install_for_development()
self.warn_deprecated_options()
......@@ -123,6 +125,8 @@ class develop(easy_install):
self.easy_install(setuptools.bootstrap_install_from)
setuptools.bootstrap_install_from = None
self.install_namespaces()
# create an .egg-link in the installation dir, pointing to our egg
log.info("Creating %s (link to %s)", self.egg_link, self.egg_base)
if not self.dry_run:
......
......@@ -31,21 +31,27 @@ class Installer:
with open(filename, 'wt') as f:
f.writelines(lines)
def uninstall_namespaces(self):
filename, ext = os.path.splitext(self._get_target())
filename += self.nspkg_ext
if not os.path.exists(filename):
return
log.info("Removing %s", filename)
os.remove(filename)
def _get_target(self):
return self.target
_nspkg_tmpl = (
"import sys, types, os, importlib.util, importlib.machinery",
"pep420 = (3, 3) < sys.version_info < (3, 5)",
"has_mfs = sys.version_info > (3, 5)",
"p = os.path.join(%(root)s, *%(pth)r)",
"ie = os.path.exists(os.path.join(p,'__init__.py'))",
"m = not ie and not pep420 and has_mfs and "
"m = has_mfs and "
"sys.modules.setdefault(%(pkg)r, "
"importlib.util.module_from_spec("
"importlib.machinery.PathFinder.find_spec(%(pkg)r, "
"[os.path.dirname(p)])))",
"m = not ie and not pep420 and not has_mfs and "
"m = not has_mfs 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)",
......
"""develop tests
"""
from __future__ import absolute_import, unicode_literals
import os
import site
import sys
import io
import subprocess
from setuptools.extern import six
......@@ -12,6 +16,7 @@ import pytest
from setuptools.command.develop import develop
from setuptools.dist import Distribution
from . import contexts
from . import namespaces
SETUP_PY = """\
from setuptools import setup
......@@ -114,3 +119,47 @@ class TestDevelop:
cmd.install_dir = tmpdir
cmd.run()
# assert '0.0' not in foocmd_text
class TestNamespaces:
@staticmethod
def install_develop(src_dir, target):
develop_cmd = [
sys.executable,
'setup.py',
'develop',
'--install-dir', str(target),
]
env = dict(PYTHONPATH=str(target))
with src_dir.as_cwd():
subprocess.check_call(develop_cmd, env=env)
def test_namespace_package_importable(self, tmpdir):
"""
Installing two packages sharing the same namespace, one installed
naturally using pip or `--single-version-externally-managed`
and the other installed using `develop` should leave the namespace
in tact and both packages reachable by import.
"""
pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
target = tmpdir / 'packages'
# use pip to install to the target directory
install_cmd = [
'pip',
'install',
str(pkg_A),
'-t', str(target),
]
subprocess.check_call(install_cmd)
self.install_develop(pkg_B, target)
namespaces.make_site_dir(target)
try_import = [
sys.executable,
'-c', 'import myns.pkgA; import myns.pkgB',
]
env = dict(PYTHONPATH=str(target))
subprocess.check_call(try_import, env=env)
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