What's the right way to determine if two `Address`...
# plugins
r
What's the right way to determine if two
Address
objects are equivalent if one is relative and one is absolute? I tried comparing their
address.spec
, which documentation claims will prepend
//
to any build root level targets, but I am not seeing that behavior in actuality, the relative specs are still missing the
//
.
c
which version of pants? I get:
Copy code
❯ pants list :
//:all-__init__.py-files
//:buildgrid_remote
//:checks-empty-init-files
//:docker_env
//:files
//:scripts
//:test_utils
//BUILD_ROOT:files
//cargo:scripts
//conftest.py:test_utils
//pants:scripts
//pants.toml:files
on current
main
in the pants repo.
r
2.18.0dev7
c
maybe try
path_safe_spec
?
r
That just replaces the colons with periods
c
what? that sounds off… can you share a redacted example?
nvm, I see what you mean
r
Would this be any different in the spec_paths refer to a directory as opposed to a file? When I use
AddressInput.dir_to_address
as opposed to
<http://AddressInput.it|AddressInput.file_to_address
it> just uses all relative paths instead of prepending the
//
in the spec path
c
the path safe one.. between the 2 sec of me posting and you replying I forgot what I said 😛
r
This is for trying to find docker image targets in a YAML-spec
Copy code
address_set = {tgt.address.spec for tgt in docker_targets}
    logger.debug(f"All docker image addresses: {address_set}")
    target_pattern = re.compile(r"[\w/\-]*:([\w/\-]+)")

    def recursive_search(contents: Any, key: Tuple[str, ...] = ()) -> Iterable[Tuple[Address, Tuple[str, ...]]]:
        if isinstance(contents, str):
            if target_pattern.fullmatch(contents):
                logger.debug(f"Found potential target {contents}")
                resolved_address = resolve_str_to_address(
                    contents,
                    description_of_origin="Deployment dependency inference",
                    relative_to=request.root_address,
                )
                logger.debug(f"Resolved potential target to address {resolved_address}")
                if resolved_address.spec in address_set:
                    logger.debug(f"Address {resolved_address} found in address set")
                    yield resolved_address, key
        elif isinstance(contents, collections.abc.Mapping):
            for k, value in contents.items():
                yield from recursive_search(value, (*key, k))
        elif isinstance(contents, collections.abc.Sequence):
            for i, entry in enumerate(contents):
                yield from recursive_search(entry, (*key, str(i)))
When I changed
resolve_str_to_address
to the following this worked:
Copy code
def resolve_str_to_address(spec: str, *, description_of_origin: str, relative_to: Address) -> Address:
    return AddressInput.parse(
        spec=spec, description_of_origin=description_of_origin, relative_to=relative_to.spec_path
    ).dir_to_address()
c
oh, wait I think you may be confused about what a relative address is
foo/bar:baz
is the same as
//foo/bar:baz
the only relative one is
:name
i.e. with no path at all.
r
If I have a set with
foo/bar:baz
in it
//foo/bar:baz in my_address_set
evaluates to false though.
c
yea, but if you use addresses, the
//
will be removed from the spec, I think.. it’s only preserved for root level addresses.
which circles back to the comment you opened with.
so don’t use
//
in your code, unless it’s a root level address 🙂
r
The addresses from
AllDockerImageTargets
, the ones at the root level, their specs don't seem to get
//
c
that is surprising, what is their
spec_path
?
r
Wait I think I'm seeing my issue. The targets themselves aren't root level, but the directory they're in is.
c
aha!
how did you manage that?
r
dir_to_address
seems to work perfectly for my use case, since what I want is the actual directory of the build file.
👍 1
c
also,
address.spec_path
is perhaps useful, depending on what you do?