[Python-checkins] distutils2: Added fallback support for .egg-info distributions

tarek.ziade python-checkins at python.org
Mon May 31 01:56:09 CEST 2010


tarek.ziade pushed a838155c9fe2 to distutils2:
http://hg.python.org/distutils2/rev/a838155c9fe2
changeset: 181:a838155c9fe2
user: Josip Djolonga
date: Sat May 29 18:02:57 2010 +0200
summary: Added fallback support for .egg-info distributions
files: src/distutils2/_backport/pkgutil.py, src/distutils2/_backport/tests/test_pkgutil.py
diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py
--- a/src/distutils2/_backport/pkgutil.py
+++ b/src/distutils2/_backport/pkgutil.py
@@ -17,8 +17,9 @@
 'get_importer', 'iter_importers', 'get_loader', 'find_loader',
 'walk_packages', 'iter_modules',
 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
- 'Distribution', 'distinfo_dirname', 'get_distributions',
- 'get_distribution', 'get_file_users',
+ 'Distribution', 'EggInfoDistribution', 'distinfo_dirname',
+ 'get_distributions', 'get_distribution', 'get_file_users',
+ 'provides_distribution', 'obsoletes_distribution',
 ]
 
 def read_code(stream):
@@ -604,7 +605,7 @@
 name = ''
 """The name of the distribution."""
 metadata = None
- """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with 
+ """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with
 the distribution's METADATA file."""
 requested = False
 """A boolean that indicates whether the REQUESTED metadata file is present
@@ -646,7 +647,7 @@
 
 def uses(self, path):
 """
- Returns ``True`` if path is listed in RECORD. *path* can be a local 
+ Returns ``True`` if path is listed in RECORD. *path* can be a local
 absolute path or a relative ``'/'``-separated path.
 
 :rtype: boolean
@@ -709,6 +710,29 @@
 for path, md5, size in self._get_records(local):
 yield path
 
+class EggInfoDistribution:
+ """Created with the *path* of the ``.egg-info`` directory or file provided
+ to the constructor. It reads the metadata contained in the file itself, or
+ if the given path happens to be a directory, the metadata is read from the
+ file PKG-INFO under that directory."""
+
+ name = ''
+ """The name of the distribution."""
+ metadata = None
+ """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with
+ the distribution's METADATA file."""
+
+ def __init__(self, path):
+ if os.path.isdir(path):
+ path = os.path.join(path, 'PKG-INFO')
+ self.metadata = DistributionMetadata(path=path)
+ self.name = self.metadata['name']
+
+ def get_installed_files(self, local=False):
+ return []
+
+ def uses(self, path):
+ return False
 
 def _normalize_dist_name(name):
 """Returns a normalized name from the given *name*.
@@ -719,7 +743,7 @@
 """
 The *name* and *version* parameters are converted into their
 filename-escaped form, i.e. any ``'-'`` characters are replaced with ``'_'``
- other than the one in ``'dist-info'`` and the one separating the name from 
+ other than the one in ``'dist-info'`` and the one separating the name from
 the version number.
 
 :parameter name: is converted to a standard distribution name by replacing
@@ -743,13 +767,15 @@
 normalized_version = version
 return '-'.join([name, normalized_version]) + file_extension
 
-def get_distributions():
+def get_distributions(use_egg_info = False):
 """
 Provides an iterator that looks for ``.dist-info`` directories in
 ``sys.path`` and returns :class:`Distribution` instances for each one of
- them.
+ them. If the parameters *use_egg_info* is ``True``, then the ``.egg-info``
+ files and directores are iterated as well.
 
- :rtype: iterator of :class:`Distribution` instances"""
+ :rtype: iterator of :class:`Distribution` and :class:`EggInfoDistribution`
+ instances"""
 for path in sys.path:
 realpath = os.path.realpath(path)
 if not os.path.isdir(realpath):
@@ -758,35 +784,50 @@
 if dir.endswith('.dist-info'):
 dist = Distribution(os.path.join(realpath, dir))
 yield dist
+ elif use_egg_info and dir.endswith('.egg-info'):
+ dist = EggInfoDistribution(os.path.join(realpath, dir))
+ yield dist
 
-def get_distribution(name):
+def get_distribution(name, use_egg_info = False):
 """
 Scans all elements in ``sys.path`` and looks for all directories ending with
 ``.dist-info``. Returns a :class:`Distribution` corresponding to the
 ``.dist-info`` directory that contains the METADATA that matches *name* for
