def test_installer_required_extras_should_be_installed( locker, repo, package, installed, env, mocker ): pool = Pool() pool.add_repository(MockRepository()) installer = Installer(NullIO(), env, package, locker, pool, installed=installed) package.add_dependency( "cachecontrol", {"version": "^0.12.5", "extras": ["filecache"]} ) installer.update(True) installer.run() assert len(installer.installer.installs) == 2 assert len(installer.installer.updates) == 0 assert len(installer.installer.removals) == 0 locker.locked(True) locker.mock_lock_data(locker.written_data) installer = Installer(NullIO(), env, package, locker, pool, installed=installed) installer.update(True) installer.run() assert len(installer.installer.installs) == 2 assert len(installer.installer.updates) == 0 assert len(installer.installer.removals) == 0
def test_find_packages(): poetry = Factory().create_poetry(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) base = project("complete") include = PackageInclude(base, "my_package") pkg_dir, packages, pkg_data = builder.find_packages(include) assert pkg_dir is None assert packages == ["my_package", "my_package.sub_pkg1", "my_package.sub_pkg2"] assert pkg_data == { "": ["*"], "my_package": ["data1/*"], "my_package.sub_pkg2": ["data2/*"], } poetry = Factory().create_poetry(project("source_package")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) base = project("source_package") include = PackageInclude(base, "package_src", source="src") pkg_dir, packages, pkg_data = builder.find_packages(include) assert pkg_dir == str(base / "src") assert packages == ["package_src"] assert pkg_data == {"": ["*"]}
def test_installer_can_handle_old_lock_files(installer, locker, package, repo, installed, config): pool = Pool() pool.add_repository(MockRepository()) package.add_dependency("pytest", "^3.5", category="dev") locker.locked() locker.mock_lock_data(fixture("old-lock")) installer = Installer(NullIO(), MockEnv(), package, locker, pool, config, installed=installed) installer.run() assert 6 == len(installer.installer.installs) installer = Installer( NullIO(), MockEnv(version_info=(2, 7, 18)), package, locker, pool, config, installed=installed, ) installer.run() # funcsigs will be added assert 7 == len(installer.installer.installs) installer = Installer( NullIO(), MockEnv(version_info=(2, 7, 18), platform="win32"), package, locker, pool, config, installed=installed, ) installer.run() # colorama will be added assert 8 == len(installer.installer.installs)
def test_wheel_localversionlabel(): module_path = fixtures_dir / "localversionlabel" project = Factory().create_poetry(module_path) WheelBuilder.make(project, NullEnv(), NullIO()) local_version_string = "localversionlabel-0.1b1+gitbranch.buildno.1" whl = module_path / "dist" / (local_version_string + "-py2.py3-none-any.whl") assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert local_version_string + ".dist-info/METADATA" in z.namelist() uploader = Uploader(project, NullIO()) assert whl in uploader.files
def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ones_first( manager, poetry, config, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] poetry.package.python_versions = "^3.6" venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) mocker.patch("sys.version_info", (2, 7, 16)) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.7.5")), ) m = mocker.patch( "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "" ) manager.create_venv(NullIO()) m.assert_called_with( Path("/foo/virtualenvs/{}-py3.7".format(venv_name)), executable="python3", flags={"always-copy": False}, )
def test_create_venv_uses_patch_version_to_detect_compatibility( manager, poetry, config, mocker, config_virtualenvs_path): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) poetry.package.python_versions = "^{}".format(".".join( str(c) for c in sys.version_info[:3])) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) mocker.patch("sys.version_info", (version.major, version.minor, version.patch + 1)) check_output = mocker.patch( "subprocess.check_output", side_effect=check_output_wrapper(Version.parse("3.6.9")), ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "") manager.create_venv(NullIO()) assert not check_output.called m.assert_called_with( config_virtualenvs_path / "{}-py{}.{}".format(venv_name, version.major, version.minor), executable=None, flags={"always-copy": False}, )
def test_wheel_prerelease(): module_path = fixtures_dir / "prerelease" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) whl = module_path / "dist" / "prerelease-0.1b1-py2.py3-none-any.whl" assert whl.exists()
def test_deactivate_non_activated_but_existing( tmp_dir, manager, poetry, config, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) ( Path(tmp_dir) / "{}-py{}".format(venv_name, ".".join(str(c) for c in sys.version_info[:2])) ).mkdir() config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(), ) manager.deactivate(NullIO()) env = manager.get() assert env.path == Path(tmp_dir) / "{}-py{}".format( venv_name, ".".join(str(c) for c in sys.version_info[:2]) ) assert Path("/prefix")
def test_create_venv_fails_if_no_compatible_python_version_could_be_found( manager, poetry, config, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] poetry.package.python_versions = "^4.8" mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=["", "", "", ""] ) m = mocker.patch( "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "" ) with pytest.raises(NoCompatiblePythonVersionFound) as e: manager.create_venv(NullIO()) expected_message = ( "Poetry was unable to find a compatible version. " "If you have one, you can explicitly use it " 'via the "env use" command.' ) assert expected_message == str(e.value) assert 0 == m.call_count
def test_create_venv_uses_patch_version_to_detect_compatibility( manager, poetry, config, mocker): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) poetry.package.python_versions = "^{}".format(".".join( str(c) for c in sys.version_info[:3])) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=["2.7.16" for _ in range(3)] + [f"{version.major}.{version.minor}.{version.patch + 1}"], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "") manager.create_venv(NullIO()) m.assert_called_with( Path("{}/virtualenvs/{}-py{}.{}".format(config.get("cache-dir"), venv_name, version.major, version.minor)), executable="python3", )
def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( manager, poetry, config, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] version = Version.parse(".".join(str(c) for c in sys.version_info[:3])) poetry.package.python_versions = "~{}".format( ".".join(str(c) for c in (version.major, version.minor - 1, 0)) ) venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) check_output = mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper( Version.parse("{}.{}.0".format(version.major, version.minor - 1)) ), ) m = mocker.patch( "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "" ) manager.create_venv( NullIO(), executable="python{}.{}".format(version.major, version.minor - 1) ) assert check_output.called m.assert_called_with( Path( "/foo/virtualenvs/{}-py{}.{}".format( venv_name, version.major, version.minor - 1 ) ), executable="python{}.{}".format(version.major, version.minor - 1), )
def test_package_src(): module_path = fixtures_dir / "source_package" builder = CompleteBuilder( Factory().create_poetry(module_path), NullEnv(execute=True), NullIO() ) builder.build() sdist = module_path / "dist" / "package-src-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "package-src-0.1/src/package_src/module.py" in tar.getnames() whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl" assert whl.exists() zip = zipfile.ZipFile(str(whl)) try: assert "package_src/__init__.py" in zip.namelist() assert "package_src/module.py" in zip.namelist() finally: zip.close()
def test_make_setup(): poetry = Factory().create_poetry(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert ns["packages"] == [ "my_package", "my_package.sub_pkg1", "my_package.sub_pkg2", ] assert ns["install_requires"] == ["cachy[msgpack]>=0.2.0,<0.3.0", "cleo>=0.6,<0.7"] assert ns["entry_points"] == { "console_scripts": [ "extra-script = my_package.extra:main[time]", "my-2nd-script = my_package:main2", "my-script = my_package:main", ] } assert ns["extras_require"] == { 'time:python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"': [ "pendulum>=1.4,<2.0" ] }
def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( manager, poetry, config, tmp_dir, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] config.merge( { "virtualenvs": { "path": str(Path(tmp_dir) / "virtualenvs"), "in-project": True, } } ) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "poetry.utils._compat.subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv") manager.activate("python3.7", NullIO()) m.assert_called_with(poetry.file.parent / ".venv", executable="python3.7") envs_file = TOMLFile(Path(tmp_dir) / "virtualenvs" / "envs.toml") assert not envs_file.exists()
def test_activate_activates_non_existing_virtualenv_no_envs_file( tmp_dir, config, mocker): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] config.add_property("settings.virtualenvs.path", str(tmp_dir)) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "poetry.utils._compat.subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = EnvManager(config).activate("python3.7", CWD, NullIO()) venv_name = EnvManager.generate_env_name("simple_project", str(CWD)) m.assert_called_with(os.path.join(tmp_dir, "{}-py3.7".format(venv_name)), executable="python3.7") envs_file = TomlFile(Path(tmp_dir) / "envs.toml") assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.7" assert envs[venv_name]["patch"] == "3.7.1" assert env.path == Path(tmp_dir) / "{}-py3.7".format(venv_name) assert env.base == Path("/prefix")
def test_build_should_temporarily_remove_the_pyproject_file(tmp_dir, mocker): move = mocker.patch("shutil.move") tmp_dir = Path(tmp_dir) env = MockEnv(path=tmp_dir, pip_version="19.1", execute=False, sys_path=[]) module_path = fixtures_dir / "extended" builder = EditableBuilder(Factory().create_poetry(module_path), env, NullIO()) builder.build() expected = [[ sys.executable, "-m", "pip", "install", "-e", str(module_path) ]] assert expected == env.executed assert 2 == move.call_count expected_calls = [ mocker.call(str(module_path / "pyproject.toml"), str(module_path / "pyproject.tmp")), mocker.call(str(module_path / "pyproject.tmp"), str(module_path / "pyproject.toml")), ] assert expected_calls == move.call_args_list
def find_latest_package(self, package, include_dev): from clikit.io import NullIO from poetry.puzzle.provider import Provider from poetry.version.version_selector import VersionSelector # find the latest version allowed in this pool if package.source_type in ("git", "file", "directory"): requires = self.poetry.package.requires if include_dev: requires = requires + self.poetry.package.dev_requires for dep in requires: if dep.name == package.name: provider = Provider(self.poetry.package, self.poetry.pool, NullIO()) if dep.is_vcs(): return provider.search_for_vcs(dep)[0] if dep.is_file(): return provider.search_for_file(dep)[0] if dep.is_directory(): return provider.search_for_directory(dep)[0] name = package.name selector = VersionSelector(self.poetry.pool) return selector.find_best_candidate( name, ">={}".format(package.pretty_version))
def test_activate_activates_existing_virtualenv_no_envs_file( tmp_dir, manager, poetry, config, mocker ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent)) os.mkdir(os.path.join(tmp_dir, "{}-py3.7".format(venv_name))) config.merge({"virtualenvs": {"path": str(tmp_dir)}}) mocker.patch( "poetry.utils._compat.subprocess.check_output", side_effect=check_output_wrapper(), ) mocker.patch( "poetry.utils._compat.subprocess.Popen.communicate", side_effect=[("/prefix", None)], ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.7", NullIO()) m.assert_not_called() envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") assert envs_file.exists() envs = envs_file.read() assert envs[venv_name]["minor"] == "3.7" assert envs[venv_name]["patch"] == "3.7.1" assert env.path == Path(tmp_dir) / "{}-py3.7".format(venv_name) assert env.base == Path("/prefix")
def test_src_excluded_nested_data(): module_path = fixtures_dir / "exclude_nested_data_toml" poetry = Factory().create_poetry(module_path) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = module_path / "dist" / "my-package-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "my-package-1.2.3/LICENSE" in names assert "my-package-1.2.3/README.rst" in names assert "my-package-1.2.3/pyproject.toml" in names assert "my-package-1.2.3/setup.py" in names assert "my-package-1.2.3/PKG-INFO" in names assert "my-package-1.2.3/my_package/__init__.py" in names assert "my-package-1.2.3/my_package/data/sub_data/data2.txt" not in names assert "my-package-1.2.3/my_package/data/sub_data/data3.txt" not in names assert "my-package-1.2.3/my_package/data/data1.txt" not in names assert "my-package-1.2.3/my_package/puplic/publicdata.txt" in names assert "my-package-1.2.3/my_package/public/item1/itemdata1.txt" not in names assert ( "my-package-1.2.3/my_package/public/item1/subitem/subitemdata.txt" not in names ) assert "my-package-1.2.3/my_package/public/item2/itemdata2.txt" not in names
def test_installer_required_extras_should_not_be_removed_when_updating_single_dependency_pypi_repository( locker, repo, package, installed, env, mocker, config): mocker.patch("sys.platform", "darwin") pool = Pool() pool.add_repository(MockRepository()) installer = Installer(NullIO(), env, package, locker, pool, config, installed=installed) package.add_dependency("poetry", {"version": "^0.12.0"}) installer.update(True) installer.run() assert len(installer.installer.installs) == 3 assert len(installer.installer.updates) == 0 assert len(installer.installer.removals) == 0 package.add_dependency("pytest", "^3.5") locker.locked(True) locker.mock_lock_data(locker.written_data) for pkg in installer.installer.installs: installed.add_package(pkg) installer = Installer(NullIO(), env, package, locker, pool, config, installed=installed) installer.update(True) installer.whitelist(["pytest"]) installer.run() assert len(installer.installer.installs) == 6 if not PY2 else 7 assert len(installer.installer.updates) == 0 assert len(installer.installer.removals) == 0
def build_sdist(sdist_directory, config_settings=None): """Builds an sdist, places it in sdist_directory""" poetry = Factory().create_poetry(Path(".")) path = SdistBuilder(poetry, SystemEnv(Path(sys.prefix)), NullIO()).build(Path(sdist_directory)) return unicode(path.name)
def installer(package, pool, locker, env, installed, config): return Installer(NullIO(), env, package, locker, pool, config, installed=installed)
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): """Builds a wheel, places it in wheel_directory""" poetry = Factory().create_poetry(Path(".")) return unicode( WheelBuilder.make_in(poetry, SystemEnv(Path(sys.prefix)), NullIO(), Path(wheel_directory)))
def test_make_pkg_info(mocker): get_metadata_content = mocker.patch( "poetry.masonry.builders.builder.Builder.get_metadata_content") poetry = Factory().create_poetry(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build_pkg_info() assert get_metadata_content.called
def call_sub(self, name, args="", silent=False): """call() equivalent which supports subcommands""" names = name.split(" ") command = self.application.get_command(names[0]) for name in names[1:]: command = command.get_sub_command(name) args = StringArgs(args) return command.run(args, silent and NullIO() or self.io)
def test_make_pkg_info_any_python(): poetry = Factory().create_poetry(project("module1")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert "Requires-Python" not in parsed
def test_default_with_excluded_data(mocker): # Patch git module to return specific excluded files p = mocker.patch("poetry.vcs.git.Git.get_ignored_files") p.return_value = [ ( ( Path(__file__).parent / "fixtures" / "default_with_excluded_data" / "my_package" / "data" / "sub_data" / "data2.txt" ) .relative_to(project("default_with_excluded_data")) .as_posix() ) ] poetry = Factory().create_poetry(project("default_with_excluded_data")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) # Check setup.py setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert "package_dir" not in ns assert ns["packages"] == ["my_package"] assert ns["package_data"] == { "": ["*"], "my_package": ["data/*", "data/sub_data/data3.txt"], } builder.build() sdist = ( fixtures_dir / "default_with_excluded_data" / "dist" / "my-package-1.2.3.tar.gz" ) assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "my-package-1.2.3/LICENSE" in names assert "my-package-1.2.3/README.rst" in names assert "my-package-1.2.3/my_package/__init__.py" in names assert "my-package-1.2.3/my_package/data/data1.txt" in names assert "my-package-1.2.3/pyproject.toml" in names assert "my-package-1.2.3/setup.py" in names assert "my-package-1.2.3/PKG-INFO" in names # all last modified times should be set to a valid timestamp for tarinfo in tar.getmembers(): assert 0 < tarinfo.mtime
def test_proper_python_requires_if_three_digits_precision_version_specified(): poetry = Factory().create_poetry(project("single_python")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert parsed["Requires-Python"] == "==2.7.15"
def test_prelease(): poetry = Factory().create_poetry(project("prerelease")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = fixtures_dir / "prerelease" / "dist" / "prerelease-0.1b1.tar.gz" assert sdist.exists()
def test_proper_python_requires_if_two_digits_precision_version_specified(): poetry = Poetry.create(project("simple_version")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert parsed["Requires-Python"] == ">=3.6,<3.7"