2
2
import json
3
3
import textwrap
4
4
import sys
5
+ import shlex
5
6
from typing import List , Tuple
6
7
7
8
from python .pip_install .extract_wheels .lib import bazel , arguments
8
9
from pip ._internal .req import parse_requirements , constructors
9
10
from pip ._internal .req .req_install import InstallRequirement
11
+ from pip ._internal .req .req_file import get_file_content , preprocess , handle_line , get_line_parser , RequirementsFileParser
10
12
from pip ._internal .network .session import PipSession
11
13
12
14
13
- def parse_install_requirements (requirements_lock : str ) -> List [InstallRequirement ]:
14
- return [
15
- constructors .install_req_from_parsed_requirement (pr )
16
- for pr in parse_requirements (requirements_lock , session = PipSession ())
17
- ]
15
+ def parse_install_requirements (requirements_lock : str , extra_pip_args : List [str ]) -> List [Tuple [InstallRequirement , str ]]:
16
+ ps = PipSession ()
17
+ # This is roughly taken from pip._internal.req.req_file.parse_requirements
18
+ # (https://github.com/pypa/pip/blob/21.0.1/src/pip/_internal/req/req_file.py#L127) in order to keep
19
+ # the original line (sort-of, its preprocessed) from the requirements_lock file around, to pass to sub repos
20
+ # as the requirement.
21
+ line_parser = get_line_parser (finder = None )
22
+ parser = RequirementsFileParser (ps , line_parser )
23
+ install_req_and_lines : List [Tuple [InstallRequirement , str ]] = []
24
+ _ , content = get_file_content (requirements_lock , ps )
25
+ for parsed_line , (_ , line ) in zip (parser .parse (requirements_lock , constraint = False ), preprocess (content )):
26
+ if parsed_line .is_requirement :
27
+ install_req_and_lines .append (
28
+ (
29
+ constructors .install_req_from_line (parsed_line .requirement ),
30
+ line
31
+ )
32
+ )
33
+
34
+ else :
35
+ extra_pip_args .extend (shlex .split (line ))
36
+ return install_req_and_lines
18
37
19
38
20
- def repo_names_and_requirements (install_reqs : List [InstallRequirement ], repo_prefix : str ) -> List [Tuple [str , str ]]:
39
+ def repo_names_and_requirements (install_reqs : List [Tuple [ InstallRequirement , str ] ], repo_prefix : str ) -> List [Tuple [str , str ]]:
21
40
return [
22
41
(
23
42
bazel .sanitise_name (ir .name , prefix = repo_prefix ),
24
- str ( ir . req )
43
+ line ,
25
44
)
26
- for ir in install_reqs
45
+ for ir , line in install_reqs
27
46
]
28
47
29
48
def deserialize_structured_args (args ):
@@ -35,6 +54,8 @@ def deserialize_structured_args(args):
35
54
for arg_name in structured_args :
36
55
if args .get (arg_name ) is not None :
37
56
args [arg_name ] = json .loads (args [arg_name ])["args" ]
F438
57
+ else :
58
+ args [arg_name ] = []
38
59
return args
39
60
40
61
@@ -54,13 +75,13 @@ def generate_parsed_requirements_contents(all_args: argparse.Namespace) -> str:
54
75
requirements_lock = args .pop ("requirements_lock" )
55
76
repo_prefix = bazel .whl_library_repo_prefix (args ["repo" ])
56
77
57
- install_reqs = parse_install_requirements (requirements_lock )
58
- repo_names_and_reqs = repo_names_and_requirements (install_reqs , repo_prefix )
78
+ install_req_and_lines = parse_install_requirements (requirements_lock , args [ "extra_pip_args" ] )
79
+ repo_names_and_reqs = repo_names_and_requirements (install_req_and_lines , repo_prefix )
59
80
all_requirements = ", " .join (
60
- [bazel .sanitised_repo_library_label (ir .name , repo_prefix = repo_prefix ) for ir in install_reqs ]
81
+ [bazel .sanitised_repo_library_label (ir .name , repo_prefix = repo_prefix ) for ir , _ in install_req_and_lines ]
61
82
)
62
83
all_whl_requirements = ", " .join (
63
- [bazel .sanitised_repo_file_label (ir .name , repo_prefix = repo_prefix ) for ir in install_reqs ]
84
+ [bazel .sanitised_repo_file_label (ir .name , repo_prefix = repo_prefix ) for ir , _ in install_req_and_lines ]
64
85
)
65
86
return textwrap .dedent ("""\
66
87
load("@rules_python//python/pip_install:pip_repository.bzl", "whl_library")
0 commit comments