@@ -386,6 +386,32 @@ def find_distributions(self, context=Context()):
386386 """
387387
388388
389+ class FastPath :
390+ """
391+ Micro-optimized class for searching a path for
392+ children.
393+ """
394+
395+ def __init__ (self , root ):
396+ self .root = root
397+
398+ def children (self ):
399+ try :
400+ children = os .listdir (self .root or '.' )
401+ path_type = pathlib .Path
402+ except Exception :
403+ try :
404+ with zipfile .ZipFile (self .root ) as zf :
405+ children = [os .path .split (child )[0 ]
406+ for child in zf .namelist ()]
407+ path_type = zipp .Path
408+ except Exception :
409+ children = []
410+ path_type = None
411+
412+ return children , path_type
413+
414+
389415@install
390416class MetadataPathFinder (NullFinder , DistributionFinder ):
391417 """A degenerate finder for distribution packages on the file system.
@@ -410,42 +436,31 @@ def find_distributions(self, context=DistributionFinder.Context()):
410436 def _search_paths (cls , name , paths ):
411437 """Find metadata directories in paths heuristically."""
412438 return itertools .chain .from_iterable (
413- cls ._search_path (path , name ) for path in paths )
439+ cls ._search_path (path , name )
440+ for path in map (FastPath , paths )
441+ )
414442
415443 @classmethod
416444 def _search_path (cls , root , name ):
417- # This function is microoptimized by avoiding the use of regexes and
418- # using strs rather than Path objects.
419- root = root or '.'
420- try :
421- children = os .listdir (root )
422- path_type = pathlib .Path
423- except Exception :
424- try :
425- with zipfile .ZipFile (root ) as zf :
426- children = [os .path .split (child )[0 ]
427- for child in zf .namelist ()]
428- path_type = zipp .Path
429- except Exception :
430- return
431445 if name is not None :
432446 normalized = name .lower ().replace ('-' , '_' )
433447 prefix = normalized + '-'
434448 else :
435449 normalized = prefix = ''
436450 suffixes = ('.dist-info' , '.egg-info' )
437451 exact_matches = [normalized + suffix for suffix in suffixes ]
438- root_n_low = os .path .split (root )[1 ].lower ()
452+ root_n_low = os .path .split (root . root )[1 ].lower ()
439453 root_is_egg = (
440454 root_n_low == normalized + '.egg'
441455 or root_n_low .startswith (prefix ) and root_n_low .endswith ('.egg' ))
456+ children , path_type = root .children ()
442457 for child in children :
443458 n_low = child .lower ()
444459 if (n_low in exact_matches
445460 or n_low .startswith (prefix ) and n_low .endswith (suffixes )
446461 # legacy case:
447462 or root_is_egg and n_low == 'egg-info' ):
448- yield path_type (root , child )
463+ yield path_type (root . root , child )
449464
450465
451466class PathDistribution (Distribution ):
0 commit comments