[Python-checkins] distutils2: now checking Requires-Python and Name

tarek.ziade python-checkins at python.org
Fri Mar 12 19:32:53 CET 2010


tarek.ziade pushed 29e64afc676d to distutils2:
http://hg.python.org/distutils2/rev/29e64afc676d
changeset: 73:29e64afc676d
tag: tip
user: Tarek Ziade <tarek at ziade.org>
date: Fri Mar 12 13:26:01 2010 -0500
summary: now checking Requires-Python and Name
files: src/distutils2/metadata.py, src/distutils2/tests/test_metadata.py, src/distutils2/version.py
diff --git a/src/distutils2/metadata.py b/src/distutils2/metadata.py
--- a/src/distutils2/metadata.py
+++ b/src/distutils2/metadata.py
@@ -1,55 +1,9 @@
 """
-==================================================
 Implementation of the Metadata for Python packages
-==================================================
 
-The file format is RFC 822 and there are currently three implementations.
-We only support reading/writing Metadata v1.0 or v1.2. If 1.1 is encountered
-1.1 extra fields will be ignored.
+Supports all Metadata formats (1.0, 1.1, 1.2).
+"""
 
-PEP 241 - Metadata v1.0
-=======================
-
-- Metadata-Version
-- Name
-- Version
-- Platform (multiple)
-- Summary
-- Description (optional)
-- Keywords (optional)
-- Home-page (optional)
-- Author (optional)
-- Author-email (optional)
-- License (optional)
-
-PEP 345 - Metadata v1.2
-=======================
-
-# XXX adding codename ? multiple email rfc232 ?
-
-- Metadata-Version
-- Name
-- Version
-- Platform (multiple)
-- Supported-Platform (multiple)
-- Summary
-- Description (optional) -- changed format
-- Keywords (optional)
-- Home-page (optional)
-- Download-URL
-- Author (optional)
-- Author-email (optional)
-- Maintainer (optional)
-- Maintainer-email (optional)
-- License (optional)
-- Classifier (multiple) -- see PEP 241
-- Requires-Python
-- Requires-External (multiple)
-- Requires-Dist (multiple)
-- Provides-Dist (multiple)
-- Obsoletes-Dist (multiple)
-
-"""
 import re
 import os
 import sys
@@ -60,7 +14,8 @@
 
 from distutils2.log import warn
 from distutils2.util import rfc822_escape
-from distutils2.version import is_valid_predicate
+from distutils2.version import (is_valid_predicate, is_valid_version,
+ is_valid_versions)
 from distutils2.errors import (MetadataConflictError,
 MetadataUnrecognizedVersionError)
 
@@ -122,10 +77,11 @@
 'Requires-External')
 
 _345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python',
- 'Obsoletes-Dist', 'Requires-External', 'Maintainer',
- 'Maintainer-email')
+ 'Obsoletes-Dist', 'Requires-External', 'Maintainer',
+ 'Maintainer-email')
 
 _ALL_FIELDS = []
+
 for field in _241_FIELDS + _314_FIELDS + _345_FIELDS:
 if field in _ALL_FIELDS:
 continue
@@ -164,37 +120,37 @@
 return '1.2'
 
 _ATTR2FIELD = {'metadata_version': 'Metadata-Version',
- 'name': 'Name',
- 'version': 'Version',
- 'platform': 'Platform',
- 'supported_platform': 'Supported-Platform',
- 'description': 'Summary',
- 'long_description': 'Description',
- 'keywords': 'Keywords',
- 'url': 'Home-page',
- 'author': 'Author',
- 'author_email': 'Author-email',
- 'maintainer': 'Maintainer',
- 'maintainer_email': 'Maintainer-email',
- 'licence': 'License',
- 'classifier': 'Classifier',
- 'download_url': 'Download-URL',
- 'obsoletes_dist': 'Obsoletes-Dist',
- 'provides_dist': 'Provides-Dist',
- 'requires_dist': 'Requires-Dist',
- 'requires_python': 'Requires-Python',
- 'requires_external': 'Requires-External',
- 'requires': 'Requires',
- 'provides': 'Provides',
- 'obsoletes': 'Obsoletes',
- }
+ 'name': 'Name',
+ 'version': 'Version',
+ 'platform': 'Platform',
+ 'supported_platform': 'Supported-Platform',
+ 'description': 'Summary',
+ 'long_description': 'Description',
+ 'keywords': 'Keywords',
+ 'url': 'Home-page',
+ 'author': 'Author',
+ 'author_email': 'Author-email',
+ 'maintainer': 'Maintainer',
+ 'maintainer_email': 'Maintainer-email',
+ 'licence': 'License',
+ 'classifier': 'Classifier',
+ 'download_url': 'Download-URL',
+ 'obsoletes_dist': 'Obsoletes-Dist',
+ 'provides_dist': 'Provides-Dist',
+ 'requires_dist': 'Requires-Dist',
+ 'requires_python': 'Requires-Python',
+ 'requires_external': 'Requires-External',
+ 'requires': 'Requires',
+ 'provides': 'Provides',
+ 'obsoletes': 'Obsoletes',
+ }
 
 _PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist')
-
+_VERSIONS_FIELDS = ('Requires-Python',)
+_VERSION_FIELDS = ('Version',)
 _LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes',
- 'Requires', 'Provides', 'Obsoletes-Dist',
- 'Provides-Dist', 'Requires-Dist', 'Requires-Python',
- 'Requires-External')
+ 'Requires', 'Provides', 'Obsoletes-Dist',
+ 'Provides-Dist', 'Requires-Dist', 'Requires-External')
 
 _ELEMENTSFIELD = ('Keywords',)
 
@@ -347,23 +303,37 @@
 """Controls then sets a metadata field"""
 name = self._convert_name(name)
 
- # XXX need to parse the Requires-Python value
- #
+ if (name in _ELEMENTSFIELD + ('Platform',) and
+ not isinstance(value, (list, tuple))):
+ if isinstance(value, str):
+ value = value.split(',')
+ else:
+ value = []
+ elif (name in _LISTFIELDS and
+ not isinstance(value, (list, tuple))):
+ if isinstance(value, str):
+ value = [value]
+ else:
+ value = None
+
 if name in _PREDICATE_FIELDS and value is not None:
 for v in value:
 # check that the values are valid predicates
 if not is_valid_predicate(v.split(';')[0]):
 warn('"%s" is not a valid predicate' % v)
- if name in _LISTFIELDS + _ELEMENTSFIELD:
- if isinstance(value, str):
- value = value.split(',')
- elif name in _UNICODEFIELDS:
+ elif name in _VERSIONS_FIELDS and value is not None:
+ if not is_valid_versions(value):
+ warn('"%s" is not a valid predicate' % value)
+ elif name in _VERSION_FIELDS and value is not None:
+ if not is_valid_version(value):
+ warn('"%s" is not a valid version' % value)
+
+ if name in _UNICODEFIELDS:
 value = self._encode_field(value)
 if name == 'Description':
 value = self._remove_line_prefix(value)
+
 self._fields[name] = value
- # will trigger an error in case the user
- # tries to set incompatible versions fields
 self._set_best_version()
 
 def get(self, name):
diff --git a/src/distutils2/tests/test_metadata.py b/src/distutils2/tests/test_metadata.py
--- a/src/distutils2/tests/test_metadata.py
+++ b/src/distutils2/tests/test_metadata.py
@@ -137,11 +137,53 @@
 def test_warnings(self):
 metadata = DistributionMetadata()
 
- # this should raise a warning
- # XXX how to test this on 2.4 ?
- metadata['Requires-Dist'] = ['Funky (Groovie)']
+ # these should raise a warning
+ values = (('Requires-Dist', 'Funky (Groovie)'),
+ ('Requires-Python', '1-4'))
 
+ from distutils2 import metadata as m
+ old = m.warn
+ m.warns = 0
 
+ def _warn(*args):
+ m.warns += 1
+
+ m.warn = _warn
+
+ try:
+ for name, value in values:
+ metadata.set(name, value)
+ finally:
+ m.warn = old
+ res = m.warns
+ del m.warns
+
+ # we should have a certain amount of warnings
+ num_wanted = len(values)
+ self.assertEquals(num_wanted, res)
+
+ def test_multiple_predicates(self):
+ metadata = DistributionMetadata()
+
+ from distutils2 import metadata as m
+ old = m.warn
+ m.warns = 0
+
+ def _warn(*args):
+ m.warns += 1
+
+ # see for "3" instead of "3.0" ???
+ # its seems like the MINOR VERSION can be omitted
+ m.warn = _warn
+ try:
+ metadata['Requires-Python'] = '>=2.6, <3.0'
+ metadata['Requires-Dist'] = ['Foo (>=2.6, <3.0)']
+ finally:
+ m.warn = old
+ res = m.warns
+ del m.warns
+
+ self.assertEquals(res, 0)
 
 def test_suite():
 return unittest2.makeSuite(DistributionMetadataTestCase)
diff --git a/src/distutils2/version.py b/src/distutils2/version.py
--- a/src/distutils2/version.py
+++ b/src/distutils2/version.py
@@ -312,6 +312,7 @@
 
 _PREDICATE = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")
 _VERSIONS = re.compile(r"^\s*\((.*)\)\s*$")
+_PLAIN_VERSIONS = re.compile(r"^\s*(.*)\s*$")
 _SPLIT_CMP = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
 
 def _split_predicate(predicate):
@@ -323,6 +324,7 @@
 comp, version = match.groups()
 return comp, NormalizedVersion(version)
 
+
 class VersionPredicate(object):
 """Defines a predicate: ProjectName (>ver1,ver2, ..)"""
 
@@ -341,7 +343,6 @@
 
 self.name, predicates = match.groups()
 predicates = predicates.strip()
-
 predicates = _VERSIONS.match(predicates)
 if predicates is not None:
 predicates = predicates.groups()[0]
@@ -359,6 +360,26 @@
 return False
 return True
 
+class Versions(VersionPredicate):
+ def __init__(self, predicate):
+ predicate = predicate.strip()
+ match = _PLAIN_VERSIONS.match(predicate)
+ if match is None:
+ raise ValueError('Bad predicate "%s"' % predicate)
+ self.name = None
+ predicates = match.groups()[0]
+ self.predicates = [_split_predicate(pred.strip())
+ for pred in predicates.split(',')]
+
+class Version(VersionPredicate):
+ def __init__(self, predicate):
+ predicate = predicate.strip()
+ match = _PLAIN_VERSIONS.match(predicate)
+ if match is None:
+ raise ValueError('Bad predicate "%s"' % predicate)
+ self.name = None
+ self.predicates = _split_predicate(match.groups()[0])
+
 def is_valid_predicate(predicate):
 try:
 VersionPredicate(predicate)
@@ -367,3 +388,19 @@
 else:
 return True
 
+def is_valid_versions(predicate):
+ try:
+ Versions(predicate)
+ except (ValueError, IrrationalVersionError):
+ return False
+ else:
+ return True
+
+def is_valid_version(predicate):
+ try:
+ Version(predicate)
+ except (ValueError, IrrationalVersionError):
+ return False
+ else:
+ return True
+
--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list

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