[Python-checkins] distutils2: Branch merge
tarek.ziade
python-checkins at python.org
Sun Jan 23 15:48:24 CET 2011
tarek.ziade pushed 9299dd4ee3fe to distutils2:
http://hg.python.org/distutils2/rev/9299dd4ee3fe
changeset: 892:9299dd4ee3fe
parent: 887:cb2aa326f4c3
parent: 891:d879ec1da01f
user: ?ric Araujo <merwok at netwok.org>
date: Fri Jan 21 21:00:54 2011 +0100
summary:
Branch merge
files:
distutils2/dist.py
distutils2/mkcfg.py
distutils2/run.py
distutils2/tests/test_command_bdist.py
distutils2/tests/test_command_cmd.py
distutils2/tests/test_command_register.py
distutils2/tests/test_config.py
distutils2/tests/test_depgraph.py
distutils2/tests/test_mixin2to3.py
setup.py
diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,17 +6,19 @@
---------
- The setup runner supports more options:
-- XXX fill changes done in commands + compilers
-- Issue 10409: Fixed the Licence selector in mkcfg
+- XXX fill changes done in commands + compilers [tarek]
+- Issue #10409: Fixed the Licence selector in mkcfg [tarek]
+- Issue #9558: Fix build_ext with VS 8.0 [éric]
+- Issue #6007: Add disclaimer about MinGW compatibility in docs [éric]
1.0a3 - 2010-10-08
------------------
-- Provided a Tox configuration for cross-python testing [holger]
+- Provided a Tox configuration for cross-Python testing [holger]
- Fixed the installation when using easy_install and Pip by switching
setup.py to distutils1 [holger/tarek]
- Added missing c/h files in the MANIFEST so they are always present
- no matter which python version was used to build it. [holger/tarek]
+ no matter which Python version was used to build it. [holger/tarek]
- Added the new setup runner that uses only setup.cfg
- Renamed mkpkg to mkcfg [tarek]
- Renamed install_tools to install [alexis]
diff --git a/distutils2/_backport/pkgutil.py b/distutils2/_backport/pkgutil.py
--- a/distutils2/_backport/pkgutil.py
+++ b/distutils2/_backport/pkgutil.py
@@ -343,8 +343,7 @@
from zipimport import zipimporter
def iter_zipimport_modules(importer, prefix=''):
- dirlist = zipimport._zip_directory_cache[importer.archive].keys()
- dirlist.sort()
+ dirlist = sorted(zipimport._zip_directory_cache[importer.archive])
_prefix = importer.prefix
plen = len(_prefix)
yielded = {}
@@ -680,7 +679,6 @@
dir.endswith('.egg')):
yield EggInfoDistribution(dist_path)
-
def _generate_cache(use_egg_info=False):
global _cache_generated, _cache_generated_egg
@@ -738,6 +736,9 @@
if _cache_enabled and not path in _cache_path:
_cache_path[path] = self
+ def __repr__(self):
+ return '%s-%s at %s' % (self.name, self.metadata.version, self.path)
+
def _get_records(self, local=False):
RECORD = os.path.join(self.path, 'RECORD')
record_reader = csv_reader(open(RECORD, 'rb'), delimiter=',')
@@ -856,9 +857,9 @@
r'(?P<rest>(?:\s*,\s*(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)*)\s*' \
r'(?P<extras>\[.*\])?')
- def __init__(self, path):
+ def __init__(self, path, display_warnings=False):
self.path = path
-
+ self.display_warnings = display_warnings
if _cache_enabled and path in _cache_path_egg:
self.metadata = _cache_path_egg[path].metadata
self.name = self.metadata['Name']
@@ -910,25 +911,35 @@
else:
raise ValueError('The path must end with .egg-info or .egg')
- provides = "%s (%s)" % (self.metadata['name'],
- self.metadata['version'])
- if self.metadata['Metadata-Version'] == '1.2':
+
+ if requires is not None:
+ if self.metadata['Metadata-Version'] == '1.1':
+ # we can't have 1.1 metadata *and* Setuptools requires
+ for field in ('Obsoletes', 'Requires', 'Provides'):
+ del self.metadata[field]
+
+ provides = "%s (%s)" % (self.metadata['name'],
+ self.metadata['version'])
self.metadata['Provides-Dist'] += (provides,)
- else:
- self.metadata['Provides'] += (provides,)
+
reqs = []
+
if requires is not None:
for line in yield_lines(requires):
- if line[0] == '[':
+ if line[0] == '[' and self.display_warnings:
warnings.warn('distutils2 does not support extensions '
'in requires.txt')
break
else:
match = self._REQUIREMENT.match(line.strip())
if not match:
- raise ValueError('Distribution %s has ill formed '
- 'requires.txt file (%s)' %
- (self.name, line))
+ # this happens when we encounter extras
+ # since they are written at the end of the file
+ # we just exit
+ break
+ #raise ValueError('Distribution %s has ill formed '
+ # 'requires.txt file (%s)' %
+ # (self.name, line))
else:
if match.group('extras'):
s = (('Distribution %s uses extra requirements '
@@ -946,14 +957,17 @@
reqs.append(name)
else:
reqs.append('%s (%s)' % (name, version))
- if self.metadata['Metadata-Version'] == '1.2':
+
+ if len(reqs) > 0:
self.metadata['Requires-Dist'] += reqs
- else:
- self.metadata['Requires'] += reqs
+
if _cache_enabled:
_cache_path_egg[self.path] = self
+ def __repr__(self):
+ return '%s-%s at %s' % (self.name, self.metadata.version, self.path)
+
def get_installed_files(self, local=False):
return []
diff --git a/distutils2/_backport/shutil.py b/distutils2/_backport/shutil.py
--- a/distutils2/_backport/shutil.py
+++ b/distutils2/_backport/shutil.py
@@ -349,7 +349,7 @@
compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'}
# flags for compression program, each element of list will be an argument
- if compress is not None and compress not in compress_ext.keys():
+ if compress is not None and compress not in compress_ext:
raise ValueError, \
("bad value for 'compress': must be None, 'gzip', 'bzip2' "
"or 'compress'")
@@ -487,7 +487,7 @@
Each element of the returned sequence is a tuple (name, description)
"""
formats = [(name, registry[2]) for name, registry in
- _ARCHIVE_FORMATS.items()]
+ _ARCHIVE_FORMATS.iteritems()]
formats.sort()
return formats
diff --git a/distutils2/_backport/sysconfig.py b/distutils2/_backport/sysconfig.py
--- a/distutils2/_backport/sysconfig.py
+++ b/distutils2/_backport/sysconfig.py
@@ -102,9 +102,8 @@
def _extend_dict(target_dict, other_dict):
- target_keys = target_dict.keys()
- for key, value in other_dict.items():
- if key in target_keys:
+ for key, value in other_dict.iteritems():
+ if key in target_dict:
continue
target_dict[key] = value
@@ -713,7 +712,7 @@
def _print_dict(title, data):
- for index, (key, value) in enumerate(sorted(data.items())):
+ for index, (key, value) in enumerate(sorted(data.iteritems())):
if index == 0:
print '%s: ' % (title)
print '\t%s = "%s"' % (key, value)
diff --git a/distutils2/_backport/tests/test_pkgutil.py b/distutils2/_backport/tests/test_pkgutil.py
--- a/distutils2/_backport/tests/test_pkgutil.py
+++ b/distutils2/_backport/tests/test_pkgutil.py
@@ -249,7 +249,7 @@
dist = Distribution(distinfo_dir)
for path, md5_, size in dist.get_installed_files():
record_data = self.records[dist.path]
- self.assertTrue(path in record_data.keys())
+ self.assertIn(path, record_data)
self.assertEqual(md5_, record_data[path][0])
self.assertEqual(size, record_data[path][1])
@@ -318,7 +318,7 @@
self.assertEqual(sorted(found), sorted(distinfo_record_paths))
# Test for the iteration of local absolute paths
distinfo_record_paths = [os.path.join(sys.prefix, path)
- for path in self.records[distinfo_dir].keys()]
+ for path in self.records[distinfo_dir]]
found = [path for path in dist.get_distinfo_files(local=True)]
self.assertEqual(sorted(found), sorted(distinfo_record_paths))
@@ -382,7 +382,7 @@
if not isinstance(dist, Distribution):
self.fail("item received was not a Distribution instance: "
"%s" % type(dist))
- if dist.name in dict(fake_dists).keys() and \
+ if dist.name in dict(fake_dists) and \
dist.path.startswith(self.fake_dists_path):
found_dists.append((dist.name, dist.metadata['version'],))
else:
@@ -405,7 +405,7 @@
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() and \
+ if dist.name in dict(fake_dists) and \
dist.path.startswith(self.fake_dists_path):
found_dists.append((dist.name, dist.metadata['version']))
else:
diff --git a/distutils2/command/__init__.py b/distutils2/command/__init__.py
--- a/distutils2/command/__init__.py
+++ b/distutils2/command/__init__.py
@@ -31,8 +31,8 @@
def get_command_names():
- return sorted(_COMMANDS.keys())
"""Return registered commands"""
+ return sorted(_COMMANDS)
def set_command(location):
diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py
--- a/distutils2/command/build_ext.py
+++ b/distutils2/command/build_ext.py
@@ -257,7 +257,7 @@
elif MSVC_VERSION == 8:
self.library_dirs.append(os.path.join(sys.exec_prefix,
- 'PC', 'VS8.0', 'win32release'))
+ 'PC', 'VS8.0'))
elif MSVC_VERSION == 7:
self.library_dirs.append(os.path.join(sys.exec_prefix,
'PC', 'VS7.1'))
diff --git a/distutils2/command/build_py.py b/distutils2/command/build_py.py
--- a/distutils2/command/build_py.py
+++ b/distutils2/command/build_py.py
@@ -68,7 +68,7 @@
self.package_data = self.distribution.package_data
self.package_dir = {}
if self.distribution.package_dir:
- for name, path in self.distribution.package_dir.items():
+ for name, path in self.distribution.package_dir.iteritems():
self.package_dir[name] = convert_path(path)
self.data_files = self.get_data_files()
diff --git a/distutils2/command/check.py b/distutils2/command/check.py
--- a/distutils2/command/check.py
+++ b/distutils2/command/check.py
@@ -76,11 +76,11 @@
raise DistutilsSetupError('The docutils package is needed.')
def check_hooks_resolvable(self):
- for options in self.distribution.command_options.values():
+ for options in self.distribution.command_options.itervalues():
for hook_kind in ("pre_hook", "post_hook"):
if hook_kind not in options:
break
- for hook_name in options[hook_kind][1].values():
+ for hook_name in options[hook_kind][1].itervalues():
try:
resolve_name(hook_name)
except ImportError:
diff --git a/distutils2/command/install_dist.py b/distutils2/command/install_dist.py
--- a/distutils2/command/install_dist.py
+++ b/distutils2/command/install_dist.py
@@ -424,7 +424,7 @@
"""Set the install directories by applying the install schemes."""
# it's the caller's problem if they supply a bad name!
scheme = get_paths(name, expand=False)
- for key, value in scheme.items():
+ for key, value in scheme.iteritems():
if key == 'platinclude':
key = 'headers'
value = os.path.join(value, self.distribution.metadata['Name'])
diff --git a/distutils2/command/register.py b/distutils2/command/register.py
--- a/distutils2/command/register.py
+++ b/distutils2/command/register.py
@@ -11,7 +11,6 @@
import urlparse
import StringIO
import logging
-from warnings import warn
from distutils2.command.cmd import Command
from distutils2 import logger
@@ -33,25 +32,19 @@
"stop the registration if the metadata is not fully compliant")
]
- boolean_options = ['show-response', 'verify', 'list-classifiers',
- 'strict']
+ boolean_options = ['show-response', 'list-classifiers', 'strict']
def initialize_options(self):
self.repository = None
self.realm = None
self.show_response = 0
self.list_classifiers = 0
- self.strict = 0
def finalize_options(self):
if self.repository is None:
self.repository = DEFAULT_REPOSITORY
if self.realm is None:
self.realm = DEFAULT_REALM
- # setting options for the `check` subcommand
- check_options = {'strict': ('register', self.strict),
- 'all': ('register', 1)}
- self.distribution.command_options['check'] = check_options
def run(self):
self.finalize_options()
@@ -67,16 +60,6 @@
else:
self.send_metadata()
- def check_metadata(self):
- """Deprecated API."""
- warn("distutils.command.register.check_metadata is deprecated, \
- use the check command instead", PendingDeprecationWarning)
- check = self.distribution.get_command_obj('check')
- check.ensure_finalized()
- check.strict = self.strict
- check.all = 1
- check.run()
-
def _set_config(self):
''' Reads the configuration file and set attributes.
'''
@@ -252,7 +235,7 @@
sep_boundary = '\n--' + boundary
end_boundary = sep_boundary + '--'
body = StringIO.StringIO()
- for key, value in data.items():
+ for key, value in data.iteritems():
# handle multiple entries for the same name
if not isinstance(value, (tuple, list)):
value = [value]
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -371,8 +371,7 @@
need_dir = {}
for file in files:
need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1
- need_dirs = need_dir.keys()
- need_dirs.sort()
+ need_dirs = sorted(need_dir)
# Now create them
for dir in need_dirs:
diff --git a/distutils2/command/upload.py b/distutils2/command/upload.py
--- a/distutils2/command/upload.py
+++ b/distutils2/command/upload.py
@@ -140,7 +140,7 @@
body = StringIO()
file_fields = ('content', 'gpg_signature')
- for key, values in data.items():
+ for key, values in data.iteritems():
# handle multiple entries for the same name
if not isinstance(values, (tuple, list)):
values = [values]
diff --git a/distutils2/compiler/__init__.py b/distutils2/compiler/__init__.py
--- a/distutils2/compiler/__init__.py
+++ b/distutils2/compiler/__init__.py
@@ -127,7 +127,7 @@
from distutils2.fancy_getopt import FancyGetopt
compilers = []
- for name, cls in _COMPILERS.items():
+ for name, cls in _COMPILERS.iteritems():
if isinstance(cls, str):
cls = resolve_name(cls)
_COMPILERS[name] = cls
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -116,8 +116,8 @@
# named library files) to include on any link
self.objects = []
- for key in self.executables.keys():
- self.set_executable(key, self.executables[key])
+ for key, value in self.executables.iteritems():
+ self.set_executable(key, value)
def set_executables(self, **args):
"""Define the executables (and options for them) that will be run
@@ -145,12 +145,12 @@
# discovered at run-time, since there are many different ways to do
# basically the same things with Unix C compilers.
- for key in args.keys():
+ for key, value in args.iteritems():
if key not in self.executables:
raise ValueError, \
"unknown executable '%s' for class %s" % \
(key, self.__class__.__name__)
- self.set_executable(key, args[key])
+ self.set_executable(key, value)
def set_executable(self, key, value):
if isinstance(value, str):
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -358,27 +358,3 @@
except IOError, exc:
return (CONFIG_H_UNCERTAIN,
"couldn't read '%s': %s" % (fn, exc.strerror))
-
-class _Deprecated_SRE_Pattern(object):
- def __init__(self, pattern):
- self.pattern = pattern
-
- def __getattr__(self, name):
- if name in ('findall', 'finditer', 'match', 'scanner', 'search',
- 'split', 'sub', 'subn'):
- warn("'distutils.cygwinccompiler.RE_VERSION' is deprecated "
- "and will be removed in the next version", DeprecationWarning)
- return getattr(self.pattern, name)
-
-RE_VERSION = _Deprecated_SRE_Pattern(re.compile('(\d+\.\d+(\.\d+)*)'))
-
-def get_versions():
- """ Try to find out the versions of gcc, ld and dllwrap.
-
- If not possible it returns None for it.
- """
- warn("'distutils.cygwinccompiler.get_versions' is deprecated "
- "use 'distutils.util.get_compiler_versions' instead",
- DeprecationWarning)
-
- return get_compiler_versions()
diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py
--- a/distutils2/compiler/msvc9compiler.py
+++ b/distutils2/compiler/msvc9compiler.py
@@ -153,7 +153,7 @@
self.macros["$(FrameworkVersion)"] = d["version"]
def sub(self, s):
- for k, v in self.macros.items():
+ for k, v in self.macros.iteritems():
s = s.replace(k, v)
return s
@@ -271,7 +271,7 @@
result[key] = removeDuplicates(value)
if len(result) != len(interesting):
- raise ValueError(str(list(result.keys())))
+ raise ValueError(str(list(result)))
return result
diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py
--- a/distutils2/compiler/msvccompiler.py
+++ b/distutils2/compiler/msvccompiler.py
@@ -146,7 +146,7 @@
self.macros["$(FrameworkVersion)"] = d["version"]
def sub(self, s):
- for k, v in self.macros.items():
+ for k, v in self.macros.iteritems():
s = string.replace(s, k, v)
return s
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -98,7 +98,7 @@
# setting the metadata values
if 'metadata' in content:
- for key, value in content['metadata'].items():
+ for key, value in content['metadata'].iteritems():
key = key.replace('_', '-')
value = self._multiline(value)
if key == 'project-url':
@@ -124,7 +124,7 @@
if 'files' in content:
files = dict([(key, self._multiline(value))
- for key, value in content['files'].items()])
+ for key, value in content['files'].iteritems()])
self.dist.packages = []
self.dist.package_dir = {}
@@ -223,7 +223,7 @@
# If there was a "global" section in the config file, use it
# to set Distribution options.
if 'global' in self.dist.command_options:
- for (opt, (src, val)) in self.dist.command_options['global'].items():
+ for (opt, (src, val)) in self.dist.command_options['global'].iteritems():
alias = self.dist.negative_opt.get(opt)
try:
if alias:
diff --git a/distutils2/depgraph.py b/distutils2/depgraph.py
--- a/distutils2/depgraph.py
+++ b/distutils2/depgraph.py
@@ -66,18 +66,28 @@
"""
self.missing[distribution].append(requirement)
+ def _repr_dist(self, dist):
+ return '%s %s' % (dist.name, dist.metadata['Version'])
+
+ def repr_node(self, dist, level=1):
+ """Prints only a subgraph"""
+ output = []
+ output.append(self._repr_dist(dist))
+ for other, label in self.adjacency_list[dist]:
+ dist = self._repr_dist(other)
+ if label is not None:
+ dist = '%s [%s]' % (dist, label)
+ output.append(' ' * level + '%s' % dist)
+ suboutput = self.repr_node(other, level+1)
+ subs = suboutput.split('\n')
+ output.extend(subs[1:])
+ return '\n'.join(output)
+
def __repr__(self):
"""Representation of the graph"""
- def _repr_dist(dist):
- return '%s %s' % (dist.name, dist.metadata['Version'])
output = []
for dist, adjs in self.adjacency_list.iteritems():
- output.append(_repr_dist(dist))
- for other, label in adjs:
- dist = _repr_dist(other)
- if label is not None:
- dist = '%s [%s]' % (dist, label)
- output.append(' %s' % dist)
+ output.append(self.repr_node(dist))
return '\n'.join(output)
@@ -129,7 +139,9 @@
# first, build the graph and find out the provides
for dist in dists:
graph.add_distribution(dist)
- provides = dist.metadata['Provides-Dist'] + dist.metadata['Provides']
+ provides = (dist.metadata['Provides-Dist'] + dist.metadata['Provides'] +
+ ['%s (%s)' % (dist.name, dist.metadata['Version'])])
+
for p in provides:
comps = p.strip().rsplit(" ", 1)
@@ -149,7 +161,13 @@
for dist in dists:
requires = dist.metadata['Requires-Dist'] + dist.metadata['Requires']
for req in requires:
- predicate = VersionPredicate(req)
+ try:
+ predicate = VersionPredicate(req)
+ except IrrationalVersionError:
+ # XXX compat-mode if cannot read the version
+ name = req.split()[0]
+ predicate = VersionPredicate(name)
+
name = predicate.name
if not name in provided:
@@ -172,7 +190,6 @@
break
if not matched:
graph.add_missing(dist, req)
-
return graph
diff --git a/distutils2/dist.py b/distutils2/dist.py
--- a/distutils2/dist.py
+++ b/distutils2/dist.py
@@ -227,14 +227,14 @@
options = attrs.get('options')
if options is not None:
del attrs['options']
- for (command, cmd_options) in options.items():
+ for (command, cmd_options) in options.iteritems():
opt_dict = self.get_option_dict(command)
- for (opt, val) in cmd_options.items():
+ for (opt, val) in cmd_options.iteritems():
opt_dict[opt] = ("setup script", val)
# Now work on the rest of the attributes. Any attribute that's
# not already defined is invalid!
- for key, val in attrs.items():
+ for key, val in attrs.iteritems():
if self.metadata.is_metadata_field(key):
self.metadata[key] = val
elif hasattr(self, key):
@@ -279,8 +279,7 @@
from pprint import pformat
if commands is None: # dump all command option dicts
- commands = self.command_options.keys()
- commands.sort()
+ commands = sorted(self.command_options)
if header is not None:
self.announce(indent + header)
@@ -477,7 +476,7 @@
# Put the options from the command line into their official
# holding pen, the 'command_options' dictionary.
opt_dict = self.get_option_dict(command)
- for (name, value) in vars(opts).items():
+ for (name, value) in vars(opts).iteritems():
opt_dict[name] = ("command line", value)
return args
@@ -679,7 +678,7 @@
logger.debug(" setting options for '%s' command:" % command_name)
- for (option, (source, value)) in option_dict.items():
+ for (option, (source, value)) in option_dict.iteritems():
logger.debug(" %s = %s (from %s)" % (option, value, source))
try:
bool_opts = [x.replace('-', '_')
diff --git a/distutils2/fancy_getopt.py b/distutils2/fancy_getopt.py
--- a/distutils2/fancy_getopt.py
+++ b/distutils2/fancy_getopt.py
@@ -107,7 +107,7 @@
def _check_alias_dict (self, aliases, what):
assert isinstance(aliases, dict)
- for (alias, opt) in aliases.items():
+ for (alias, opt) in aliases.iteritems():
if alias not in self.option_index:
raise DistutilsGetoptError, \
("invalid %s '%s': "
diff --git a/distutils2/index/dist.py b/distutils2/index/dist.py
--- a/distutils2/index/dist.py
+++ b/distutils2/index/dist.py
@@ -101,7 +101,7 @@
def is_final(self):
"""proxy to version.is_final"""
return self.version.is_final
-
+
def fetch_distributions(self):
if self.dists is None:
self._index.get_distributions(self.name, '%s' % self.version)
@@ -127,7 +127,7 @@
self.dists[dist_type] = DistInfo(self, dist_type,
index=self._index, **params)
if python_version:
- self.dists[dist_type].python_version = python_version
+ self.dists[dist_type].python_version = python_version
def get_distribution(self, dist_type=None, prefer_source=True):
"""Return a distribution.
@@ -302,7 +302,7 @@
def unpack(self, path=None):
"""Unpack the distribution to the given path.
-
+
If not destination is given, creates a temporary location.
Returns the location of the extracted files (root).
@@ -310,10 +310,10 @@
if not self._unpacked_dir:
if path is None:
path = tempfile.mkdtemp()
-
+
filename = self.download()
content_type = mimetypes.guess_type(filename)[0]
-
+
if (content_type == 'application/zip'
or filename.endswith('.zip')
or filename.endswith('.pybundle')
@@ -351,7 +351,7 @@
"""
def __init__(self, name, releases=None, contains_hidden=False, index=None):
self.set_index(index)
- self.releases = []
+ self.releases = []
self.name = name
self.contains_hidden = contains_hidden
if releases:
@@ -376,6 +376,8 @@
"""
predicate = get_version_predicate(requirements)
releases = self.filter(predicate)
+ if len(releases) == 0:
+ return None
releases.sort_releases(prefer_final, reverse=True)
return releases[0]
@@ -404,11 +406,11 @@
raise ValueError("%s is not the same project than %s" %
(release.name, self.name))
version = '%s' % release.version
-
+
if not version in self.get_versions():
# append only if not already exists
self.releases.append(release)
- for dist in release.dists.values():
+ for dist in release.dists.itervalues():
for url in dist.urls:
self.add_release(version, dist.dist_type, **url)
else:
@@ -445,8 +447,7 @@
reverse=reverse, *args, **kwargs)
def get_release(self, version):
- """Return a release from it's version.
- """
+ """Return a release from its version."""
matches = [r for r in self.releases if "%s" % r.version == version]
if len(matches) != 1:
raise KeyError(version)
diff --git a/distutils2/index/simple.py b/distutils2/index/simple.py
--- a/distutils2/index/simple.py
+++ b/distutils2/index/simple.py
@@ -1,7 +1,7 @@
"""index.simple
Contains the class "SimpleIndexCrawler", a simple spider to find and retrieve
-distributions on the Python Package Index, using it's "simple" API,
+distributions on the Python Package Index, using its "simple" API,
avalaible at http://pypi.python.org/simple/
"""
from fnmatch import translate
@@ -14,6 +14,7 @@
import logging
import os
+from distutils2 import logger
from distutils2.index.base import BaseClient
from distutils2.index.dist import (ReleasesList, EXTENSIONS,
get_infos_from_url, MD5_HASH)
@@ -167,6 +168,7 @@
if predicate.name.lower() in self._projects and not force_update:
return self._projects.get(predicate.name.lower())
prefer_final = self._get_prefer_final(prefer_final)
+ logger.info('Reading info on PyPI about %s' % predicate.name)
self._process_index_page(predicate.name)
if predicate.name.lower() not in self._projects:
diff --git a/distutils2/index/wrapper.py b/distutils2/index/wrapper.py
--- a/distutils2/index/wrapper.py
+++ b/distutils2/index/wrapper.py
@@ -1,5 +1,4 @@
-import xmlrpc
-import simple
+from distutils2.index import simple, xmlrpc
_WRAPPER_MAPPINGS = {'get_release': 'simple',
'get_releases': 'simple',
@@ -58,7 +57,7 @@
# instantiate the classes and set their _project attribute to the one
# of the wrapper.
- for name, cls in index_classes.items():
+ for name, cls in index_classes.iteritems():
obj = self._indexes.setdefault(name, cls())
obj._projects = self._projects
obj._index = self
diff --git a/distutils2/index/xmlrpc.py b/distutils2/index/xmlrpc.py
--- a/distutils2/index/xmlrpc.py
+++ b/distutils2/index/xmlrpc.py
@@ -159,8 +159,15 @@
index=self._index))
except IrrationalVersionError, e:
logging.warn("Irrational version error found: %s" % e)
+ return [self._projects[p['name'].lower()] for p in projects]
- return [self._projects[p['name'].lower()] for p in projects]
+ def get_all_projects(self):
+ """Return the list of all projects registered in the package index"""
+ projects = self.proxy.list_packages()
+ for name in projects:
+ self.get_releases(name, show_hidden=True)
+
+ return [self._projects[name.lower()] for name in set(projects)]
@property
def proxy(self):
diff --git a/distutils2/install.py b/distutils2/install.py
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -123,13 +123,13 @@
try:
if install:
installed_files = install_dists(install, install_path) # install to tmp first
- for files in temp_files.values():
+ for files in temp_files.itervalues():
for old, new in files:
os.remove(new)
except Exception,e:
# if an error occurs, put back the files in the good place.
- for files in temp_files.values():
+ for files in temp_files.itervalues():
for old, new in files:
shutil.move(new, old)
@@ -183,7 +183,7 @@
infos = {'install': [], 'remove': [], 'conflict': []}
# Get what the missing deps are
- for dists in depgraph.missing.values():
+ for dists in depgraph.missing.itervalues():
if dists:
logging.info("missing dependencies found, installing them")
# we have missing deps
@@ -203,7 +203,7 @@
"""extends the lists contained in the `info` dict with those contained
in the `new_info` one
"""
- for key, value in infos.items():
+ for key, value in infos.iteritems():
if key in new_infos:
infos[key].extend(new_infos[key])
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -195,8 +195,10 @@
# also document the mapping API and UNKNOWN default key
def __init__(self, path=None, platform_dependent=False,
- execution_context=None, fileobj=None, mapping=None):
+ execution_context=None, fileobj=None, mapping=None,
+ display_warnings=False):
self._fields = {}
+ self.display_warnings = display_warnings
self.version = None
self.docutils_support = _HAS_DOCUTILS
self.platform_dependent = platform_dependent
@@ -387,21 +389,22 @@
else:
value = []
- 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]):
- logger.warn('"%s" is not a valid predicate (field "%s")' %
- (v, name))
- # FIXME this rejects UNKNOWN, is that right?
- elif name in _VERSIONS_FIELDS and value is not None:
- if not is_valid_versions(value):
- logger.warn('"%s" is not a valid version (field "%s")' %
- (value, name))
- elif name in _VERSION_FIELDS and value is not None:
- if not is_valid_version(value):
- logger.warn('"%s" is not a valid version (field "%s")' %
- (value, name))
+ if self.display_warnings:
+ 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]):
+ logger.warn('"%s" is not a valid predicate (field "%s")' %
+ (v, name))
+ # FIXME this rejects UNKNOWN, is that right?
+ elif name in _VERSIONS_FIELDS and value is not None:
+ if not is_valid_versions(value):
+ logger.warn('"%s" is not a valid version (field "%s")' %
+ (value, name))
+ elif name in _VERSION_FIELDS and value is not None:
+ if not is_valid_version(value):
+ logger.warn('"%s" is not a valid version (field "%s")' %
+ (value, name))
if name in _UNICODEFIELDS:
value = self._encode_field(value)
diff --git a/distutils2/mkcfg.py b/distutils2/mkcfg.py
--- a/distutils2/mkcfg.py
+++ b/distutils2/mkcfg.py
@@ -367,7 +367,7 @@
if not trove:
return
- for key in sorted(trove.keys()):
+ for key in sorted(trove):
if len(trove[key]) == 0:
if ask_yn('Add "%s"' % desc[4:] + ' :: ' + key, 'n') == 'y':
classifiers[desc[4:] + ' :: ' + key] = 1
@@ -455,7 +455,7 @@
"number.")
def _dotted_packages(self, data):
- packages = sorted(data.keys())
+ packages = sorted(data)
modified_pkgs = []
for pkg in packages:
pkg = pkg.lstrip('./')
diff --git a/distutils2/run.py b/distutils2/run.py
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -7,6 +7,8 @@
DistutilsError, CCompilerError)
from distutils2.dist import Distribution
from distutils2 import __version__
+from distutils2._backport.pkgutil import get_distributions, get_distribution
+from distutils2.depgraph import generate_graph
# This is a barebones help message generated displayed when the user
# runs the setup script with no arguments at all. More useful help
@@ -116,20 +118,64 @@
"""Main entry point for Distutils2"""
parser = OptionParser()
parser.disable_interspersed_args()
+ parser.usage = '%prog [options] cmd1 cmd2 ..'
+
parser.add_option("-v", "--version",
action="store_true", dest="version", default=False,
help="Prints out the version of Distutils2 and exits.")
+ parser.add_option("-s", "--search",
+ action="store", dest="search", default=None,
+ help="Search for installed distributions.")
+
+ parser.add_option("-g", "--graph",
+ action="store", dest="graph", default=None,
+ help="Display the graph for a given installed distribution.")
+
+ parser.add_option("-f", "--full-graph",
+ action="store_true", dest="fgraph", default=False,
+ help="Display the full graph for installed distributions.")
+
options, args = parser.parse_args()
if options.version:
print('Distutils2 %s' % __version__)
# sys.exit(0)
+ if options.search is not None:
+ search = options.search.lower()
+ for dist in get_distributions(use_egg_info=True):
+ name = dist.name.lower()
+ if search in name:
+ print('%s %s at %s' % (dist.name, dist.metadata['version'],
+ dist.path))
+
+ sys.exit(0)
+
+ if options.graph is not None:
+ name = options.graph
+ dist = get_distribution(name, use_egg_info=True)
+ if dist is None:
+ print('Distribution not found.')
+ else:
+ dists = get_distributions(use_egg_info=True)
+ graph = generate_graph(dists)
+ print(graph.repr_node(dist))
+
+ sys.exit(0)
+
+ if options.fgraph:
+ dists = get_distributions(use_egg_info=True)
+ graph = generate_graph(dists)
+ print(graph)
+ sys.exit(0)
+
if len(args) == 0:
parser.print_help()
+ sys.exit(0)
return commands_main()
# sys.exit(0)
+
if __name__ == '__main__':
main()
diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py
--- a/distutils2/tests/pypi_server.py
+++ b/distutils2/tests/pypi_server.py
@@ -400,7 +400,7 @@
self._dists.append(dist)
return [r.search_result() for r in results]
- def list_package(self):
+ def list_packages(self):
return [d.name for d in self._dists]
def package_releases(self, package_name, show_hidden=False):
diff --git a/distutils2/tests/test_command_bdist.py b/distutils2/tests/test_command_bdist.py
--- a/distutils2/tests/test_command_bdist.py
+++ b/distutils2/tests/test_command_bdist.py
@@ -40,10 +40,9 @@
# XXX an explicit list in bdist is
# not the best way to bdist_* commands
# we should add a registry
- formats = ['zip', 'gztar', 'bztar', 'ztar', 'tar', 'wininst', 'msi']
- formats.sort()
- found = cmd.format_command.keys()
- found.sort()
+ formats = sorted(('zip', 'gztar', 'bztar', 'ztar',
+ 'tar', 'wininst', 'msi'))
+ found = sorted(cmd.format_command)
self.assertEqual(found, formats)
def test_skip_build(self):
diff --git a/distutils2/tests/test_command_cmd.py b/distutils2/tests/test_command_cmd.py
--- a/distutils2/tests/test_command_cmd.py
+++ b/distutils2/tests/test_command_cmd.py
@@ -66,12 +66,20 @@
cmd.ensure_string_list('option1')
self.assertEqual(cmd.option1, ['ok', 'dok'])
- cmd.option2 = ['xxx', 'www']
- cmd.ensure_string_list('option2')
+ cmd.yes_string_list = ['one', 'two', 'three']
+ cmd.yes_string_list2 = 'ok'
+ cmd.ensure_string_list('yes_string_list')
+ cmd.ensure_string_list('yes_string_list2')
+ self.assertEqual(cmd.yes_string_list, ['one', 'two', 'three'])
+ self.assertEqual(cmd.yes_string_list2, ['ok'])
- cmd.option3 = ['ok', 2]
- self.assertRaises(DistutilsOptionError, cmd.ensure_string_list,
- 'option3')
+ cmd.not_string_list = ['one', 2, 'three']
+ cmd.not_string_list2 = object()
+ self.assertRaises(DistutilsOptionError,
+ cmd.ensure_string_list, 'not_string_list')
+
+ self.assertRaises(DistutilsOptionError,
+ cmd.ensure_string_list, 'not_string_list2')
def test_ensure_filename(self):
cmd = self.cmd
diff --git a/distutils2/tests/test_command_register.py b/distutils2/tests/test_command_register.py
--- a/distutils2/tests/test_command_register.py
+++ b/distutils2/tests/test_command_register.py
@@ -86,6 +86,8 @@
def tearDown(self):
getpass.getpass = self._old_getpass
urllib2.build_opener = self.old_opener
+ if hasattr(register_module, 'raw_input'):
+ del register_module.raw_input
super(RegisterTestCase, self).tearDown()
def _get_cmd(self, metadata=None):
@@ -108,7 +110,6 @@
# patching raw_input and getpass.getpass
# so register gets happy
- #
# Here's what we are faking :
# use your existing login (choice 1.)
# Username : 'tarek'
@@ -116,11 +117,7 @@
# Save your login (y/N)? : 'y'
inputs = RawInputs('1', 'tarek', 'y')
register_module.raw_input = inputs.__call__
- # let's run the command
- try:
- cmd.run()
- finally:
- del register_module.raw_input
+ cmd.run()
# we should have a brand new .pypirc file
self.assertTrue(os.path.exists(self.rc))
@@ -134,8 +131,8 @@
# if we run the command again
def _no_way(prompt=''):
raise AssertionError(prompt)
+
register_module.raw_input = _no_way
-
cmd.show_response = 1
cmd.run()
@@ -164,13 +161,10 @@
cmd = self._get_cmd()
inputs = RawInputs('2', 'tarek', 'tarek at ziade.org')
register_module.raw_input = inputs.__call__
- try:
- # let's run the command
- # FIXME does this send a real request? use a mock server
- # also, silence self.announce (with LoggingCatcher)
- cmd.run()
- finally:
- del register_module.raw_input
+ # let's run the command
+ # FIXME does this send a real request? use a mock server
+ # also, silence self.announce (with LoggingCatcher)
+ cmd.run()
# we should have send a request
self.assertTrue(self.conn.reqs, 1)
@@ -184,11 +178,7 @@
cmd = self._get_cmd()
inputs = RawInputs('3', 'tarek at ziade.org')
register_module.raw_input = inputs.__call__
- try:
- # let's run the command
- cmd.run()
- finally:
- del register_module.raw_input
+ cmd.run()
# we should have send a request
self.assertTrue(self.conn.reqs, 1)
@@ -208,6 +198,8 @@
cmd = self._get_cmd({})
cmd.ensure_finalized()
cmd.strict = 1
+ inputs = RawInputs('1', 'tarek', 'y')
+ register_module.raw_input = inputs.__call__
self.assertRaises(DistutilsSetupError, cmd.run)
# metadata is OK but long_description is broken
@@ -229,22 +221,14 @@
cmd.strict = 1
inputs = RawInputs('1', 'tarek', 'y')
register_module.raw_input = inputs.__call__
- # let's run the command
- try:
- cmd.run()
- finally:
- del register_module.raw_input
+ cmd.run()
# strict is not by default
cmd = self._get_cmd()
cmd.ensure_finalized()
inputs = RawInputs('1', 'tarek', 'y')
register_module.raw_input = inputs.__call__
- # let's run the command
- try:
- cmd.run()
- finally:
- del register_module.raw_input
+ cmd.run()
def test_register_pep345(self):
cmd = self._get_cmd({})
diff --git a/distutils2/tests/test_command_sdist.py b/distutils2/tests/test_command_sdist.py
--- a/distutils2/tests/test_command_sdist.py
+++ b/distutils2/tests/test_command_sdist.py
@@ -363,7 +363,7 @@
finally:
f.close()
- self.assertEquals(len(manifest), 4)
+ self.assertEqual(len(manifest), 4)
# adding a file
self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
@@ -383,7 +383,7 @@
f.close()
# do we have the new file in MANIFEST ?
- self.assertEquals(len(manifest2), 5)
+ self.assertEqual(len(manifest2), 5)
self.assertIn('doc2.txt', manifest2[-1])
def test_manifest_marker(self):
diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py
--- a/distutils2/tests/test_config.py
+++ b/distutils2/tests/test_config.py
@@ -204,7 +204,7 @@
'FooBarBazTest')
# did the README got loaded ?
- self.assertEquals(dist.metadata['description'], 'yeah')
+ self.assertEqual(dist.metadata['description'], 'yeah')
# do we have the D Compiler enabled ?
from distutils2.compiler import new_compiler, _COMPILERS
@@ -238,7 +238,7 @@
finally:
sys.argv[:] = old_sys
- self.assertEquals(dist.foo_was_here, 1)
+ self.assertEqual(dist.foo_was_here, 1)
def test_suite():
diff --git a/distutils2/tests/test_cygwinccompiler.py b/distutils2/tests/test_cygwinccompiler.py
--- a/distutils2/tests/test_cygwinccompiler.py
+++ b/distutils2/tests/test_cygwinccompiler.py
@@ -8,10 +8,9 @@
from distutils2.tests import captured_stdout
from distutils2.compiler import cygwinccompiler
-from distutils2.compiler.cygwinccompiler import (CygwinCCompiler, check_config_h,
- CONFIG_H_OK, CONFIG_H_NOTOK,
- CONFIG_H_UNCERTAIN, get_versions,
- get_msvcr, RE_VERSION)
+from distutils2.compiler.cygwinccompiler import (
+ CygwinCCompiler, check_config_h, get_msvcr,
+ CONFIG_H_OK, CONFIG_H_NOTOK, CONFIG_H_UNCERTAIN)
from distutils2.util import get_compiler_versions
from distutils2.tests import unittest, support
diff --git a/distutils2/tests/test_index_dist.py b/distutils2/tests/test_index_dist.py
--- a/distutils2/tests/test_index_dist.py
+++ b/distutils2/tests/test_index_dist.py
@@ -237,6 +237,10 @@
# dists.sort_distributions(prefer_source=True)
# self.assertEqual(fb2_binary, dists[0])
+ def test_get_last(self):
+ dists = ReleasesList('Foo')
+ self.assertEqual(dists.get_last('Foo 1.0'), None)
+
def test_suite():
suite = unittest.TestSuite()
diff --git a/distutils2/tests/test_index_simple.py b/distutils2/tests/test_index_simple.py
--- a/distutils2/tests/test_index_simple.py
+++ b/distutils2/tests/test_index_simple.py
@@ -293,8 +293,8 @@
<a href="../download" rel="download">link2</a>
<a href="../simpleurl">link2</a>
"""
- found_links = dict(crawler._default_link_matcher(content,
- base_url)).keys()
+ found_links = set(dict(crawler._default_link_matcher(content,
+ base_url)))
self.assertIn('http://example.org/some/homepage', found_links)
self.assertIn('http://example.org/some/simpleurl', found_links)
self.assertIn('http://example.org/some/download', found_links)
diff --git a/distutils2/tests/test_index_xmlrpc.py b/distutils2/tests/test_index_xmlrpc.py
--- a/distutils2/tests/test_index_xmlrpc.py
+++ b/distutils2/tests/test_index_xmlrpc.py
@@ -25,6 +25,24 @@
invalid="test")
@use_xmlrpc_server()
+ def test_get_all_projects(self, server):
+ client = self._get_client(server)
+ server.xmlrpc.set_distributions([
+ {'name': 'FooBar', 'version': '1.1'},
+ {'name': 'FooBar', 'version': '1.2'},
+ {'name': 'Foo', 'version': '1.1'},
+ ])
+ results = client.get_all_projects()
+ self.assertEqual(2, len(results))
+
+ # check we do have two releases for Foobar's project
+ self.assertEqual(2, len(results[0].releases))
+
+ names = [r.name for r in results]
+ self.assertIn('FooBar', names)
+ self.assertIn('Foo', names)
+
+ @use_xmlrpc_server()
def test_get_releases(self, server):
client = self._get_client(server)
server.xmlrpc.set_distributions([
diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py
--- a/distutils2/tests/test_install.py
+++ b/distutils2/tests/test_install.py
@@ -214,7 +214,7 @@
for dict1, dict2, expect in tests:
install._update_infos(dict1, dict2)
- for key in expect.keys():
+ for key in expect:
self.assertEqual(expect[key], dict1[key])
def test_install_dists_rollback(self):
@@ -284,7 +284,7 @@
install.install_from_infos(install=to_install,
install_path=install_path)
for dist in to_install:
- self.assertEquals(dist.install_called_with, (install_path,))
+ self.assertEqual(dist.install_called_with, (install_path,))
def test_suite():
suite = unittest.TestSuite()
diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py
--- a/distutils2/tests/test_metadata.py
+++ b/distutils2/tests/test_metadata.py
@@ -117,7 +117,7 @@
metadata['Name'] = "baz; sys.platform == 'blah'"
# FIXME is None or 'UNKNOWN' correct here?
# where is that documented?
- self.assertEquals(metadata['Name'], None)
+ self.assertEqual(metadata['Name'], None)
# test with context
context = {'sys.platform': 'okook'}
diff --git a/distutils2/tests/test_mixin2to3.py b/distutils2/tests/test_mixin2to3.py
--- a/distutils2/tests/test_mixin2to3.py
+++ b/distutils2/tests/test_mixin2to3.py
@@ -25,7 +25,7 @@
converted_code_content = "print('test')\n"
new_code_content = "".join(open(code_name).readlines())
- self.assertEquals(new_code_content, converted_code_content)
+ self.assertEqual(new_code_content, converted_code_content)
@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_doctests_only(self):
@@ -45,7 +45,7 @@
converted_doctest_content = '\n'.join(converted_doctest_content)
new_doctest_content = "".join(open(doctest_name).readlines())
- self.assertEquals(new_doctest_content, converted_doctest_content)
+ self.assertEqual(new_doctest_content, converted_doctest_content)
@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_additional_fixers(self):
@@ -64,7 +64,7 @@
fixers=['distutils2.tests.fixer'])
converted_code_content = "isinstance(x, T)"
new_code_content = "".join(open(code_name).readlines())
- self.assertEquals(new_code_content, converted_code_content)
+ self.assertEqual(new_code_content, converted_code_content)
def test_suite():
return unittest.makeSuite(Mixin2to3TestCase)
diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py
--- a/distutils2/tests/test_util.py
+++ b/distutils2/tests/test_util.py
@@ -144,7 +144,7 @@
os.path.join = _join
self.assertEqual(convert_path('/home/to/my/stuff'),
- '/home/to/my/stuff')
+ '/home/to/my/stuff')
# win
os.sep = '\\'
@@ -156,9 +156,9 @@
self.assertRaises(ValueError, convert_path, 'home/to/my/stuff/')
self.assertEqual(convert_path('home/to/my/stuff'),
- 'home\\to\\my\\stuff')
+ 'home\\to\\my\\stuff')
self.assertEqual(convert_path('.'),
- os.curdir)
+ os.curdir)
def test_change_root(self):
# linux/mac
@@ -171,9 +171,9 @@
os.path.join = _join
self.assertEqual(change_root('/root', '/old/its/here'),
- '/root/old/its/here')
+ '/root/old/its/here')
self.assertEqual(change_root('/root', 'its/here'),
- '/root/its/here')
+ '/root/its/here')
# windows
os.name = 'nt'
@@ -190,9 +190,9 @@
os.path.join = _join
self.assertEqual(change_root('c:\\root', 'c:\\old\\its\\here'),
- 'c:\\root\\old\\its\\here')
+ 'c:\\root\\old\\its\\here')
self.assertEqual(change_root('c:\\root', 'its\\here'),
- 'c:\\root\\its\\here')
+ 'c:\\root\\its\\here')
# BugsBunny os (it's a great os)
os.name = 'BugsBunny'
@@ -203,7 +203,7 @@
def test_split_quoted(self):
self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'),
- ['one', 'two', 'three', 'four'])
+ ['one', 'two', 'three', 'four'])
def test_strtobool(self):
yes = ('y', 'Y', 'yes', 'True', 't', 'true', 'True', 'On', 'on', '1')
@@ -383,7 +383,7 @@
run_2to3([file_name])
new_content = "".join(file_handle.read())
file_handle.close()
- self.assertEquals(new_content, converted_content)
+ self.assertEqual(new_content, converted_content)
@unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_run_2to3_on_doctests(self):
@@ -399,7 +399,7 @@
run_2to3([file_name], doctests_only=True)
new_content = "".join(file_handle.readlines())
file_handle.close()
- self.assertEquals(new_content, converted_content)
+ self.assertEqual(new_content, converted_content)
def test_nt_quote_args(self):
diff --git a/distutils2/tests/test_version.py b/distutils2/tests/test_version.py
--- a/distutils2/tests/test_version.py
+++ b/distutils2/tests/test_version.py
@@ -61,9 +61,9 @@
def test_huge_version(self):
- self.assertEquals(str(V('1980.0')), '1980.0')
+ self.assertEqual(str(V('1980.0')), '1980.0')
self.assertRaises(HugeMajorVersionNumError, V, '1981.0')
- self.assertEquals(str(V('1981.0', error_on_huge_major_num=False)), '1981.0')
+ self.assertEqual(str(V('1981.0', error_on_huge_major_num=False)), '1981.0')
def test_comparison(self):
r"""
@@ -196,9 +196,20 @@
self.assertRaises(ValueError, VersionPredicate, '')
+ self.assertTrue(VersionPredicate('Hey 2.5').match('2.5.1'))
+
# XXX need to silent the micro version in this case
#assert not VersionPredicate('Ho (<3.0,!=2.6)').match('2.6.3')
+
+ # Make sure a predicate that ends with a number works
+ self.assertTrue(VersionPredicate('virtualenv5 (1.0)').match('1.0'))
+ self.assertTrue(VersionPredicate('virtualenv5').match('1.0'))
+ self.assertTrue(VersionPredicate('vi5two').match('1.0'))
+ self.assertTrue(VersionPredicate('5two').match('1.0'))
+ self.assertTrue(VersionPredicate('vi5two 1.0').match('1.0'))
+ self.assertTrue(VersionPredicate('5two 1.0').match('1.0'))
+
# test repr
for predicate in predicates:
self.assertEqual(str(VersionPredicate(predicate)), predicate)
@@ -220,12 +231,13 @@
for version in other_versions:
self.assertFalse(V(version).is_final)
+
class VersionWhiteBoxTestCase(unittest.TestCase):
def test_parse_numdots(self):
# For code coverage completeness, as pad_zeros_length can't be set or
# influenced from the public interface
- self.assertEquals(V('1.0')._parse_numdots('1.0', '1.0',
+ self.assertEqual(V('1.0')._parse_numdots('1.0', '1.0',
pad_zeros_length=3),
[1, 0, 0])
diff --git a/distutils2/version.py b/distutils2/version.py
--- a/distutils2/version.py
+++ b/distutils2/version.py
@@ -322,8 +322,9 @@
return None
-_PREDICATE = re.compile(r"(?i)^\s*([a-z_][\sa-zA-Z_-]*(?:\.[a-z_]\w*)*)(.*)")
-_VERSIONS = re.compile(r"^\s*\((.*)\)\s*$")
+# A predicate is: "ProjectName (VERSION1, VERSION2, ..)
+_PREDICATE = re.compile(r"(?i)^\s*(\w[\s\w-]*(?:\.\w*)*)(.*)")
+_VERSIONS = re.compile(r"^\s*\((?P<versions>.*)\)\s*$|^\s*(?P<versions2>.*)\s*$")
_PLAIN_VERSIONS = re.compile(r"^\s*(.*)\s*$")
_SPLIT_CMP = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
@@ -358,14 +359,25 @@
name, predicates = match.groups()
self.name = name.strip()
- predicates = predicates.strip()
- predicates = _VERSIONS.match(predicates)
- if predicates is not None:
- predicates = predicates.groups()[0]
- self.predicates = [_split_predicate(pred.strip())
- for pred in predicates.split(',')]
+ self.predicates = []
+ if predicates is None:
+ return
+
+ predicates = _VERSIONS.match(predicates.strip())
+ if predicates is None:
+ return
+
+ predicates = predicates.groupdict()
+ if predicates['versions'] is not None:
+ versions = predicates['versions']
else:
- self.predicates = []
+ versions = predicates.get('versions2')
+
+ if versions is not None:
+ for version in versions.split(','):
+ if version.strip() == '':
+ continue
+ self.predicates.append(_split_predicate(version))
def match(self, version):
"""Check if the provided version matches the predicates."""
diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst
--- a/docs/source/install/index.rst
+++ b/docs/source/install/index.rst
@@ -927,15 +927,34 @@
GNU C / Cygwin / MinGW
^^^^^^^^^^^^^^^^^^^^^^
-These instructions only apply if you're using a version of Python prior to
-2.4.1 with a MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1).
-
This section describes the necessary steps to use Distutils with the GNU C/C++
compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter
that was built with Cygwin, everything should work without any of these
following steps.
-These compilers require some special libraries. This task is more complex than
+Not all extensions can be built with MinGW or Cygwin, but many can. Extensions
+most likely to not work are those that use C++ or depend on Microsoft Visual C
+extensions.
+
+To let Distutils compile your extension with Cygwin you have to type::
+
+ python setup.py build --compiler=cygwin
+
+and for Cygwin in no-cygwin mode [#]_ or for MinGW type::
+
+ python setup.py build --compiler=mingw32
+
+If you want to use any of these options/compilers as default, you should
+consider writing it in your personal or system-wide configuration file for
+Distutils (see section :ref:`inst-config-files`.)
+
+Older Versions of Python and MinGW
+""""""""""""""""""""""""""""""""""
+The following instructions only apply if you're using a version of Python
+inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with
+binutils-2.13.90-20030111-1).
+
+These compilers require some special libraries. This task is more complex than
for Borland's C++, because there is no program to convert the library. First
you have to create a list of symbols which the Python DLL exports. (You can find
a good program for this task at
@@ -965,18 +984,6 @@
them too. The converted files have to reside in the same directories as the
normal libraries do.
-To let Distutils compile your extension with Cygwin you now have to type ::
-
- python setup.py build --compiler cygwin
-
-and for Cygwin in no-cygwin mode [#]_ or for MinGW type::
-
- python setup.py build --compiler mingw32
-
-If you want to use any of these options/compilers as default, you should
-consider to write it in your personal or system-wide configuration file for
-Distutils (see section :ref:`inst-config-files`.)
-
.. seealso::
diff --git a/docs/source/library/distutils2.index.xmlrpc.rst b/docs/source/library/distutils2.index.xmlrpc.rst
--- a/docs/source/library/distutils2.index.xmlrpc.rst
+++ b/docs/source/library/distutils2.index.xmlrpc.rst
@@ -90,7 +90,7 @@
<ReleaseInfo FooBar 1.1>
Assuming we already have a :class:`distutils2.index.ReleaseInfo` object defined,
-it's possible to pass it ot the xmlrpc client to retrieve and complete it's
+it's possible to pass it ot the xmlrpc client to retrieve and complete its
metadata::
>>> foobar11 = ReleaseInfo("FooBar", "1.1")
diff --git a/docs/source/library/distutils2.rst b/docs/source/library/distutils2.rst
--- a/docs/source/library/distutils2.rst
+++ b/docs/source/library/distutils2.rst
@@ -24,6 +24,7 @@
distutils2.version
distutils2.metadata
distutils2.depgraph
+ distutils2.install
distutils2.index
distutils2.tests.pypi_server
diff --git a/runtests.py b/runtests.py
--- a/runtests.py
+++ b/runtests.py
@@ -64,7 +64,7 @@
# running coverage 2.x
cov.cache = COVERAGE_FILE
cov.restore()
- morfs = [m for m in cov.cexecuted.keys() if "distutils2" in m]
+ morfs = [m for m in cov.cexecuted if "distutils2" in m]
prefixes = ["runtests", "distutils2/tests", "distutils2/_backport"]
prefixes += ignore_prefixes(unittest)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -189,9 +189,10 @@
return exts
-setup_kwargs = {}
+setup_kwargs = {'scripts': ['distutils2/pysetup']}
+
if sys.version < '2.6':
- setup_kwargs['scripts'] = ['distutils2/mkcfg.py']
+ setup_kwargs['scripts'].append('distutils2/mkcfg.py')
if sys.version < '2.5':
setup_kwargs['ext_modules'] = prepare_hashlib_extensions()
--
Repository URL: http://hg.python.org/distutils2
More information about the Python-checkins
mailing list