Commit b1b3ce90 by Randy Döring

installer: support for duplicate direct origin dependencies with same version

parent 801a549a
...@@ -12,6 +12,7 @@ from poetry.installation.pip_installer import PipInstaller ...@@ -12,6 +12,7 @@ from poetry.installation.pip_installer import PipInstaller
from poetry.repositories import Pool from poetry.repositories import Pool
from poetry.repositories import Repository from poetry.repositories import Repository
from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.installed_repository import InstalledRepository
from poetry.repositories.lockfile_repository import LockfileRepository
from poetry.utils.extras import get_extra_package_names from poetry.utils.extras import get_extra_package_names
from poetry.utils.helpers import canonicalize_name from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import pluralize from poetry.utils.helpers import pluralize
...@@ -107,9 +108,7 @@ class Installer: ...@@ -107,9 +108,7 @@ class Installer:
self._write_lock = False self._write_lock = False
self._execute_operations = False self._execute_operations = False
local_repo = Repository() return self._do_install()
return self._do_install(local_repo)
def dry_run(self, dry_run: bool = True) -> Installer: def dry_run(self, dry_run: bool = True) -> Installer:
self._dry_run = dry_run self._dry_run = dry_run
...@@ -204,14 +203,14 @@ class Installer: ...@@ -204,14 +203,14 @@ class Installer:
): ):
ops = solver.solve(use_latest=[]).calculate_operations() ops = solver.solve(use_latest=[]).calculate_operations()
local_repo = Repository() lockfile_repo = LockfileRepository()
self._populate_local_repo(local_repo, ops) self._populate_lockfile_repo(lockfile_repo, ops)
self._write_lock_file(local_repo, force=True) self._write_lock_file(lockfile_repo, force=True)
return 0 return 0
def _do_install(self, local_repo: Repository) -> int: def _do_install(self) -> int:
from poetry.puzzle.solver import Solver from poetry.puzzle.solver import Solver
locked_repository = Repository() locked_repository = Repository()
...@@ -266,10 +265,11 @@ class Installer: ...@@ -266,10 +265,11 @@ class Installer:
# currently installed # currently installed
ops = self._get_operations_from_lock(locked_repository) ops = self._get_operations_from_lock(locked_repository)
self._populate_local_repo(local_repo, ops) lockfile_repo = LockfileRepository()
self._populate_lockfile_repo(lockfile_repo, ops)
if self._update: if self._update:
self._write_lock_file(local_repo) self._write_lock_file(lockfile_repo)
if self._lock: if self._lock:
# If we are only in lock mode, no need to go any further # If we are only in lock mode, no need to go any further
...@@ -292,8 +292,8 @@ class Installer: ...@@ -292,8 +292,8 @@ class Installer:
# Making a new repo containing the packages # Making a new repo containing the packages
# newly resolved and the ones from the current lock file # newly resolved and the ones from the current lock file
repo = Repository() repo = Repository()
for package in local_repo.packages + locked_repository.packages: for package in lockfile_repo.packages + locked_repository.packages:
if not repo.has_package(package): if not package.is_direct_origin() and not repo.has_package(package):
repo.add_package(package) repo.add_package(package)
pool.add_repository(repo) pool.add_repository(repo)
...@@ -318,7 +318,7 @@ class Installer: ...@@ -318,7 +318,7 @@ class Installer:
transaction = Transaction( transaction = Transaction(
locked_repository.packages, locked_repository.packages,
[(package, 0) for package in local_repo.packages], [(package, 0) for package in lockfile_repo.packages],
installed_packages=self._installed_repository.packages, installed_packages=self._installed_repository.packages,
root_package=root, root_package=root,
) )
...@@ -332,12 +332,12 @@ class Installer: ...@@ -332,12 +332,12 @@ class Installer:
# We need to filter operations so that packages # We need to filter operations so that packages
# not compatible with the current system, # not compatible with the current system,
# or optional and not requested, are dropped # or optional and not requested, are dropped
self._filter_operations(ops, local_repo) self._filter_operations(ops, lockfile_repo)
# Execute operations # Execute operations
return self._execute(ops) return self._execute(ops)
def _write_lock_file(self, repo: Repository, force: bool = False) -> None: def _write_lock_file(self, repo: LockfileRepository, force: bool = False) -> None:
if self._write_lock and (force or self._update): if self._write_lock and (force or self._update):
updated_lock = self._locker.set_lock_data(self._package, repo.packages) updated_lock = self._locker.set_lock_data(self._package, repo.packages)
...@@ -460,8 +460,8 @@ class Installer: ...@@ -460,8 +460,8 @@ class Installer:
self._installer.remove(operation.package) self._installer.remove(operation.package)
def _populate_local_repo( def _populate_lockfile_repo(
self, local_repo: Repository, ops: Sequence[Operation] self, repo: LockfileRepository, ops: Sequence[Operation]
) -> None: ) -> None:
for op in ops: for op in ops:
if isinstance(op, Uninstall): if isinstance(op, Uninstall):
...@@ -471,8 +471,8 @@ class Installer: ...@@ -471,8 +471,8 @@ class Installer:
else: else:
package = op.package package = op.package
if not local_repo.has_package(package): if not repo.has_package(package):
local_repo.add_package(package) repo.add_package(package)
def _get_operations_from_lock( def _get_operations_from_lock(
self, locked_repository: Repository self, locked_repository: Repository
......
[[package]]
name = "demo"
version = "0.1.0"
description = ""
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.source]
type = "url"
url = "https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
[package.dependencies]
pendulum = ">=1.4.4"
[package.extras]
bar = ["tomlkit"]
foo = ["cleo"]
[[package]]
name = "demo"
version = "0.1.0"
description = ""
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.source]
type = "url"
url = "https://python-poetry.org/distributions/demo-0.1.0.tar.gz"
[package.dependencies]
pendulum = ">=1.4.4"
[package.extras]
bar = ["tomlkit"]
foo = ["cleo"]
[[package]]
name = "pendulum"
version = "1.4.4"
description = ""
category = "main"
optional = false
python-versions = "*"
[metadata]
python-versions = "*"
lock-version = "1.1"
content-hash = "123456789"
[metadata.files]
demo = []
pendulum = []
...@@ -2231,6 +2231,56 @@ def test_run_installs_with_url_file( ...@@ -2231,6 +2231,56 @@ def test_run_installs_with_url_file(
assert installer.executor.installations_count == 2 assert installer.executor.installations_count == 2
@pytest.mark.parametrize("env_platform", ["linux", "win32"])
def test_run_installs_with_same_version_url_files(
pool: Pool,
locker: Locker,
installed: CustomInstalledRepository,
config: Config,
repo: Repository,
package: ProjectPackage,
env_platform: str,
) -> None:
urls = {
"linux": "https://python-poetry.org/distributions/demo-0.1.0.tar.gz",
"win32": (
"https://python-poetry.org/distributions/demo-0.1.0-py2.py3-none-any.whl"
),
}
for platform, url in urls.items():
package.add_dependency(
Factory.create_dependency(
"demo",
{"url": url, "markers": f"sys_platform == '{platform}'"},
)
)
repo.add_package(get_package("pendulum", "1.4.4"))
installer = Installer(
NullIO(),
MockEnv(platform=env_platform),
package,
locker,
pool,
config,
installed=installed,
executor=Executor(
MockEnv(platform=env_platform),
pool,
config,
NullIO(),
),
)
installer.use_executor(True)
installer.run()
expected = fixture("with-same-version-url-dependencies")
assert locker.written_data == expected
assert installer.executor.installations_count == 2
demo_package = next(p for p in installer.executor.installations if p.name == "demo")
assert demo_package.source_url == urls[env_platform]
def test_installer_uses_prereleases_if_they_are_compatible( def test_installer_uses_prereleases_if_they_are_compatible(
installer: Installer, locker: Locker, package: ProjectPackage, repo: Repository installer: Installer, locker: Locker, package: ProjectPackage, repo: Repository
): ):
......
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