Skip to content

Commit

Permalink
Review feedback and a test fix for #14419.
Browse files Browse the repository at this point in the history
[ci skip-rust]
[ci skip-build-wheels]
  • Loading branch information
stuhood committed Feb 10, 2022
1 parent 9140a3e commit 89bcdf1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 25 deletions.
8 changes: 5 additions & 3 deletions src/python/pants/build_graph/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,14 @@ def sanitize(s: str) -> str:
return f"{prefix}{path}{target}{params}{generated}"

def maybe_convert_to_target_generator(self) -> Address:
"""If this address is generated or parametrized, convert it to its generator target.
"""If this address is generated, convert it to its generator target.
Otherwise, return self unmodified.
"""
if self.is_generated_target or self.is_parametrized:
return self.__class__(self.spec_path, target_name=self._target_name)
if self.is_generated_target:
return self.__class__(
self.spec_path, target_name=self._target_name, parameters=self.parameters
)
return self

def maybe_convert_to_generated_target(self) -> Address:
Expand Down
35 changes: 15 additions & 20 deletions src/python/pants/engine/internals/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,33 +177,23 @@ def warn_deprecated_field_type(request: _WarnDeprecatedFieldRequest) -> _WarnDep

@dataclass(frozen=True)
class _TargetParametrizations:
"""All parametrizations and generated targets for a single input Address.
"""All parametrizations and generated targets for a single input Address."""

If a Target has been parametrized, it might _not_ be present in this output, due to it not being
addressable using its un-parameterized Address.
"""

target: Target | None
original_target: Target
parametrizations: FrozenDict[Address, Target]

def get(self, address: Address) -> Target | None:
if self.target and self.target.address == address:
return self.target
if self.original_target.address == address:
return self.original_target
return self.parametrizations.get(address)

def generated_or_generator(self, maybe_generator: Address) -> Iterator[Target]:
if not self.target:
raise ValueError(
"A `parametrized` target cannot be consumed without its parameters specified.\n"
f"Target `{maybe_generator}` can be addressed as:\n"
f"{bullet_list(addr.spec for addr in self.parametrizations)}"
)
if self.parametrizations:
# Generated Targets.
yield from self.parametrizations.values()
else:
# Did not generate targets.
yield self.target
yield self.original_target


@rule
Expand Down Expand Up @@ -295,13 +285,18 @@ async def resolve_target_parametrizations(


@rule
async def resolve_target(address: Address) -> WrappedTarget:
async def resolve_target(
address: Address,
target_types_to_generate_requests: TargetTypesToGenerateTargetsRequests,
) -> WrappedTarget:
base_address = address.maybe_convert_to_target_generator()
parametrizations = await Get(_TargetParametrizations, Address, base_address)
if not parametrizations.parametrizations and address.is_file_target and parametrizations.target:
# TODO: This is an accommodation to allow using file Addresses for non-generator singleton
# targets. See https://github.com/pantsbuild/pants/issues/14419.
return WrappedTarget(parametrizations.target)
if address.is_generated_target and not target_types_to_generate_requests.is_generator(
parametrizations.original_target
):
# TODO: This is an accommodation to allow using file/generator Addresses for non-generator
# atom targets. See https://github.com/pantsbuild/pants/issues/14419.
return WrappedTarget(parametrizations.original_target)
target = parametrizations.get(address)
if target is None:
raise ValueError(
Expand Down
4 changes: 2 additions & 2 deletions src/python/pants/engine/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,9 +879,9 @@ class GenerateTargetsRequest(Generic[_TargetGenerator]):
# The base Address to generate for. Note that due to parametrization, this may not
# always be the Address of the underlying target.
template_address: Address
# The `TargetGenerator.moved_field/copied_field` Field instances that the generator
# The `TargetGenerator.moved_field/copied_field` Field values that the generator
# should generate targets with.
template: dict[str, Field] = dataclasses.field(hash=False)
template: dict[str, Any] = dataclasses.field(hash=False)
# Per-generated-Target overrides.
overrides: dict[str, dict[str, Any]] = dataclasses.field(hash=False)

Expand Down

0 comments on commit 89bcdf1

Please sign in to comment.