1919
2020__all__ = [
2121 'Distribution' ,
22+ 'DistributionFinder' ,
2223 'PackageNotFoundError' ,
2324 'distribution' ,
2425 'distributions' ,
@@ -158,24 +159,41 @@ def from_name(cls, name):
158159 metadata cannot be found.
159160 """
160161 for resolver in cls ._discover_resolvers ():
161- dists = resolver (name )
162+ dists = resolver (DistributionFinder . Context ( name = name ) )
162163 dist = next (dists , None )
163164 if dist is not None :
164165 return dist
165166 else :
166167 raise PackageNotFoundError (name )
167168
168169 @classmethod
169- def discover (cls ):
170+ def discover (cls , ** kwargs ):
170171 """Return an iterable of Distribution objects for all packages.
171172
173+ Pass a ``context`` or pass keyword arguments for constructing
174+ a context.
175+
176+ :context: A ``DistributionFinder.Context`` object.
172177 :return: Iterable of Distribution objects for all packages.
173178 """
179+ context = kwargs .pop ('context' , None )
180+ if context and kwargs :
181+ raise ValueError ("cannot accept context and kwargs" )
182+ context = context or DistributionFinder .Context (** kwargs )
174183 return itertools .chain .from_iterable (
175- resolver ()
184+ resolver (context )
176185 for resolver in cls ._discover_resolvers ()
177186 )
178187
188+ @staticmethod
189+ def at (path ):
190+ """Return a Distribution for the indicated metadata path
191+
192+ :param path: a string or path-like object
193+ :return: a concrete Distribution instance for the path
194+ """
195+ return PathDistribution (pathlib .Path (path ))
196+
179197 @staticmethod
180198 def _discover_resolvers ():
181199 """Search the meta_path for resolvers."""
@@ -215,7 +233,7 @@ def entry_points(self):
215233 def files (self ):
216234 """Files in this distribution.
217235
218- :return: Iterable of PackagePath for this distribution or None
236+ :return: List of PackagePath for this distribution or None
219237
220238 Result is `None` if the metadata file that enumerates files
221239 (i.e. RECORD for dist-info or SOURCES.txt for egg-info) is
@@ -231,7 +249,7 @@ def make_file(name, hash=None, size_str=None):
231249 result .dist = self
232250 return result
233251
234- return file_lines and starmap (make_file , csv .reader (file_lines ))
252+ return file_lines and list ( starmap (make_file , csv .reader (file_lines ) ))
235253
236254 def _read_files_distinfo (self ):
237255 """
@@ -251,7 +269,8 @@ def _read_files_egginfo(self):
251269 @property
252270 def requires (self ):
253271 """Generated requirements specified for this Distribution"""
254- return self ._read_dist_info_reqs () or self ._read_egg_info_reqs ()
272+ reqs = self ._read_dist_info_reqs () or self ._read_egg_info_reqs ()
273+ return reqs and list (reqs )
255274
256275 def _read_dist_info_reqs (self ):
257276 return self .metadata .get_all ('Requires-Dist' )
@@ -312,15 +331,35 @@ class DistributionFinder(MetaPathFinder):
312331 A MetaPathFinder capable of discovering installed distributions.
313332 """
314333
334+ class Context :
335+
336+ name = None
337+ """
338+ Specific name for which a distribution finder should match.
339+ """
340+
341+ def __init__ (self , ** kwargs ):
342+ vars (self ).update (kwargs )
343+
344+ @property
345+ def path (self ):
346+ """
347+ The path that a distribution finder should search.
348+ """
349+ return vars (self ).get ('path' , sys .path )
350+
351+ @property
352+ def pattern (self ):
353+ return '.*' if self .name is None else re .escape (self .name )
354+
315355 @abc .abstractmethod
316- def find_distributions (self , name = None , path = None ):
356+ def find_distributions (self , context = Context () ):
317357 """
318358 Find distributions.
319359
320360 Return an iterable of all Distribution instances capable of
321- loading the metadata for packages matching the ``name``
322- (or all names if not supplied) along the paths in the list
323- of directories ``path`` (defaults to sys.path).
361+ loading the metadata for packages matching the ``context``,
362+ a DistributionFinder.Context instance.
324363 """
325364
326365
@@ -352,12 +391,12 @@ def distribution(package):
352391 return Distribution .from_name (package )
353392
354393
355- def distributions ():
394+ def distributions (** kwargs ):
356395 """Get all ``Distribution`` instances in the current environment.
357396
358397 :return: An iterable of ``Distribution`` instances.
359398 """
360- return Distribution .discover ()
399+ return Distribution .discover (** kwargs )
361400
362401
363402def metadata (package ):
0 commit comments