diff --git a/src/poetry/puzzle/provider.py b/src/poetry/puzzle/provider.py index 1e634995dd7..2c7d8f6407c 100644 --- a/src/poetry/puzzle/provider.py +++ b/src/poetry/puzzle/provider.py @@ -853,17 +853,7 @@ def get_locked(self, dependency: Dependency) -> DependencyPackage | None: locked = self._locked.get(dependency.name, []) for dependency_package in locked: package = dependency_package.package - if ( - # Locked dependencies are always without features. - # Thus, we can't use is_same_package_as() here because it compares - # the complete_name (including features). - dependency.name == package.name - and ( - dependency.source_type is None - or dependency.is_same_source_as(package) - ) - and dependency.constraint.allows(package.version) - ): + if package.satisfies(dependency): return DependencyPackage(dependency, package) return None diff --git a/tests/installation/test_installer.py b/tests/installation/test_installer.py index f7fd6213c58..09db34c61f6 100644 --- a/tests/installation/test_installer.py +++ b/tests/installation/test_installer.py @@ -2554,3 +2554,107 @@ def test_installer_should_use_the_locked_version_of_git_dependencies_without_ref source_reference="HEAD", source_resolved_reference=expected_reference, ) + + +# https://github.com/python-poetry/poetry/issues/6710 +@pytest.mark.parametrize("env_platform", ["darwin", "linux"]) +def test_installer_distinguishes_locked_packages_by_source( + pool: Pool, + locker: Locker, + installed: CustomInstalledRepository, + config: Config, + repo: Repository, + package: ProjectPackage, + env_platform: str, +): + # Require 1.11.0+cpu from pytorch for most platforms, but specify 1.11.0 and pypi on + # darwin. + package.add_dependency( + Factory.create_dependency( + "torch", + { + "version": "1.11.0+cpu", + "markers": "sys_platform != 'darwin'", + "source": "pytorch", + }, + ) + ) + package.add_dependency( + Factory.create_dependency( + "torch", + { + "version": "1.11.0", + "markers": "sys_platform == 'darwin'", + "source": "pypi", + }, + ) + ) + + # Locking finds both the pypi and the pytorch packages. + locker.locked(True) + locker.mock_lock_data( + { + "package": [ + { + "name": "torch", + "version": "1.11.0", + "category": "main", + "optional": False, + "files": [], + "python-versions": "*", + }, + { + "name": "torch", + "version": "1.11.0+cpu", + "category": "main", + "optional": False, + "files": [], + "python-versions": "*", + "source": { + "type": "legacy", + "url": "https://download.pytorch.org/whl", + "reference": "pytorch", + }, + }, + ], + "metadata": { + "python-versions": "*", + "platform": "*", + "content-hash": "123456789", + }, + } + ) + 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() + + # Results of installation are consistent with the platform requirements. + version = "1.11.0" if env_platform == "darwin" else "1.11.0+cpu" + source_type = None if env_platform == "darwin" else "legacy" + source_url = ( + None if env_platform == "darwin" else "https://download.pytorch.org/whl" + ) + source_reference = None if env_platform == "darwin" else "pytorch" + + assert len(installer.executor.installations) == 1 + assert installer.executor.installations[0] == Package( + "torch", + version, + source_type=source_type, + source_url=source_url, + source_reference=source_reference, + )