refactor(pypi): return a list from parse_requirements (#2931)
The modeling of the data structures returned by the `parse_requirements`
function was not optimal and this was because historically there was
more logic in the `extension.bzl` and more things were decided there.
With the recent refactors it is possible to have a harder to misuse data
structure from the `parse_requirements`. For each `package` we will
return a struct which will have a `srcs` field that will contain easy to
consume values.
With this in place we can do the fix that is outlined in the referenced
issue.
Work towards #2648
diff --git a/python/private/pypi/extension.bzl b/python/private/pypi/extension.bzl
index d3a15df..b79be6e 100644
--- a/python/private/pypi/extension.bzl
+++ b/python/private/pypi/extension.bzl
@@ -202,8 +202,12 @@
logger = logger,
)
- for whl_name, requirements in requirements_by_platform.items():
- group_name = whl_group_mapping.get(whl_name)
+ exposed_packages = {}
+ for whl in requirements_by_platform:
+ if whl.is_exposed:
+ exposed_packages[whl.name] = None
+
+ group_name = whl_group_mapping.get(whl.name)
group_deps = requirement_cycles.get(group_name, [])
# Construct args separately so that the lock file can be smaller and does not include unused
@@ -214,7 +218,7 @@
maybe_args = dict(
# The following values are safe to omit if they have false like values
add_libdir_to_library_search_path = pip_attr.add_libdir_to_library_search_path,
- annotation = whl_modifications.get(whl_name),
+ annotation = whl_modifications.get(whl.name),
download_only = pip_attr.download_only,
enable_implicit_namespace_pkgs = pip_attr.enable_implicit_namespace_pkgs,
environment = pip_attr.environment,
@@ -226,7 +230,7 @@
python_interpreter_target = python_interpreter_target,
whl_patches = {
p: json.encode(args)
- for p, args in whl_overrides.get(whl_name, {}).items()
+ for p, args in whl_overrides.get(whl.name, {}).items()
},
)
if not enable_pipstar:
@@ -245,119 +249,99 @@
if v != default
})
- for requirement in requirements:
- for repo_name, (args, config_setting) in _whl_repos(
- requirement = requirement,
+ for src in whl.srcs:
+ repo = _whl_repo(
+ src = src,
whl_library_args = whl_library_args,
download_only = pip_attr.download_only,
netrc = pip_attr.netrc,
auth_patterns = pip_attr.auth_patterns,
python_version = major_minor,
- multiple_requirements_for_whl = len(requirements) > 1.,
+ is_multiple_versions = whl.is_multiple_versions,
enable_pipstar = enable_pipstar,
- ).items():
- repo_name = "{}_{}".format(pip_name, repo_name)
- if repo_name in whl_libraries:
- fail("Attempting to creating a duplicate library {} for {}".format(
- repo_name,
- whl_name,
- ))
+ )
- whl_libraries[repo_name] = args
- whl_map.setdefault(whl_name, {})[config_setting] = repo_name
+ repo_name = "{}_{}".format(pip_name, repo.repo_name)
+ if repo_name in whl_libraries:
+ fail("Attempting to creating a duplicate library {} for {}".format(
+ repo_name,
+ whl.name,
+ ))
+
+ whl_libraries[repo_name] = repo.args
+ whl_map.setdefault(whl.name, {})[repo.config_setting] = repo_name
return struct(
whl_map = whl_map,
- exposed_packages = {
- whl_name: None
- for whl_name, requirements in requirements_by_platform.items()
- if len([r for r in requirements if r.is_exposed]) > 0
- },
+ exposed_packages = exposed_packages,
extra_aliases = extra_aliases,
whl_libraries = whl_libraries,
)
-def _whl_repos(*, requirement, whl_library_args, download_only, netrc, auth_patterns, multiple_requirements_for_whl = False, python_version, enable_pipstar = False):
- ret = {}
+def _whl_repo(*, src, whl_library_args, is_multiple_versions, download_only, netrc, auth_patterns, python_version, enable_pipstar = False):
+ args = dict(whl_library_args)
+ args["requirement"] = src.requirement_line
+ is_whl = src.filename.endswith(".whl")
- dists = requirement.whls
- if not download_only and requirement.sdist:
- dists = dists + [requirement.sdist]
+ if src.extra_pip_args and not is_whl:
+ # pip is not used to download wheels and the python
+ # `whl_library` helpers are only extracting things, however
+ # for sdists, they will be built by `pip`, so we still
+ # need to pass the extra args there, so only pop this for whls
+ args["extra_pip_args"] = src.extra_pip_args
- for distribution in dists:
- args = dict(whl_library_args)
- if netrc:
- args["netrc"] = netrc
- if auth_patterns:
- args["auth_patterns"] = auth_patterns
-
- if not distribution.filename.endswith(".whl"):
- # pip is not used to download wheels and the python
- # `whl_library` helpers are only extracting things, however
- # for sdists, they will be built by `pip`, so we still
- # need to pass the extra args there.
- args["extra_pip_args"] = requirement.extra_pip_args
-
- # This is no-op because pip is not used to download the wheel.
- args.pop("download_only", None)
-
- args["requirement"] = requirement.line
- args["urls"] = [distribution.url]
- args["sha256"] = distribution.sha256
- args["filename"] = distribution.filename
- if not enable_pipstar:
- args["experimental_target_platforms"] = [
- # Get rid of the version fot the target platforms because we are
- # passing the interpreter any way. Ideally we should search of ways
- # how to pass the target platforms through the hub repo.
- p.partition("_")[2]
- for p in requirement.target_platforms
- ]
-
- # Pure python wheels or sdists may need to have a platform here
- target_platforms = None
- if distribution.filename.endswith(".whl") and not distribution.filename.endswith("-any.whl"):
- pass
- elif multiple_requirements_for_whl:
- target_platforms = requirement.target_platforms
-
- repo_name = whl_repo_name(
- distribution.filename,
- distribution.sha256,
- )
- ret[repo_name] = (
- args,
- whl_config_setting(
+ if not src.url or (not is_whl and download_only):
+ # Fallback to a pip-installed wheel
+ target_platforms = src.target_platforms if is_multiple_versions else []
+ return struct(
+ repo_name = pypi_repo_name(
+ normalize_name(src.distribution),
+ *target_platforms
+ ),
+ args = args,
+ config_setting = whl_config_setting(
version = python_version,
- filename = distribution.filename,
- target_platforms = target_platforms,
+ target_platforms = target_platforms or None,
),
)
- if ret:
- return ret
+ # This is no-op because pip is not used to download the wheel.
+ args.pop("download_only", None)
- # Fallback to a pip-installed wheel
- args = dict(whl_library_args) # make a copy
- args["requirement"] = requirement.line
- if requirement.extra_pip_args:
- args["extra_pip_args"] = requirement.extra_pip_args
+ if netrc:
+ args["netrc"] = netrc
+ if auth_patterns:
+ args["auth_patterns"] = auth_patterns
- target_platforms = requirement.target_platforms if multiple_requirements_for_whl else []
- repo_name = pypi_repo_name(
- normalize_name(requirement.distribution),
- *target_platforms
- )
- ret[repo_name] = (
- args,
- whl_config_setting(
+ args["urls"] = [src.url]
+ args["sha256"] = src.sha256
+ args["filename"] = src.filename
+ if not enable_pipstar:
+ args["experimental_target_platforms"] = [
+ # Get rid of the version fot the target platforms because we are
+ # passing the interpreter any way. Ideally we should search of ways
+ # how to pass the target platforms through the hub repo.
+ p.partition("_")[2]
+ for p in src.target_platforms
+ ]
+
+ # Pure python wheels or sdists may need to have a platform here
+ target_platforms = None
+ if is_whl and not src.filename.endswith("-any.whl"):
+ pass
+ elif is_multiple_versions:
+ target_platforms = src.target_platforms
+
+ return struct(
+ repo_name = whl_repo_name(src.filename, src.sha256),
+ args = args,
+ config_setting = whl_config_setting(
version = python_version,
- target_platforms = target_platforms or None,
+ filename = src.filename,
+ target_platforms = target_platforms,
),
)
- return ret
-
def parse_modules(
module_ctx,
_fail = fail,
diff --git a/python/private/pypi/parse_requirements.bzl b/python/private/pypi/parse_requirements.bzl
index bdfac46..bd2981e 100644
--- a/python/private/pypi/parse_requirements.bzl
+++ b/python/private/pypi/parse_requirements.bzl
@@ -179,49 +179,91 @@
}),
)
- ret = {}
- for whl_name, reqs in sorted(requirements_by_platform.items()):
+ ret = []
+ for name, reqs in sorted(requirements_by_platform.items()):
requirement_target_platforms = {}
for r in reqs.values():
target_platforms = env_marker_target_platforms.get(r.requirement_line, r.target_platforms)
for p in target_platforms:
requirement_target_platforms[p] = None
- is_exposed = len(requirement_target_platforms) == len(requirements)
- if not is_exposed and logger:
+ item = struct(
+ # Return normalized names
+ name = normalize_name(name),
+ is_exposed = len(requirement_target_platforms) == len(requirements),
+ is_multiple_versions = len(reqs.values()) > 1,
+ srcs = _package_srcs(
+ name = name,
+ reqs = reqs,
+ index_urls = index_urls,
+ env_marker_target_platforms = env_marker_target_platforms,
+ extract_url_srcs = extract_url_srcs,
+ logger = logger,
+ ),
+ )
+ ret.append(item)
+ if not item.is_exposed and logger:
logger.debug(lambda: "Package '{}' will not be exposed because it is only present on a subset of platforms: {} out of {}".format(
- whl_name,
+ name,
sorted(requirement_target_platforms),
sorted(requirements),
))
- # Return normalized names
- ret_requirements = ret.setdefault(normalize_name(whl_name), [])
+ if logger:
+ logger.debug(lambda: "Will configure whl repos: {}".format([w.name for w in ret]))
- for r in sorted(reqs.values(), key = lambda r: r.requirement_line):
- whls, sdist = _add_dists(
- requirement = r,
- index_urls = index_urls.get(whl_name),
- logger = logger,
- )
+ return ret
- target_platforms = env_marker_target_platforms.get(r.requirement_line, r.target_platforms)
- ret_requirements.append(
+def _package_srcs(
+ *,
+ name,
+ reqs,
+ index_urls,
+ logger,
+ env_marker_target_platforms,
+ extract_url_srcs):
+ """A function to return sources for a particular package."""
+ srcs = []
+ for r in sorted(reqs.values(), key = lambda r: r.requirement_line):
+ whls, sdist = _add_dists(
+ requirement = r,
+ index_urls = index_urls.get(name),
+ logger = logger,
+ )
+
+ target_platforms = env_marker_target_platforms.get(r.requirement_line, r.target_platforms)
+ target_platforms = sorted(target_platforms)
+
+ all_dists = [] + whls
+ if sdist:
+ all_dists.append(sdist)
+
+ if extract_url_srcs and all_dists:
+ req_line = r.srcs.requirement
+ else:
+ all_dists = [struct(
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ )]
+ req_line = r.srcs.requirement_line
+
+ for dist in all_dists:
+ srcs.append(
struct(
- distribution = r.distribution,
- line = r.srcs.requirement if extract_url_srcs and (whls or sdist) else r.srcs.requirement_line,
- target_platforms = sorted(target_platforms),
+ distribution = name,
extra_pip_args = r.extra_pip_args,
- whls = whls,
- sdist = sdist,
- is_exposed = is_exposed,
+ requirement_line = req_line,
+ target_platforms = target_platforms,
+ filename = dist.filename,
+ sha256 = dist.sha256,
+ url = dist.url,
+ yanked = dist.yanked,
),
)
- if logger:
- logger.debug(lambda: "Will configure whl repos: {}".format(ret.keys()))
-
- return ret
+ return srcs
def select_requirement(requirements, *, platform):
"""A simple function to get a requirement for a particular platform.
diff --git a/python/private/pypi/pip_repository.bzl b/python/private/pypi/pip_repository.bzl
index c8d23f4..724fb6d 100644
--- a/python/private/pypi/pip_repository.bzl
+++ b/python/private/pypi/pip_repository.bzl
@@ -94,15 +94,15 @@
selected_requirements = {}
options = None
repository_platform = host_platform(rctx)
- for name, requirements in requirements_by_platform.items():
+ for whl in requirements_by_platform:
requirement = select_requirement(
- requirements,
+ whl.srcs,
platform = None if rctx.attr.download_only else repository_platform,
)
if not requirement:
continue
options = options or requirement.extra_pip_args
- selected_requirements[name] = requirement.line
+ selected_requirements[whl.name] = requirement.requirement_line
bzl_packages = sorted(selected_requirements.keys())
diff --git a/tests/pypi/parse_requirements/parse_requirements_tests.bzl b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
index 497e083..926a7e0 100644
--- a/tests/pypi/parse_requirements/parse_requirements_tests.bzl
+++ b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
@@ -100,22 +100,28 @@
"requirements_lock": ["linux_x86_64", "windows_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- sdist = None,
- is_exposed = True,
- line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
- target_platforms = [
- "linux_x86_64",
- "windows_x86_64",
- ],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = [
+ "linux_x86_64",
+ "windows_x86_64",
+ ],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_simple)
@@ -127,24 +133,25 @@
"requirements_direct": ["linux_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- sdist = None,
- is_exposed = True,
- line = "foo[extra]",
- target_platforms = ["linux_x86_64"],
- whls = [struct(
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo[extra]",
+ target_platforms = ["linux_x86_64"],
url = "https://some-url/package.whl",
filename = "package.whl",
sha256 = "",
yanked = False,
- )],
- ),
- ],
- })
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_direct_urls_integration)
@@ -156,21 +163,27 @@
},
extra_pip_args = ["--trusted-host=example.org"],
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = ["--index-url=example.org", "--trusted-host=example.org"],
- sdist = None,
- is_exposed = True,
- line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
- target_platforms = [
- "linux_x86_64",
- ],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = ["--index-url=example.org", "--trusted-host=example.org"],
+ requirement_line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = [
+ "linux_x86_64",
+ ],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_extra_pip_args)
@@ -181,19 +194,25 @@
"requirements_lock_dupe": ["linux_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- sdist = None,
- is_exposed = True,
- line = "foo[extra,extra_2]==0.0.1 --hash=sha256:deadbeef",
- target_platforms = ["linux_x86_64"],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo[extra,extra_2]==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = ["linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_dupe_requirements)
@@ -206,44 +225,57 @@
},
)
- env.expect.that_dict(got).contains_exactly({
- "bar": [
- struct(
- distribution = "bar",
- extra_pip_args = [],
- line = "bar==0.0.1 --hash=sha256:deadb00f",
- target_platforms = ["windows_x86_64"],
- whls = [],
- sdist = None,
- is_exposed = False,
- ),
- ],
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- line = "foo==0.0.3 --hash=sha256:deadbaaf",
- target_platforms = ["linux_x86_64"],
- whls = [],
- sdist = None,
- is_exposed = True,
- ),
- struct(
- distribution = "foo",
- extra_pip_args = [],
- line = "foo[extra]==0.0.2 --hash=sha256:deadbeef",
- target_platforms = ["windows_x86_64"],
- whls = [],
- sdist = None,
- is_exposed = True,
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "bar",
+ is_exposed = False,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "bar",
+ extra_pip_args = [],
+ requirement_line = "bar==0.0.1 --hash=sha256:deadb00f",
+ target_platforms = ["windows_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = True,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo==0.0.3 --hash=sha256:deadbaaf",
+ target_platforms = ["linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo[extra]==0.0.2 --hash=sha256:deadbeef",
+ target_platforms = ["windows_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
env.expect.that_str(
select_requirement(
- got["foo"],
+ got[1].srcs,
platform = "windows_x86_64",
- ).line,
+ ).requirement_line,
).equals("foo[extra]==0.0.2 --hash=sha256:deadbeef")
_tests.append(_test_multi_os)
@@ -257,39 +289,52 @@
},
)
- env.expect.that_dict(got).contains_exactly({
- "bar": [
- struct(
- distribution = "bar",
- extra_pip_args = ["--platform=manylinux_2_17_x86_64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
- is_exposed = False,
- sdist = None,
- line = "bar==0.0.1 --hash=sha256:deadb00f",
- target_platforms = ["cp39_linux_x86_64"],
- whls = [],
- ),
- ],
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = ["--platform=manylinux_2_17_x86_64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
- is_exposed = True,
- sdist = None,
- line = "foo==0.0.1 --hash=sha256:deadbeef",
- target_platforms = ["cp39_linux_x86_64"],
- whls = [],
- ),
- struct(
- distribution = "foo",
- extra_pip_args = ["--platform=macosx_10_9_arm64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
- is_exposed = True,
- sdist = None,
- line = "foo==0.0.3 --hash=sha256:deadbaaf",
- target_platforms = ["cp39_osx_aarch64"],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "bar",
+ is_exposed = False,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "bar",
+ extra_pip_args = ["--platform=manylinux_2_17_x86_64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
+ requirement_line = "bar==0.0.1 --hash=sha256:deadb00f",
+ target_platforms = ["cp39_linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = True,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = ["--platform=manylinux_2_17_x86_64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
+ requirement_line = "foo==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = ["cp39_linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ struct(
+ distribution = "foo",
+ extra_pip_args = ["--platform=macosx_10_9_arm64", "--python-version=39", "--implementation=cp", "--abi=cp39"],
+ requirement_line = "foo==0.0.3 --hash=sha256:deadbaaf",
+ target_platforms = ["cp39_osx_aarch64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_multi_os_legacy)
@@ -324,30 +369,42 @@
},
evaluate_markers = _mock_eval_markers,
)
- env.expect.that_dict(got).contains_exactly({
- "bar": [
- struct(
- distribution = "bar",
- extra_pip_args = [],
- is_exposed = True,
- sdist = None,
- line = "bar==0.0.1 --hash=sha256:deadbeef",
- target_platforms = ["cp311_linux_super_exotic", "cp311_windows_x86_64"],
- whls = [],
- ),
- ],
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- is_exposed = False,
- sdist = None,
- line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
- target_platforms = ["cp311_windows_x86_64"],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "bar",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "bar",
+ extra_pip_args = [],
+ requirement_line = "bar==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = ["cp311_linux_super_exotic", "cp311_windows_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ struct(
+ name = "foo",
+ is_exposed = False,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
+ target_platforms = ["cp311_windows_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_env_marker_resolution)
@@ -358,28 +415,35 @@
"requirements_different_package_version": ["linux_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- is_exposed = True,
- sdist = None,
- line = "foo==0.0.1 --hash=sha256:deadb00f",
- target_platforms = ["linux_x86_64"],
- whls = [],
- ),
- struct(
- distribution = "foo",
- extra_pip_args = [],
- is_exposed = True,
- sdist = None,
- line = "foo==0.0.1+local --hash=sha256:deadbeef",
- target_platforms = ["linux_x86_64"],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = True,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo==0.0.1 --hash=sha256:deadb00f",
+ target_platforms = ["linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo==0.0.1+local --hash=sha256:deadbeef",
+ target_platforms = ["linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_different_package_version)
@@ -390,38 +454,35 @@
"requirements_optional_hash": ["linux_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- sdist = None,
- is_exposed = True,
- line = "foo==0.0.4",
- target_platforms = ["linux_x86_64"],
- whls = [struct(
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = True,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo==0.0.4",
+ target_platforms = ["linux_x86_64"],
url = "https://example.org/foo-0.0.4.whl",
filename = "foo-0.0.4.whl",
sha256 = "",
yanked = False,
- )],
- ),
- struct(
- distribution = "foo",
- extra_pip_args = [],
- sdist = None,
- is_exposed = True,
- line = "foo==0.0.5",
- target_platforms = ["linux_x86_64"],
- whls = [struct(
+ ),
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo==0.0.5",
+ target_platforms = ["linux_x86_64"],
url = "https://example.org/foo-0.0.5.whl",
filename = "foo-0.0.5.whl",
sha256 = "deadbeef",
yanked = False,
- )],
- ),
- ],
- })
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_optional_hash)
@@ -432,19 +493,25 @@
"requirements_git": ["linux_x86_64"],
},
)
- env.expect.that_dict(got).contains_exactly({
- "foo": [
- struct(
- distribution = "foo",
- extra_pip_args = [],
- is_exposed = True,
- sdist = None,
- line = "foo @ git+https://github.com/org/foo.git@deadbeef",
- target_platforms = ["linux_x86_64"],
- whls = [],
- ),
- ],
- })
+ env.expect.that_collection(got).contains_exactly([
+ struct(
+ name = "foo",
+ is_exposed = True,
+ is_multiple_versions = False,
+ srcs = [
+ struct(
+ distribution = "foo",
+ extra_pip_args = [],
+ requirement_line = "foo @ git+https://github.com/org/foo.git@deadbeef",
+ target_platforms = ["linux_x86_64"],
+ url = "",
+ filename = "",
+ sha256 = "",
+ yanked = False,
+ ),
+ ],
+ ),
+ ])
_tests.append(_test_git_sources)