@@ -88,6 +88,7 @@ def parse_requirements(
8888 evaluate_markers = evaluate_markers or (lambda _ctx , _requirements : {})
8989 options = {}
9090 requirements = {}
91+ reqs_with_env_markers = {}
9192 for file , plats in requirements_by_platform .items ():
9293 logger .trace (lambda : "Using {} for {}" .format (file , plats ))
9394 contents = ctx .read (file )
@@ -96,16 +97,41 @@ def parse_requirements(
9697 # needed for the whl_library declarations later.
9798 parse_result = parse_requirements_txt (contents )
9899
100+ tokenized_options = []
101+ for opt in parse_result .options :
102+ for p in opt .split (" " ):
103+ tokenized_options .append (p )
104+
105+ pip_args = tokenized_options + extra_pip_args
106+ for plat in plats :
107+ requirements [plat ] = parse_result .requirements
108+ for entry in parse_result .requirements :
109+ requirement_line = entry [1 ]
110+
111+ # output all of the requirement lines that have a marker
112+ if ";" in requirement_line :
113+ reqs_with_env_markers .setdefault (requirement_line , []).append (plat )
114+ options [plat ] = pip_args
115+
116+ # This may call to Python, so execute it early (before calling to the
117+ # internet below) and ensure that we call it only once.
118+ resolved_marker_platforms = evaluate_markers (ctx , reqs_with_env_markers )
119+ logger .trace (lambda : "Evaluated env markers from:\n {}\n \n To:\n {}" .format (
120+ reqs_with_env_markers ,
121+ resolved_marker_platforms ,
122+ ))
123+
124+ requirements_by_platform = {}
125+ for plat , parse_results in requirements .items ():
99126 # Replicate a surprising behavior that WORKSPACE builds allowed:
100127 # Defining a repo with the same name multiple times, but only the last
101128 # definition is respected.
102129 # The requirement lines might have duplicate names because lines for extras
103130 # are returned as just the base package name. e.g., `foo[bar]` results
104131 # in an entry like `("foo", "foo[bar] == 1.0 ...")`.
105- # Lines with different markers are not condidered duplicates.
106132 requirements_dict = {}
107133 for entry in sorted (
108- parse_result . requirements ,
134+ parse_results ,
109135 # Get the longest match and fallback to original WORKSPACE sorting,
110136 # which should get us the entry with most extras.
111137 #
@@ -114,33 +140,22 @@ def parse_requirements(
114140 # should do this now.
115141 key = lambda x : (len (x [1 ].partition ("==" )[0 ]), x ),
116142 ):
117- req = requirement ( entry [1 ])
118- requirements_dict [( req . name , req . version , req . marker )] = entry
143+ req_line = entry [1 ]
144+ req = requirement ( req_line )
119145
120- tokenized_options = []
121- for opt in parse_result .options :
122- for p in opt .split (" " ):
123- tokenized_options .append (p )
146+ if req .marker and plat not in resolved_marker_platforms .get (req_line , []):
147+ continue
124148
125- pip_args = tokenized_options + extra_pip_args
126- for plat in plats :
127- requirements [plat ] = requirements_dict .values ()
128- options [plat ] = pip_args
149+ requirements_dict [req .name ] = entry
129150
130- requirements_by_platform = {}
131- reqs_with_env_markers = {}
132- for target_platform , reqs_ in requirements .items ():
133- extra_pip_args = options [target_platform ]
151+ extra_pip_args = options [plat ]
134152
135- for distribution , requirement_line in reqs_ :
153+ for distribution , requirement_line in requirements_dict . values () :
136154 for_whl = requirements_by_platform .setdefault (
137155 normalize_name (distribution ),
138156 {},
139157 )
140158
141- if ";" in requirement_line :
142- reqs_with_env_markers .setdefault (requirement_line , []).append (target_platform )
143-
144159 for_req = for_whl .setdefault (
145160 (requirement_line , "," .join (extra_pip_args )),
146161 struct (
@@ -151,20 +166,7 @@ def parse_requirements(
151166 extra_pip_args = extra_pip_args ,
152167 ),
153168 )
154- for_req .target_platforms .append (target_platform )
155-
156- # This may call to Python, so execute it early (before calling to the
157- # internet below) and ensure that we call it only once.
158- #
159- # NOTE @aignas 2024-07-13: in the future, if this is something that we want
160- # to do, we could use Python to parse the requirement lines and infer the
161- # URL of the files to download things from. This should be important for
162- # VCS package references.
163- env_marker_target_platforms = evaluate_markers (ctx , reqs_with_env_markers )
164- logger .trace (lambda : "Evaluated env markers from:\n {}\n \n To:\n {}" .format (
165- reqs_with_env_markers ,
166- env_marker_target_platforms ,
167- ))
169+ for_req .target_platforms .append (plat )
168170
169171 index_urls = {}
170172 if get_index_urls :
@@ -183,8 +185,7 @@ def parse_requirements(
183185 for name , reqs in sorted (requirements_by_platform .items ()):
184186 requirement_target_platforms = {}
185187 for r in reqs .values ():
186- target_platforms = env_marker_target_platforms .get (r .requirement_line , r .target_platforms )
187- for p in target_platforms :
188+ for p in r .target_platforms :
188189 requirement_target_platforms [p ] = None
189190
190191 item = struct (
@@ -197,7 +198,6 @@ def parse_requirements(
197198 reqs = reqs ,
198199 index_urls = index_urls ,
199200 platforms = platforms ,
200- env_marker_target_platforms = env_marker_target_platforms ,
201201 extract_url_srcs = extract_url_srcs ,
202202 logger = logger ,
203203 ),
@@ -221,18 +221,13 @@ def _package_srcs(
221221 index_urls ,
222222 platforms ,
223223 logger ,
224- env_marker_target_platforms ,
225224 extract_url_srcs ):
226225 """A function to return sources for a particular package."""
227226 srcs = {}
228227 for r in sorted (reqs .values (), key = lambda r : r .requirement_line ):
229- if ";" in r .requirement_line :
230- target_platforms = env_marker_target_platforms .get (r .requirement_line , [])
231- else :
232- target_platforms = r .target_platforms
233228 extra_pip_args = tuple (r .extra_pip_args )
234229
235- for target_platform in target_platforms :
230+ for target_platform in r . target_platforms :
236231 if platforms and target_platform not in platforms :
237232 fail ("The target platform '{}' could not be found in {}" .format (
238233 target_platform ,
0 commit comments