diff --git a/src/python/pants/backend/python/dependency_inference/module_mapper.py b/src/python/pants/backend/python/dependency_inference/module_mapper.py index 18d5e171df5..b5d50cc6cfc 100644 --- a/src/python/pants/backend/python/dependency_inference/module_mapper.py +++ b/src/python/pants/backend/python/dependency_inference/module_mapper.py @@ -8,6 +8,7 @@ import logging from collections import defaultdict from dataclasses import dataclass +from functools import total_ordering from pathlib import PurePath from typing import DefaultDict, Iterable, Mapping, Tuple @@ -39,10 +40,16 @@ ResolveName = str +@total_ordering class ModuleProviderType(enum.Enum): TYPE_STUB = enum.auto() IMPL = enum.auto() + def __lt__(self, other) -> bool: + if not isinstance(other, ModuleProviderType): + return NotImplemented + return self.name < other.name + @dataclass(frozen=True, order=True) class ModuleProvider: diff --git a/src/python/pants/backend/python/dependency_inference/module_mapper_test.py b/src/python/pants/backend/python/dependency_inference/module_mapper_test.py index 8e59c7ed4af..6dcf8c39ff8 100644 --- a/src/python/pants/backend/python/dependency_inference/module_mapper_test.py +++ b/src/python/pants/backend/python/dependency_inference/module_mapper_test.py @@ -650,3 +650,29 @@ def get_owners(resolve: str | None) -> PythonModuleOwners: Address("", target_name="dep1"), Address("", target_name="dep2"), ) + + +def test_issue_15111(rule_runner: RuleRunner) -> None: + """Ensure we can handle when a single address implement multiple modules. + + This is currently only possible with third-party targets. + """ + rule_runner.write_files( + {"BUILD": "python_requirement(name='req', requirements=['docopt', 'types-docopt'])"} + ) + rule_runner.set_options(["--python-enable-resolves"]) + result = rule_runner.request(ThirdPartyPythonModuleMapping, []) + assert result == ThirdPartyPythonModuleMapping( + { + "python-default": FrozenDict( + { + "docopt": ( + ModuleProvider(Address("", target_name="req"), ModuleProviderType.IMPL), + ModuleProvider( + Address("", target_name="req"), ModuleProviderType.TYPE_STUB + ), + ), + } + ) + } + )