@@ -258,7 +258,10 @@ def _get_html_page(link, session=None):
258
258
259
259
class CandidateEvaluator (object ):
260
260
261
- _py_version_re = re .compile (r'-py([123]\.?[0-9]?)$' )
261
+ """
262
+ Responsible for filtering and sorting candidates for installation based
263
+ on what tags are valid.
264
+ """
262
265
263
266
def __init__ (
264
267
self ,
@@ -269,6 +272,11 @@ def __init__(
269
272
self ._prefer_binary = prefer_binary
270
273
self ._valid_tags = valid_tags
271
274
275
+ # We compile the regex here instead of as a class attribute so as
276
+ # not to not impact pip start-up time. This is also okay because
277
+ # CandidateEvaluator is generally instantiated only once per pip
278
+ # invocation (when PackageFinder is instantiated).
279
+ self ._py_version_re = re .compile (r'-py([123]\.?[0-9]?)$' )
272
280
# These are boring links that have already been logged somehow.
273
281
self ._logged_links = set () # type: Set[Link]
274
282
@@ -278,13 +286,17 @@ def _log_skipped_link(self, link, reason):
278
286
logger .debug ('Skipping link %s; %s' , link , reason )
279
287
self ._logged_links .add (link )
280
288
281
- def is_wheel_supported (self , wheel ):
289
+ def _is_wheel_supported (self , wheel ):
282
290
# type: (Wheel) -> bool
283
291
return wheel .supported (self ._valid_tags )
284
292
285
- def _link_package_versions (self , link , search ):
293
+ def evaluate_link (self , link , search ):
286
294
# type: (Link, Search) -> Optional[InstallationCandidate]
287
- """Return an InstallationCandidate or None"""
295
+ """
296
+ Determine whether a link is a candidate for installation.
297
+
298
+ Returns an InstallationCandidate if so, otherwise None.
299
+ """
288
300
version = None
289
301
if link .egg_fragment :
290
302
egg_info = link .egg_fragment
@@ -318,7 +330,7 @@ def _link_package_versions(self, link, search):
318
330
link , 'wrong project name (not %s)' % search .supplied )
319
331
return None
320
332
321
- if not self .is_wheel_supported (wheel ):
333
+ if not self ._is_wheel_supported (wheel ):
322
334
self ._log_skipped_link (
323
335
link , 'it is not compatible with this Python' )
324
336
return None
@@ -384,7 +396,7 @@ def _sort_key(self, candidate):
384
396
if candidate .location .is_wheel :
385
397
# can raise InvalidWheelFilename
386
398
wheel = Wheel (candidate .location .filename )
387
- if not wheel . supported ( self ._valid_tags ):
399
+ if not self ._is_wheel_supported ( wheel ):
388
400
raise UnsupportedWheel (
389
401
"%s is not a supported wheel for this platform. It "
390
402
"can't be sorted." % wheel .filename
@@ -762,7 +774,7 @@ def find_all_candidates(self, project_name):
762
774
This checks index_urls and find_links.
763
775
All versions found are returned as an InstallationCandidate list.
764
776
765
- See _link_package_versions for details on which files are accepted
777
+ See evaluate_link() for details on which files are accepted
766
778
"""
767
779
index_locations = self ._get_index_urls_locations (project_name )
768
780
index_file_loc , index_url_loc = self ._sort_locations (index_locations )
@@ -962,9 +974,9 @@ def _package_versions(
962
974
# type: (...) -> List[InstallationCandidate]
963
975
result = []
964
976
for link in self ._sort_links (links ):
965
- v = self .candidate_evaluator ._link_package_versions (link , search )
966
- if v is not None :
967
- result .append (v )
977
+ candidate = self .candidate_evaluator .evaluate_link (link , search )
978
+ if candidate is not None :
979
+ result .append (candidate )
968
980
return result
969
981
970
982
0 commit comments