- the *name* metadata.
+ the *name* metadata field.
+ If no distribution exists with the given *name* and the parameter
+ *use_egg_info* is set to ``True``, then all files and directories ending
+ with ``.egg-info`` are scanned. A :class:`EggInfoDistribution` instance is
+ returned if one is found that has metadata that matches *name* for the
+ *name* metadata field.
 
 This function only returns the first result founded, as no more than one
 value is expected. If the directory is not found, ``None`` is returned.
 
- :rtype: :class:`Distribution` or None"""
+ :rtype: :class:`Distribution` or :class:`EggInfoDistribution: or None"""
 found = None
 for dist in get_distributions():
 if dist.name == name:
 found = dist
 break
+ if use_egg_info:
+ for dist in get_distributions(True):
+ if dist.name == name:
+ found = dist
+ break
 return found
 
-def obsoletes_distribution(name, version=None):
+def obsoletes_distribution(name, version=None, use_egg_info = False):
 """
 Iterates over all distributions to find which distributions obsolete *name*.
 If a *version* is provided, it will be used to filter the results.
+ If the argument *use_egg_info* is set to ``True``, then ``.egg-info``
+ distributions will be considered as well.
 
 :type name: string
 :type version: string
 :parameter name:
 """
- for dist in get_distributions():
+ for dist in get_distributions(use_egg_info):
 obsoleted = dist.metadata['Obsoletes-Dist'] + dist.metadata['Obsoletes']
 for obs in obsoleted:
 o_components = obs.split(' ', 1)
@@ -804,14 +845,16 @@
 yield dist
 break
 
