Skip to content

Commit 3002d39

Browse files
committed
feat(pypi) Handle local version in requirement parsing
1 parent 155efce commit 3002d39

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

.bazelrc

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
55
# To update these lines, execute
66
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
7-
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8-
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
7+
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8+
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
99

1010
test --test_output=errors
1111

examples/bzlmod/MODULE.bazel.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/private/pypi/parse_requirements.bzl

+14-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ load(":index_sources.bzl", "index_sources")
3232
load(":parse_requirements_txt.bzl", "parse_requirements_txt")
3333
load(":whl_target_platforms.bzl", "select_whls")
3434

35+
def _extract_version(entry):
36+
"""Extract the version part from the requirement string.
37+
38+
39+
entry: The requirement string.
40+
"""
41+
version_start = entry.find("==")
42+
if version_start != -1:
43+
# Extract everything after '==' until the next space or end of the string
44+
version = entry[version_start + 2:].split(" ")[0]
45+
return version
46+
return None
47+
3548
def parse_requirements(
3649
ctx,
3750
*,
@@ -92,7 +105,7 @@ def parse_requirements(
92105
# are returned as just the base package name. e.g., `foo[bar]` results
93106
# in an entry like `("foo", "foo[bar] == 1.0 ...")`.
94107
requirements_dict = {
95-
normalize_name(entry[0]): entry
108+
(entry[0], _extract_version(entry[1])): entry
96109
for entry in sorted(
97110
parse_result.requirements,
98111
# Get the longest match and fallback to original WORKSPACE sorting,

tests/pypi/parse_requirements/parse_requirements_tests.bzl

+47
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ load("//python/private/pypi:parse_requirements.bzl", "parse_requirements", "sele
1919

2020
def _mock_ctx():
2121
testdata = {
22+
"requirements_different_package_version": """\
23+
foo==0.0.1+local --hash=sha256:deadbeef
24+
foo==0.0.1 --hash=sha256:deadb00f
25+
""",
2226
"requirements_direct": """\
2327
foo[extra] @ https://some-url
2428
""",
@@ -382,6 +386,49 @@ def _test_env_marker_resolution(env):
382386

383387
_tests.append(_test_env_marker_resolution)
384388

389+
# <list [struct(distribution = "foo", extra_pip_args = [], is_exposed = True, requirement_line = "foo==0.0.1 --hash=sha256:deadb00f", sdist = None, srcs = struct(requirement = "foo==0.0.1", shas = ["deadb00f"], version = "0.0.1"), target_platforms = ["linux_x86_64"], whls = []), struct(distribution = "foo", extra_pip_args = [], is_exposed = True, requirement_line = "foo==0.0.1+local --hash=sha256:deadbeef", sdist = None, srcs = struct(requirement = "foo==0.0.1+local", shas = ["deadbeef"], version = "0.0.1+local"), target_platforms = ["linux_x86_64"], whls = [])]>
390+
def _test_different_package_version(env):
391+
got = parse_requirements(
392+
ctx = _mock_ctx(),
393+
requirements_by_platform = {
394+
"requirements_different_package_version": ["linux_x86_64"],
395+
},
396+
)
397+
env.expect.that_dict(got).contains_exactly({
398+
"foo": [
399+
struct(
400+
distribution = "foo",
401+
extra_pip_args = [],
402+
requirement_line = "foo==0.0.1 --hash=sha256:deadb00f",
403+
srcs = struct(
404+
requirement = "foo==0.0.1",
405+
shas = ["deadb00f"],
406+
version = "0.0.1",
407+
),
408+
target_platforms = ["linux_x86_64"],
409+
whls = [],
410+
sdist = None,
411+
is_exposed = True,
412+
),
413+
struct(
414+
distribution = "foo",
415+
extra_pip_args = [],
416+
requirement_line = "foo==0.0.1+local --hash=sha256:deadbeef",
417+
srcs = struct(
418+
requirement = "foo==0.0.1+local",
419+
shas = ["deadbeef"],
420+
version = "0.0.1+local",
421+
),
422+
target_platforms = ["linux_x86_64"],
423+
whls = [],
424+
sdist = None,
425+
is_exposed = True,
426+
),
427+
],
428+
})
429+
430+
_tests.append(_test_different_package_version)
431+
385432
def parse_requirements_test_suite(name):
386433
"""Create the test suite.
387434

0 commit comments

Comments
 (0)