11 from setuptools.command import test
15 from setuptools.command.develop import develop
16 from setuptools.dist import Distribution
17 from . import contexts
18 from . import namespaces
21 from setuptools import setup
28 INIT_PY = """print "foo"
33 def temp_user(monkeypatch):
34 with contexts.tempdir() as user_base:
35 with contexts.tempdir() as user_site:
36 monkeypatch.setattr('site.USER_BASE', user_base)
37 monkeypatch.setattr('site.USER_SITE', user_site)
42 def test_env(tmpdir, temp_user):
44 foo = target.mkdir('foo')
45 setup = target / 'setup.py'
47 raise ValueError(dir(target))
48 with setup.open('w') as f:
50 init = foo / '__init__.py'
51 with init.open('w') as f:
58 in_virtualenv = hasattr(sys, 'real_prefix')
59 in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix
61 def test_console_scripts(self, tmpdir):
63 Test that console scripts are installed and that they reference
64 only the project by name and not the current version.
67 "TODO: needs a fixture to cause 'develop' "
68 "to be invoked without mutating environment."
80 dist = Distribution(settings)
81 dist.script_name = 'setup.py'
83 cmd.ensure_finalized()
84 cmd.install_dir = tmpdir
86 # assert '0.0' not in foocmd_text
91 TODO: These tests were written with a minimal understanding
92 of what _resolve_setup_path is intending to do. Come up with
93 more meaningful cases that look like real-world scenarios.
96 def test_resolve_setup_path_cwd(self):
97 assert develop._resolve_setup_path('.', '.', '.') == '.'
99 def test_resolve_setup_path_one_dir(self):
100 assert develop._resolve_setup_path('pkgs', '.', 'pkgs') == '../'
102 def test_resolve_setup_path_one_dir_trailing_slash(self):
103 assert develop._resolve_setup_path('pkgs/', '.', 'pkgs') == '../'
106 class TestNamespaces:
108 def install_develop(src_dir, target):
117 with src_dir.as_cwd():
118 with test.test.paths_on_pythonpath([str(target)]):
119 subprocess.check_call(develop_cmd)
122 bool(os.environ.get("APPVEYOR")),
123 reason="https://github.com/pypa/setuptools/issues/851",
126 platform.python_implementation() == 'PyPy',
127 reason="https://github.com/pypa/setuptools/issues/1202",
129 def test_namespace_package_importable(self, tmpdir):
131 Installing two packages sharing the same namespace, one installed
132 naturally using pip or `--single-version-externally-managed`
133 and the other installed using `develop` should leave the namespace
134 in tact and both packages reachable by import.
136 pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
137 pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
138 target = tmpdir / 'packages'
139 # use pip to install to the target directory
149 subprocess.check_call(install_cmd)
150 self.install_develop(pkg_B, target)
151 namespaces.make_site_dir(target)
155 'import myns.pkgA; import myns.pkgB',
157 with test.test.paths_on_pythonpath([str(target)]):
158 subprocess.check_call(try_import)
160 # additionally ensure that pkg_resources import works
161 pkg_resources_imp = [
164 'import pkg_resources',
166 with test.test.paths_on_pythonpath([str(target)]):
167 subprocess.check_call(pkg_resources_imp)
170 def install_workaround(site_packages):
171 site_packages.mkdir(parents=True)
172 sc = site_packages / 'sitecustomize.py'
178 here = pathlib.Path(__file__).parent
179 site.addsitedir(str(here))
185 platform.python_implementation() == 'PyPy',
186 reason="Workaround fails on PyPy (why?)",
188 def test_editable_prefix(self, tmp_path, sample_project):
190 Editable install to a prefix should be discoverable.
192 prefix = tmp_path / 'prefix'
195 # figure out where pip will likely install the package
196 site_packages = prefix / next(
197 pathlib.Path(path).relative_to(sys.prefix)
199 if 'site-packages' in path and path.startswith(sys.prefix)
202 # install the workaround
203 self.install_workaround(site_packages)
205 env = dict(os.environ, PYTHONPATH=str(site_packages))
215 '--no-build-isolation',
217 subprocess.check_call(cmd, env=env)
219 # now run 'sample' with the prefix on the PYTHONPATH
220 bin = 'Scripts' if platform.system() == 'Windows' else 'bin'
221 exe = prefix / bin / 'sample'
222 if sys.version_info < (3, 7) and platform.system() == 'Windows':
224 subprocess.check_call([exe], env=env)