Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions python/private/pypi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ bzl_library(
srcs = ["pkg_aliases.bzl"],
deps = [
":labels",
":whl_library_deps_targets",
"//python/private:common_labels",
"//python/private:text_util",
"@bazel_skylib//lib:selects",
Expand Down
70 changes: 61 additions & 9 deletions python/private/pypi/pkg_aliases.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ load(
"EXTRACTED_WHEEL_FILES",
"PY_LIBRARY_IMPL_LABEL",
"PY_LIBRARY_PUBLIC_LABEL",
"PY_SRCS_LABEL",
"WHEEL_FILE",
"WHEEL_FILE_IMPL_LABEL",
"WHEEL_FILE_PUBLIC_LABEL",
)
load(":whl_library_deps_targets.bzl", "whl_library_deps_targets")

_NO_MATCH_ERROR_TEMPLATE = """\
No matching wheel for current configuration's Python version and platform.
Expand Down Expand Up @@ -79,6 +82,10 @@ def pkg_aliases(
actual,
group_name = None,
extra_aliases = None,
requires_dist = [],
extras = [],
include = [],
group_deps = [],
**kwargs):
"""Create aliases for an actual package.

Expand All @@ -91,31 +98,74 @@ def pkg_aliases(
the aliases to point to mapping to repositories. The keys are passed
to bazel skylib's `selects.with_or`, so they can be tuples as well.
group_name: {type}`str` The group name that the pkg belongs to.
group_deps: {type}`list[str]` The packages that are in the given group. Comes
as an arg through the hub repository.
extra_aliases: {type}`list[str]` The extra aliases to be created.
requires_dist: {type}`list[str]` The list of dependencies. Comes from METADATA or a lock
file.
extras: {type}`list[str]` The extras for which we should add extra
dependencies when parsing the requires_dist. Comes from METADATA or a lock file.
include: {type}`list[str]` The subset of packages to include.
Comes from `//:config.bzl#packages`
**kwargs: extra kwargs to pass to {bzl:obj}`get_config_settings`.
"""
alias = kwargs.pop("native", native).alias
_native = kwargs.pop("native", native)
rules = kwargs.pop("rules", struct(
whl_library_deps_targets = whl_library_deps_targets,
))
select = kwargs.pop("select", selects.with_or)

alias(
_native.alias(
name = name,
actual = ":" + PY_LIBRARY_PUBLIC_LABEL,
)

target_names = {
PY_LIBRARY_PUBLIC_LABEL: PY_LIBRARY_IMPL_LABEL if group_name else PY_LIBRARY_PUBLIC_LABEL,
WHEEL_FILE_PUBLIC_LABEL: WHEEL_FILE_IMPL_LABEL if group_name else WHEEL_FILE_PUBLIC_LABEL,
if requires_dist:
# if it has a group_name set, then it will create the impl label target in the
# current macro, we still need to do the aliases to the actual groups package as
# per below
rules.whl_library_deps_targets(
repo = None,
aliases = {}, # not none
metadata_name = name,
requires_dist = requires_dist,
extras = extras,
include = include,
group_deps = group_deps,
group_name = group_name,
dep_template = "//{name}:{target}", # this is const in this setting
visibility = ["//visibility:public"],
native = _native,
rules = rules,
)
target_names = {}
else:
if group_name:
py_library_target = PY_LIBRARY_IMPL_LABEL
whl_target = WHEEL_FILE_IMPL_LABEL
else:
py_library_target = PY_LIBRARY_PUBLIC_LABEL
whl_target = WHEEL_FILE_PUBLIC_LABEL

target_names = {
PY_LIBRARY_PUBLIC_LABEL: py_library_target,
WHEEL_FILE_PUBLIC_LABEL: whl_target,
}

target_names = target_names | {
DATA_LABEL: DATA_LABEL,
DIST_INFO_LABEL: DIST_INFO_LABEL,
EXTRACTED_WHEEL_FILES: EXTRACTED_WHEEL_FILES,
PY_SRCS_LABEL: PY_SRCS_LABEL,
WHEEL_FILE: WHEEL_FILE,
} | {
x: x
for x in extra_aliases or []
}

actual = multiplatform_whl_aliases(aliases = actual, **kwargs)
if type(actual) == type({}) and "//conditions:default" not in actual:
alias(
_native.alias(
name = _INCOMPATIBLE,
actual = select(
{_LABEL_CURRENT_CONFIG_NO_MATCH: _LABEL_NONE},
Expand Down Expand Up @@ -157,19 +207,21 @@ def pkg_aliases(
kwargs = {}
if target_name.startswith("_"):
kwargs["visibility"] = ["//_groups:__subpackages__"]
elif target_name in (WHEEL_FILE, PY_SRCS_LABEL):
kwargs["visibility"] = ["//visibility:private"]

alias(
_native.alias(
name = target_name,
actual = _actual,
**kwargs
)

if group_name:
alias(
_native.alias(
name = PY_LIBRARY_PUBLIC_LABEL,
actual = "//_groups:{}_pkg".format(group_name),
)
alias(
_native.alias(
name = WHEEL_FILE_PUBLIC_LABEL,
actual = "//_groups:{}_whl".format(group_name),
)
Expand Down
179 changes: 178 additions & 1 deletion tests/pypi/pkg_aliases/pkg_aliases_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ load(
"pkg_aliases",
) # buildifier: disable=bzl-visibility
load("//python/private/pypi:whl_config_setting.bzl", "whl_config_setting") # buildifier: disable=bzl-visibility
load("//python/private/pypi:whl_library_deps_targets.bzl", "whl_library_deps_targets") # buildifier: disable=bzl-visibility

_tests = []

Expand All @@ -32,7 +33,7 @@ def _test_legacy_aliases(env):
name = "foo",
actual = "repo",
native = struct(
alias = lambda name, actual: got.update({name: actual}),
alias = lambda name, actual, visibility = None: got.update({name: actual}),
),
extra_aliases = ["my_special"],
)
Expand All @@ -41,6 +42,8 @@ def _test_legacy_aliases(env):
want = {
"foo": ":pkg",
"pkg": "@repo//:pkg",
"srcs": "@repo//:srcs",
"whl_file": "@repo//:whl_file",
"whl": "@repo//:whl",
"data": "@repo//:data",
"dist_info": "@repo//:dist_info",
Expand Down Expand Up @@ -245,11 +248,185 @@ def _test_group_aliases(env):
"name": "whl",
"actual": "//_groups:my_group_whl",
},
{
"name": "srcs",
"actual": "@repo//:srcs",
"visibility": ["//visibility:private"],
},
{
"name": "whl_file",
"actual": "@repo//:whl_file",
"visibility": ["//visibility:private"],
},
]
env.expect.that_collection(actual).contains_exactly(want)

_tests.append(_test_group_aliases)

def _test_deps_and_aliases(env):
# Use this function as it is used in pip_repository
actual_aliases = []
actual_deps_targets = {}

# buildifier: disable=unsorted-dict-items
want_aliases = [
{
"name": "foo",
"actual": ":pkg",
},
{
"name": "data",
"actual": "@repo//:data",
},
{
"name": "dist_info",
"actual": "@repo//:dist_info",
},
{
"name": "extracted_whl_files",
"actual": "@repo//:extracted_whl_files",
},
{
"name": "pkg",
"actual": "//_groups:my_group_pkg",
},
{
"name": "whl",
"actual": "//_groups:my_group_whl",
},
{
"name": "srcs",
"actual": "@repo//:srcs",
"visibility": ["//visibility:private"],
},
{
"name": "whl_file",
"actual": "@repo//:whl_file",
"visibility": ["//visibility:private"],
},
]
want_deps_targets = {
"aliases": {},
"dep_template": "//{name}:{target}",
"extras": [],
"group_deps": ["bar", "foo"],
"group_name": "my_group",
"include": [],
"metadata_name": "foo",
"repo": None,
"requires_dist": ["bar", "baz; python_version > \"3.10\""],
"visibility": ["//visibility:public"],
}

pkg_aliases(
name = "foo",
actual = "repo",
group_name = "my_group",
group_deps = [
"bar",
"foo",
],
requires_dist = [
"bar",
"baz; python_version > \"3.10\"",
],
native = struct(
alias = lambda **kwargs: actual_aliases.append(kwargs),
),
rules = struct(
whl_library_deps_targets = lambda **kwargs: actual_deps_targets.update(kwargs),
),
)
env.expect.that_collection(actual_aliases).contains_exactly(want_aliases)
env.expect.that_dict(actual_deps_targets).contains_at_least(want_deps_targets)

_tests.append(_test_deps_and_aliases)

def _test_deps_and_aliases_integration(env):
# Use this function as it is used in pip_repository
actual_aliases = []
actual_env_marker_settings = []
actual_py_library = {}

# buildifier: disable=unsorted-dict-items
want_aliases = [
{
"name": "foo",
"actual": ":pkg",
},
{
"name": "data",
"actual": "@repo//:data",
},
{
"name": "dist_info",
"actual": "@repo//:dist_info",
},
{
"name": "extracted_whl_files",
"actual": "@repo//:extracted_whl_files",
},
{
"name": "pkg",
"actual": "//_groups:my_group_pkg",
},
{
"name": "whl",
"actual": "//_groups:my_group_whl",
},
{
"name": "srcs",
"actual": "@repo//:srcs",
"visibility": ["//visibility:private"],
},
{
"name": "whl_file",
"actual": "@repo//:whl_file",
"visibility": ["//visibility:private"],
},
]

# buildifier: disable=unsorted-dict-items
want_settings = [
{
"name": "include_baz",
"expression": "python_version > \"3.10\"",
"visibility": ["//visibility:private"],
},
]

# buildifier: disable=unsorted-dict-items
want_library = {
"name": "pkg",
"deps": ["srcs", "//bar:pkg"] + select({":is_include_baz_true": ["//baz:pkg"], "//conditions:default": []}),
"srcs": ["srcs"],
"tags": [],
"visibility": ["//:__subpackages__"],
}

pkg_aliases(
name = "foo",
actual = "repo",
group_name = "my_group",
requires_dist = [
"bar",
"baz; python_version > \"3.10\"",
],
native = struct(
alias = lambda **kwargs: actual_aliases.append(kwargs),
),
rules = struct(
whl_library_deps_targets = whl_library_deps_targets,
env_marker_setting = lambda **kwargs: actual_env_marker_settings.append(kwargs),
py_library = lambda **kwargs: actual_py_library.update(kwargs),
),
)
env.expect.that_collection(actual_aliases).contains_exactly(want_aliases)
env.expect.that_collection(actual_env_marker_settings).contains_exactly(want_settings)
env.expect.that_dict(actual_py_library).contains_at_least(want_library)

_tests.append(_test_deps_and_aliases_integration)

def _test_multiplatform_whl_aliases_empty(env):
# Check that we still work with an empty requirements.txt
got = multiplatform_whl_aliases(aliases = {})
Expand Down