-def provides_distribution(name, version=None):
+def provides_distribution(name, version=None, use_egg_info = False):
 """
 Iterates over all distributions to find which distributions provide *name*.
 If a *version* is provided, it will be used to filter the results. Scans
 all elements in ``sys.path`` and looks for all directories ending with
 ``.dist-info``. Returns a :class:`Distribution` corresponding to the
 ``.dist-info`` directory that contains a ``METADATA`` that matches *name*
- for the name metadata.
+ for the name metadata. If the argument *use_egg_info* is set to ``True``,
+ then all files and directories ending with ``.egg-info`` are considered
+ as well and returns an :class:`EggInfoDistribution` instance.
 
 This function only returns the first result founded, since no more than
 one values are expected. If the directory is not found, returns ``None``.
@@ -829,7 +872,7 @@
 except ValueError:
 raise DistutilsError('Invalid name or version')
 
- for dist in get_distributions():
+ for dist in get_distributions(use_egg_info):
 provided = dist.metadata['Provides-Dist'] + dist.metadata['Provides']
 
 for p in provided:
diff --git a/src/distutils2/_backport/tests/test_pkgutil.py b/src/distutils2/_backport/tests/test_pkgutil.py
--- a/src/distutils2/_backport/tests/test_pkgutil.py
+++ b/src/distutils2/_backport/tests/test_pkgutil.py
@@ -216,7 +216,9 @@
 found_dists = []
 
 # Import the function in question
- from distutils2._backport.pkgutil import get_distributions, Distribution
+ from distutils2._backport.pkgutil import get_distributions, \
+ Distribution, \
+ EggInfoDistribution
 
 # Verify the fake dists have been found.
 dists = [ dist for dist in get_distributions() ]
@@ -231,13 +233,31 @@
 # Finally, test that we found all that we were looking for
 self.assertListEqual(sorted(found_dists), sorted(fake_dists))
 
+ # Now, test if the egg-info distributions are found correctly as well
+ fake_dists += [('bacon', '0.1'), ('cheese', '2.0.2')]
+ found_dists = []
+
+ dists = [ dist for dist in get_distributions(use_egg_info=True) ]
+ for dist in dists:
+ if not (isinstance(dist, Distribution) or \
+ isinstance(dist, EggInfoDistribution)):
+ self.fail("item received was not a Distribution or "
+ "EggInfoDistribution instance: %s" % type(dist))
+ if dist.name in dict(fake_dists).keys():
+ found_dists.append((dist.name, dist.metadata['version']))
+
+ self.assertListEqual(sorted(fake_dists), sorted(found_dists))
+
+
 def test_get_distribution(self):
 """Test for looking up a distribution by name."""
 # Test the lookup of the towel-stuff distribution
 name = 'towel-stuff' # Note: This is different from the directory name
 
 # Import the function in question
- from distutils2._backport.pkgutil import get_distribution, Distribution
+ from distutils2._backport.pkgutil import get_distribution, \
+ Distribution, \
+ EggInfoDistribution
 
 # Lookup the distribution
 dist = get_distribution(name)
@@ -250,6 +270,21 @@
 # Verify partial name matching doesn't work
 self.assertEqual(None, get_distribution('towel'))
 
+ # Verify that it does not find egg-info distributions, when not
+ # instructed to
+ self.assertEqual(None, get_distribution('bacon'))
+ self.assertEqual(None, get_distribution('cheese'))
+
+ # Now check that it works well in both situations, when egg-info
+ # is a file and directory respectively.
+ dist = get_distribution('cheese', use_egg_info=True)
+ self.assertTrue(isinstance(dist, EggInfoDistribution))
+ self.assertEqual(dist.name, 'cheese')
+
+ dist = get_distribution('bacon', use_egg_info=True)
+ self.assertTrue(isinstance(dist, EggInfoDistribution))
+ self.assertEqual(dist.name, 'bacon')
+
 def test_get_file_users(self):
 """Test the iteration of distributions that use a file."""
 from distutils2._backport.pkgutil import get_file_users, Distribution
@@ -265,46 +300,74 @@
 from distutils2._backport.pkgutil import provides_distribution
 from distutils2.errors import DistutilsError
 
+ checkLists = lambda x,y: self.assertListEqual(sorted(x), sorted(y))
+
 l = [dist.name for dist in provides_distribution('truffles')]
- self.assertListEqual(l, ['choxie', 'towel-stuff'])
+ checkLists(l, ['choxie', 'towel-stuff'])
 
 l = [dist.name for dist in provides_distribution('truffles', '1.0')]
- self.assertListEqual(l, ['choxie'])
+ checkLists(l, ['choxie'])
+
+ l = [dist.name for dist in provides_distribution('truffles', '1.0',
+ use_egg_info=True)]
+ checkLists(l, ['choxie', 'cheese'])
 
 l = [dist.name for dist in provides_distribution('truffles', '1.1.2')]
- self.assertListEqual(l, ['towel-stuff'])
+ checkLists(l, ['towel-stuff'])
 
 l = [dist.name for dist in provides_distribution('truffles', '1.1')]
- self.assertListEqual(l, ['towel-stuff'])
+ checkLists(l, ['towel-stuff'])
 
 l = [dist.name for dist in provides_distribution('truffles', '!=1.1,<=2.0')]
- self.assertListEqual(l, ['choxie'])
+ checkLists(l, ['choxie'])
+
+ l = [dist.name for dist in provides_distribution('truffles', '!=1.1,<=2.0',
+ use_egg_info=True)]
+ checkLists(l, ['choxie', 'bacon', 'cheese'])
 
 l = [dist.name for dist in provides_distribution('truffles', '>1.0')]
- self.assertListEqual(l, ['towel-stuff'])
+ checkLists(l, ['towel-stuff'])
+
+ l = [dist.name for dist in provides_distribution('truffles', '>1.5')]
+ checkLists(l, [])
+
+ l = [dist.name for dist in provides_distribution('truffles', '>1.5',
+ use_egg_info=True)]
+ checkLists(l, ['bacon'])
 
 l = [dist.name for dist in provides_distribution('truffles', '>=1.0')]
- self.assertListEqual(l, ['choxie', 'towel-stuff'])
+ checkLists(l, ['choxie', 'towel-stuff'])
 
 def test_obsoletes(self):
 """ Test looking for distributions based on what they obsolete """
 from distutils2._backport.pkgutil import obsoletes_distribution
 from distutils2.errors import DistutilsError
 
+ checkLists = lambda x,y: self.assertListEqual(sorted(x), sorted(y))
+
 l = [dist.name for dist in obsoletes_distribution('truffles', '1.0')]
- self.assertListEqual(l, [])
+ checkLists(l, [])
+
+ l = [dist.name for dist in obsoletes_distribution('truffles', '1.0',
+ use_egg_info=True)]
+ checkLists(l, ['cheese', 'bacon'])
+
 
 l = [dist.name for dist in obsoletes_distribution('truffles', '0.8')]
- self.assertListEqual(l, ['choxie'])
+ checkLists(l, ['choxie'])
+
+ l = [dist.name for dist in obsoletes_distribution('truffles', '0.8',
+ use_egg_info=True)]
+ checkLists(l, ['choxie', 'cheese'])
 
 l = [dist.name for dist in obsoletes_distribution('truffles', '0.9.6')]
- self.assertListEqual(l, ['choxie', 'towel-stuff'])
+ checkLists(l, ['choxie', 'towel-stuff'])
 
 l = [dist.name for dist in obsoletes_distribution('truffles', '0.5.2.3')]
- self.assertListEqual(l, ['choxie', 'towel-stuff'])
+ checkLists(l, ['choxie', 'towel-stuff'])
 
 l = [dist.name for dist in obsoletes_distribution('truffles', '0.2')]
- self.assertListEqual(l, ['towel-stuff'])
+ checkLists(l, ['towel-stuff'])
 
 
 def test_suite():
--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /