Skip to content

Commit bd42ad2

Browse files
Support annotations on pip packages with extras. (#865)
* Support annotations on pip packages with extras. E.g., the following requirement: ``` requests[security]>=2.8.1 ``` This is handled correctly by all of the other plumbing, but trying to add an annotation to `requests` will fail. This is because annotations have separate logic for parsing requirements in the generated .bzl file. It would previously turn the requirement into `requests[security]` rather than just `requests`. * Add test verifying that annotations work for packages with extras.
1 parent b1546b6 commit bd42ad2

File tree

8 files changed

+67
-4
lines changed

8 files changed

+67
-4
lines changed

examples/pip_parse_vendored/requirements.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def entry_point(pkg, script = None):
3838
def _get_annotation(requirement):
3939
# This expects to parse `setuptools==58.2.0 --hash=sha256:2551203ae6955b9876741a26ab3e767bb3242dafe86a32a749ea0d78b6792f11`
4040
# down wo `setuptools`.
41-
name = requirement.split(" ")[0].split("=")[0]
41+
name = requirement.split(" ")[0].split("=")[0].split("[")[0]
4242
return _annotations.get(name)
4343

4444
def install_deps(**whl_library_kwargs):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/bazel-*

examples/pip_repository_annotations/BUILD

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ compile_pip_requirements(
1616
py_test(
1717
name = "pip_parse_annotations_test",
1818
srcs = ["pip_repository_annotations_test.py"],
19-
env = {"WHEEL_PKG_DIR": "pip_parsed_wheel"},
19+
env = {
20+
"REQUESTS_PKG_DIR": "pip_parsed_requests",
21+
"WHEEL_PKG_DIR": "pip_parsed_wheel",
22+
},
2023
main = "pip_repository_annotations_test.py",
2124
deps = [
25+
"@pip_parsed_requests//:pkg",
2226
"@pip_parsed_wheel//:pkg",
2327
"@rules_python//python/runfiles",
2428
],
@@ -27,10 +31,14 @@ py_test(
2731
py_test(
2832
name = "pip_install_annotations_test",
2933
srcs = ["pip_repository_annotations_test.py"],
30-
env = {"WHEEL_PKG_DIR": "pip_installed_wheel"},
34+
env = {
35+
"REQUESTS_PKG_DIR": "pip_installed_requests",
36+
"WHEEL_PKG_DIR": "pip_installed_wheel",
37+
},
3138
main = "pip_repository_annotations_test.py",
3239
deps = [
3340
requirement("wheel"),
41+
requirement("requests"),
3442
"@rules_python//python/runfiles",
3543
],
3644
)

examples/pip_repository_annotations/WORKSPACE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ load("@rules_python//python:pip.bzl", "package_annotation", "pip_install", "pip_
3030
# package. For details on `package_annotation` and it's uses, see the
3131
# docs at @rules_python//docs:pip.md`.
3232
ANNOTATIONS = {
33+
# This annotation verifies that annotations work correctly for pip packages with extras
34+
# specified, in this case requests[security].
35+
"requests": package_annotation(
36+
additive_build_content = """\
37+
load("@bazel_skylib//rules:write_file.bzl", "write_file")
38+
write_file(
39+
name = "generated_file",
40+
out = "generated_file.txt",
41+
content = ["Hello world from requests"],
42+
)
43+
""",
44+
data = [":generated_file"],
45+
),
3346
"wheel": package_annotation(
3447
additive_build_content = """\
3548
load("@bazel_skylib//rules:write_file.bzl", "write_file")

examples/pip_repository_annotations/pip_repository_annotations_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,26 @@ def test_data_exclude_glob(self):
9090
self.assertTrue(Path(metadata_path).exists())
9191
self.assertFalse(Path(wheel_path).exists())
9292

93+
def requests_pkg_dir(self) -> str:
94+
env = os.environ.get("REQUESTS_PKG_DIR")
95+
self.assertIsNotNone(env)
96+
return env
97+
98+
def test_extra(self):
99+
# This test verifies that annotations work correctly for pip packages with extras
100+
# specified, in this case requests[security].
101+
r = runfiles.Create()
102+
rpath = r.Rlocation(
103+
"pip_repository_annotations_example/external/{}/generated_file.txt".format(
104+
self.requests_pkg_dir()
105+
)
106+
)
107+
generated_file = Path(rpath)
108+
self.assertTrue(generated_file.exists())
109+
110+
content = generated_file.read_text().rstrip()
111+
self.assertEqual(content, "Hello world from requests")
112+
93113

94114
if __name__ == "__main__":
95115
unittest.main()

examples/pip_repository_annotations/requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
--extra-index-url https://pypi.python.org/simple/
44

55
wheel
6+
requests[security]>=2.8.1

examples/pip_repository_annotations/requirements.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66
#
77
--extra-index-url https://pypi.python.org/simple/
88

9+
certifi==2022.9.24 \
10+
--hash=sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14 \
11+
--hash=sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382
12+
# via requests
13+
charset-normalizer==2.1.1 \
14+
--hash=sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845 \
15+
--hash=sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f
16+
# via requests
17+
idna==3.4 \
18+
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
19+
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
20+
# via requests
21+
requests[security]==2.28.1 \
22+
--hash=sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983 \
23+
--hash=sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349
24+
# via -r ./requirements.in
25+
urllib3==1.26.12 \
26+
--hash=sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e \
27+
--hash=sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997
28+
# via requests
929
wheel==0.37.1 \
1030
--hash=sha256:4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a \
1131
--hash=sha256:e9a504e793efbca1b8e0e9cb979a249cf4a0a7b5b8c9e8b65a5e39d49529c1c4

python/pip_install/extract_wheels/parse_requirements_to_bzl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def entry_point(pkg, script = None):
155155
def _get_annotation(requirement):
156156
# This expects to parse `setuptools==58.2.0 --hash=sha256:2551203ae6955b9876741a26ab3e767bb3242dafe86a32a749ea0d78b6792f11`
157157
# down wo `setuptools`.
158-
name = requirement.split(" ")[0].split("=")[0]
158+
name = requirement.split(" ")[0].split("=")[0].split("[")[0]
159159
return _annotations.get(name)
160160
161161
def install_deps(**whl_library_kwargs):

0 commit comments

Comments
 (0)