[Python-checkins] distutils2: merged upstream

tarek.ziade python-checkins at python.org
Sun Sep 19 10:20:22 CEST 2010


tarek.ziade pushed 876665b5723a to distutils2:
http://hg.python.org/distutils2/rev/876665b5723a
changeset: 643:876665b5723a
parent: 642:dc69e41bcdd5
parent: 591:6637a9e0935e
user: Konrad Delong <konryd at gmail.com>
date: Sun Aug 15 22:48:31 2010 +0200
summary: merged upstream
files: src/distutils2/dist.py, src/distutils2/tests/Setup.sample, src/distutils2/tests/support.py, src/distutils2/tests/test_build_ext.py, src/distutils2/tests/test_converter.py, src/distutils2/tests/test_dist.py, src/distutils2/tests/test_extension.py, src/distutils2/tests/test_register.py, src/distutils2/tests/test_sdist.py, src/distutils2/tests/test_upload_docs.py
diff --git a/docs/source/distutils/sourcedist.rst b/docs/source/distutils/sourcedist.rst
--- a/docs/source/distutils/sourcedist.rst
+++ b/docs/source/distutils/sourcedist.rst
@@ -108,6 +108,9 @@
 :file:`MANIFEST`, you must specify everything: the default set of files
 described above does not apply in this case.
 
+:file:`MANIFEST` files start with a comment indicating they are generated.
+Files without this comment are not overwritten or removed.
+
 See :ref:`manifest_template` section for a syntax reference.
 
 .. _manifest-options:
@@ -264,4 +267,3 @@
 ``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename
 character" is platform-specific: on Unix it is anything except slash; on Windows
 anything except backslash or colon.
-
diff --git a/docs/source/library/distutils2.version.rst b/docs/source/library/distutils2.version.rst
--- a/docs/source/library/distutils2.version.rst
+++ b/docs/source/library/distutils2.version.rst
@@ -7,8 +7,8 @@
 <http://www.python.org/dev/peps/pep-0345/#version-specifiers>`_ about
 Metadatas.
 
-NormalizedVersion 
-==================
+NormalizedVersion
+=================
 
 A Normalized version is a specific version of a distribution, as
 described in the PEP 345. So, you can work with the `NormalizedVersion` like
@@ -35,10 +35,10 @@
 ----------------------------
 
 Before this version scheme, there was existing others ones. Distutils2 provides
-a tool that suggests a normalized version: the `suggest_normalized_version` 
+a tool that suggests a normalized version: the `suggest_normalized_version`
 function::
 
- >>> suggest_normalized_version('2.1-rc1') 
+ >>> suggest_normalized_version('2.1-rc1')
 2.1c1
 
 If `suggest_normalized_version` can't actually suggest you a version, it will
@@ -47,7 +47,7 @@
 >>> print suggest_normalized_version('not a version')
 None
 
-Dealing with version predicates 
+Dealing with version predicates
 ===============================
 
 `VersionPredicate` knows how to parse stuff like "ProjectName (>=version)", the
diff --git a/src/DEVNOTES.txt b/src/DEVNOTES.txt
--- a/src/DEVNOTES.txt
+++ b/src/DEVNOTES.txt
@@ -15,7 +15,8 @@
 
 - Renaming to do:
 
- - DistributionMetadata > Metadata or ReleaseMetadata
+ - DistributionMetadata > Metadata
+ - Distribution > Release or Project
 - pkgutil > pkgutil.__init__ + new pkgutil.database (or better name)
 - RationalizedVersion > Version
 - suggest_rationalized_version > suggest
diff --git a/src/distutils2/command/build.py b/src/distutils2/command/build.py
--- a/src/distutils2/command/build.py
+++ b/src/distutils2/command/build.py
@@ -43,6 +43,12 @@
 "forcibly build everything (ignore file timestamps)"),
 ('executable=', 'e',
 "specify final destination interpreter path (build.py)"),
+ ('use-2to3', None,
+ "use 2to3 to make source python 3.x compatible"),
+ ('convert-2to3-doctests', None,
+ "use 2to3 to convert doctests in seperate text files"),
+ ('use-2to3-fixers', None,
+ "list additional fixers opted for during 2to3 conversion"),
 ]
 
 boolean_options = ['debug', 'force']
@@ -66,6 +72,9 @@
 self.debug = None
 self.force = 0
 self.executable = None
+ self.use_2to3 = False
+ self.convert_2to3_doctests = None
+ self.use_2to3_fixers = None
 
 def finalize_options(self):
 if self.plat_name is None:
diff --git a/src/distutils2/command/build_py.py b/src/distutils2/command/build_py.py
--- a/src/distutils2/command/build_py.py
+++ b/src/distutils2/command/build_py.py
@@ -13,57 +13,10 @@
 from distutils2.core import Command
 from distutils2.errors import DistutilsOptionError, DistutilsFileError
 from distutils2.util import convert_path
-from distutils2.converter.refactor import DistutilsRefactoringTool
+from distutils2.compat import Mixin2to3
 
 # marking public APIs
-__all__ = ['Mixin2to3', 'build_py']
-
-try:
- from distutils2.util import Mixin2to3 as _Mixin2to3
- from lib2to3.refactor import get_fixers_from_package
- _CONVERT = True
- _KLASS = _Mixin2to3
-except ImportError:
- _CONVERT = False
- _KLASS = object
-
-class Mixin2to3(_KLASS):
- """ The base class which can be used for refactoring. When run under
- Python 3.0, the run_2to3 method provided by Mixin2to3 is overridden.
- When run on Python 2.x, it merely creates a class which overrides run_2to3,
- yet does nothing in particular with it.
- """
- if _CONVERT:
- def _run_2to3(self, files, doctests=[]):
- """ Takes a list of files and doctests, and performs conversion
- on those.
- - First, the files which contain the code(`files`) are converted.
- - Second, the doctests in `files` are converted.
- - Thirdly, the doctests in `doctests` are converted.
- """
-
- # Convert the ".py" files.
- logging.info("Converting Python code")
- _KLASS.run_2to3(self, files)
-
- # Convert the doctests in the ".py" files.
- logging.info("Converting doctests with '.py' files")
- _KLASS.run_2to3(self, files, doctests_only=True)
-
- # If the following conditions are met, then convert:-
- # 1. User has specified the 'convert_2to3_doctests' option. So, we
- # can expect that the list 'doctests' is not empty.
- # 2. The default is allow distutils2 to allow conversion of text files
- # containing doctests. It is set as
- # distutils2.run_2to3_on_doctests
-
- if doctests != [] and distutils2.run_2to3_on_doctests:
- logging.info("Converting text files which contain doctests")
- _KLASS.run_2to3(self, doctests, doctests_only=True)
- else:
- # If run on Python 2.x, there is nothing to do.
- def _run_2to3(self, files, doctests=[]):
- pass
+__all__ = ['build_py']
 
 class build_py(Command, Mixin2to3):
 
@@ -77,6 +30,12 @@
 "also compile with optimization: -O1 for \"python -O\", "
 "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"),
 ('force', 'f', "forcibly build everything (ignore file timestamps)"),
+ ('use-2to3', None,
+ "use 2to3 to make source python 3.x compatible"),
+ ('convert-2to3-doctests', None,
+ "use 2to3 to convert doctests in seperate text files"),
+ ('use-2to3-fixers', None,
+ "list additional fixers opted for during 2to3 conversion"),
 ]
 
 boolean_options = ['compile', 'force']
@@ -93,9 +52,15 @@
 self.force = None
 self._updated_files = []
 self._doctests_2to3 = []
+ self.use_2to3 = False
+ self.convert_2to3_doctests = None
+ self.use_2to3_fixers = None
 
 def finalize_options(self):
- self.set_undefined_options('build', 'build_lib', 'force')
+ self.set_undefined_options('build',
+ 'use_2to3', 'use_2to3_fixers',
+ 'convert_2to3_doctests', 'build_lib',
+ 'force')
 
 # Get the distribution options that are aliases for build_py
 # options -- list of packages and list of modules.
@@ -145,8 +110,9 @@
 self.build_packages()
 self.build_package_data()
 
- if self.distribution.use_2to3 and self_updated_files:
- self.run_2to3(self._updated_files, self._doctests_2to3)
+ if self.use_2to3 and self._updated_files:
+ self.run_2to3(self._updated_files, self._doctests_2to3,
+ self.use_2to3_fixers)
 
 self.byte_compile(self.get_outputs(include_bytecode=0))
 
diff --git a/src/distutils2/command/build_scripts.py b/src/distutils2/command/build_scripts.py
--- a/src/distutils2/command/build_scripts.py
+++ b/src/distutils2/command/build_scripts.py
@@ -13,11 +13,12 @@
 import sysconfig
 except ImportError:
 from distutils2._backport import sysconfig
+from distutils2.compat import Mixin2to3
 
 # check if Python is called on the first line with this expression
 first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
 
-class build_scripts (Command):
+class build_scripts (Command, Mixin2to3):
 
 description = "\"build\" scripts (copy and fixup #! line)"
 
@@ -36,11 +37,16 @@
 self.force = None
 self.executable = None
 self.outfiles = None
+ self.use_2to3 = False
+ self.convert_2to3_doctests = None
+ self.use_2to3_fixers = None
 
 def finalize_options (self):
 self.set_undefined_options('build',
 ('build_scripts', 'build_dir'),
- 'force', 'executable')
+ 'use_2to3', 'use_2to3_fixers',
+ 'convert_2to3_doctests', 'force',
+ 'executable')
 self.scripts = self.distribution.scripts
 
 def get_source_files(self):
@@ -49,8 +55,9 @@
 def run (self):
 if not self.scripts:
 return
- self.copy_scripts()
-
+ copied_files = self.copy_scripts()
+ if self.use_2to3 and self.copied_files:
+ self._run_2to3(self.copied_files, fixers=self.use_2to3_fixers)
 
 def copy_scripts (self):
 """Copy each script listed in 'self.scripts'; if it's marked as a
@@ -126,7 +133,7 @@
 log.info("changing mode of %s from %o to %o",
 file, oldmode, newmode)
 os.chmod(file, newmode)
-
+ return outfiles
 # copy_scripts ()
 
 # class build_scripts
diff --git a/src/distutils2/command/cmd.py b/src/distutils2/command/cmd.py
--- a/src/distutils2/command/cmd.py
+++ b/src/distutils2/command/cmd.py
@@ -53,7 +53,7 @@
 
 # Pre and post command hooks are run just before or just after the command
 # itself. They are simple functions that receive the command instance. They
- # should be specified as dotted strings.
+ # are specified as callable objects or dotted strings (for lazy loading).
 pre_hook = None
 post_hook = None
 
@@ -162,13 +162,12 @@
 
 
 def dump_options(self, header=None, indent=""):
- from distutils2.fancy_getopt import longopt_xlate
 if header is None:
 header = "command options for '%s':" % self.get_command_name()
 self.announce(indent + header, level=log.INFO)
 indent = indent + " "
 for (option, _, _) in self.user_options:
- option = option.translate(longopt_xlate)
+ option = option.replace('-', '_')
 if option[-1] == "=":
 option = option[:-1]
 value = getattr(self, option)
@@ -331,7 +330,6 @@
 setattr(self, dst_option,
 getattr(src_cmd_obj, src_option))
 
-
 def get_finalized_command(self, command, create=1):
 """Wrapper around Distribution's 'get_command_obj()' method: find
 (create if necessary and 'create' is true) the command object for
diff --git a/src/distutils2/command/install.py b/src/distutils2/command/install.py
--- a/src/distutils2/command/install.py
+++ b/src/distutils2/command/install.py
@@ -18,7 +18,6 @@
 from distutils2.util import convert_path, change_root, get_platform
 from distutils2.errors import DistutilsOptionError
 
-
 class install(Command):
 
 description = "install everything from build directory"
@@ -193,6 +192,7 @@
 # array of user input is decided. Yes, it's quite complex!)
 
 def finalize_options(self):
+ """Finalizes options."""
 # This method (and its pliant slaves, like 'finalize_unix()',
 # 'finalize_other()', and 'select_scheme()') is where the default
 # installation directories for modules, extension modules, and
diff --git a/src/distutils2/command/install_distinfo.py b/src/distutils2/command/install_distinfo.py
--- a/src/distutils2/command/install_distinfo.py
+++ b/src/distutils2/command/install_distinfo.py
@@ -25,9 +25,8 @@
 
 
 class install_distinfo(Command):
- """Install a .dist-info directory for the package"""
 
- description = 'Install a .dist-info directory for the package'
+ description = 'install a .dist-info directory for the distribution'
 
 user_options = [
 ('distinfo-dir=', None,
diff --git a/src/distutils2/compat.py b/src/distutils2/compat.py
new file mode 100644
--- /dev/null
+++ b/src/distutils2/compat.py
@@ -0,0 +1,64 @@
+""" distutils2.compat
+
+Used to provide classes, variables and imports which can be used to
+support distutils2 across versions(2.x and 3.x)
+"""
+
+import logging
+
+
+try:
+ from distutils2.util import Mixin2to3 as _Mixin2to3
+ from distutils2 import run_2to3_on_doctests
+ from lib2to3.refactor import get_fixers_from_package
+ _CONVERT = True
+ _KLASS = _Mixin2to3
+except ImportError:
+ _CONVERT = False
+ _KLASS = object
+
+# marking public APIs
+__all__ = ['Mixin2to3']
+
+class Mixin2to3(_KLASS):
+ """ The base class which can be used for refactoring. When run under
+ Python 3.0, the run_2to3 method provided by Mixin2to3 is overridden.
+ When run on Python 2.x, it merely creates a class which overrides run_2to3,
+ yet does nothing in particular with it.
+ """
+ if _CONVERT:
+ def _run_2to3(self, files, doctests=[], fixers=[]):
+ """ Takes a list of files and doctests, and performs conversion
+ on those.
+ - First, the files which contain the code(`files`) are converted.
+ - Second, the doctests in `files` are converted.
+ - Thirdly, the doctests in `doctests` are converted.
+ """
+ # if additional fixers are present, use them
+ if fixers:
+ self.fixer_names = fixers
+
+ # Convert the ".py" files.
+ logging.info("Converting Python code")
+ _KLASS.run_2to3(self, files)
+
+ # Convert the doctests in the ".py" files.
+ logging.info("Converting doctests with '.py' files")
+ _KLASS.run_2to3(self, files, doctests_only=True)
+
+ # If the following conditions are met, then convert:-
+ # 1. User has specified the 'convert_2to3_doctests' option. So, we
+ # can expect that the list 'doctests' is not empty.
+ # 2. The default is allow distutils2 to allow conversion of text files
+ # containing doctests. It is set as
+ # distutils2.run_2to3_on_doctests
+
+ if doctests != [] and run_2to3_on_doctests:
+ logging.info("Converting text files which contain doctests")
+ _KLASS.run_2to3(self, doctests, doctests_only=True)
+ else:
+ # If run on Python 2.x, there is nothing to do.
+ def _run_2to3(self, files, doctests=[], fixers=[]):
+ pass
+
+
diff --git a/src/distutils2/converter/__init__.py b/src/distutils2/converter/__init__.py
--- a/src/distutils2/converter/__init__.py
+++ b/src/distutils2/converter/__init__.py
@@ -1,8 +0,0 @@
-"""distutils2.converter
-
-This package provide a refactoring tool to transform a
-setuptools or distutils project into a distutils2 one.
-"""
-
-from distutils2.converter.refactor import DistutilsRefactoringTool
-
diff --git a/src/distutils2/converter/refactor.py b/src/distutils2/converter/refactor.py
--- a/src/distutils2/converter/refactor.py
+++ b/src/distutils2/converter/refactor.py
@@ -1,7 +1,5 @@
 """distutils2.converter.refactor
 
-Provides DistutilsRefactoringTool, a class that register fixers used
-to refactor distutils or setuptools packages into distutils2 ones.
 """
 try:
 from lib2to3.refactor import RefactoringTool
@@ -11,18 +9,4 @@
 _LIB2TO3 = False
 
 _DISTUTILS_FIXERS = ['distutils2.converter.fixers.fix_imports',
- 'distutils2.converter.fixers.fix_setup_options']
-
-if _LIB2TO3:
- class DistutilsRefactoringTool(RefactoringTool):
-
- def __init__(self, fixer_names=_DISTUTILS_FIXERS, options=None,
- explicit=None):
-
- super(DistutilsRefactoringTool, self).__init__(fixer_names, options,
- explicit)
-else:
- class DistutilsRefactoringTool(object):
- def __init__(self, *args, **kw):
- raise NotImplementedError('Not available if run from Python < 2.6')
-
+ 'distutils2.converter.fixers.fix_setup_options']
\ No newline at end of file
diff --git a/src/distutils2/core.py b/src/distutils2/core.py
--- a/src/distutils2/core.py
+++ b/src/distutils2/core.py
@@ -49,8 +49,8 @@
 'maintainer', 'maintainer_email', 'url', 'license',
 'description', 'long_description', 'keywords',
 'platforms', 'classifiers', 'download_url',
- 'requires', 'provides', 'obsoletes', 'use_2to3',
- 'convert_2to3_doctests',
+ 'requires', 'provides', 'obsoletes', 'use_2to3_fixers',
+ 'convert_2to3_doctests', 'use_2to3_fixers'
 )
 
 # Legal keyword arguments for the Extension constructor
diff --git a/src/distutils2/dist.py b/src/distutils2/dist.py
--- a/src/distutils2/dist.py
+++ b/src/distutils2/dist.py
@@ -375,14 +375,13 @@
 val = parser.get(section, opt)
 opt = opt.replace('-', '_')
 
- # ... although practicality beats purity :(
+ # Hooks use a suffix system to prevent being overriden
+ # by a config file processed later (i.e. a hook set in
+ # the user config file cannot be replaced by a hook
+ # set in a project config file, unless they have the
+ # same suffix).
 if opt.startswith("pre_hook.") or opt.startswith("post_hook."):
 hook_type, alias = opt.split(".")
- # Hooks are somewhat exceptional, as they are
- # gathered from many config files (not overriden as
- # other options).
- # The option_dict expects {"command": ("filename", # "value")}
- # so for hooks, we store only the last config file processed
 hook_dict = opt_dict.setdefault(hook_type, (filename, {}))[1]
 hook_dict[alias] = val
 else:
@@ -963,12 +962,34 @@
 self.have_run[command] = 1
 
 def run_command_hooks(self, cmd_obj, hook_kind):
+ """Run hooks registered for that command and phase.
+
+ *cmd_obj* is a finalized command object; *hook_kind* is either
+ 'pre_hook' or 'post_hook'.
+ """
+ if hook_kind not in ('pre_hook', 'post_hook'):
+ raise ValueError('invalid hook kind: %r' % hook_kind)
+
 hooks = getattr(cmd_obj, hook_kind)
+
 if hooks is None:
 return
- for hook in hooks.values():
- hook_func = resolve_name(hook)
- hook_func(cmd_obj)
+
+ for hook in hooks.itervalues():
+ if isinstance(hook, basestring):
+ try:
+ hook_obj = resolve_name(hook)
+ except ImportError, e:
+ raise DistutilsModuleError(e)
+ else:
+ hook_obj = hook
+
+ if not hasattr(hook_obj, '__call__'):
+ raise DistutilsOptionError('hook %r is not callable' % hook)
+
+ log.info('running %s %s for command %s',
+ hook_kind, hook, cmd_obj.get_command_name())
+ hook_obj(cmd_obj)
 
 # -- Distribution query methods ------------------------------------
 def has_pure_modules(self):
diff --git a/src/distutils2/fancy_getopt.py b/src/distutils2/fancy_getopt.py
--- a/src/distutils2/fancy_getopt.py
+++ b/src/distutils2/fancy_getopt.py
@@ -26,11 +26,6 @@
 # For recognizing "negative alias" options, eg. "quiet=!verbose"
 neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat))
 
-# This is used to translate long options to legitimate Python identifiers
-# (for use as attributes of some object).
-longopt_xlate = string.maketrans('-', '_')
-
-
 class FancyGetopt(object):
 """Wrapper around the standard 'getopt()' module that provides some
 handy extra functionality:
@@ -115,8 +110,7 @@
 """Translate long option name 'long_option' to the form it
 has as an attribute of some object: ie., translate hyphens
 to underscores."""
- return string.translate(long_option, longopt_xlate)
-
+ return long_option.replace('-', '_')
 
 def _check_alias_dict (self, aliases, what):
 assert isinstance(aliases, dict)
@@ -472,7 +466,7 @@
 """Convert a long option name to a valid Python identifier by
 changing "-" to "_".
 """
- return string.translate(opt, longopt_xlate)
+ return opt.replace('-', '_')
 
 
 class OptionDummy(object):
diff --git a/src/distutils2/index/simple.py b/src/distutils2/index/simple.py
--- a/src/distutils2/index/simple.py
+++ b/src/distutils2/index/simple.py
@@ -160,12 +160,12 @@
 the results.
 """
 predicate = get_version_predicate(requirements)
- if self._projects.has_key(predicate.name.lower()) and not force_update:
+ 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)
 self._process_index_page(predicate.name)
 
- if not self._projects.has_key(predicate.name.lower()):
+ if predicate.name.lower() not in self._projects:
 raise ProjectNotFound()
 
 releases = self._projects.get(predicate.name.lower())
diff --git a/src/distutils2/manifest.py b/src/distutils2/manifest.py
--- a/src/distutils2/manifest.py
+++ b/src/distutils2/manifest.py
@@ -96,9 +96,24 @@
 by 'add_defaults()' and 'read_template()') to the manifest file
 named by 'self.manifest'.
 """
+ if os.path.isfile(path):
+ fp = open(path)
+ try:
+ first_line = fp.readline()
+ finally:
+ fp.close()
+
+ if first_line != '# file GENERATED by distutils, do NOT edit\n':
+ logging.info("not writing to manually maintained "
+ "manifest file '%s'", path)
+ return
+
 self.sort()
 self.remove_duplicates()
- write_file(path, self.files)
+ content = self.files[:]
+ content.insert(0, '# file GENERATED by distutils, do NOT edit')
+ logging.info("writing manifest file '%s'", path)
+ write_file(path, content)
 
 def read(self, path):
 """Read the manifest file (named by 'self.manifest') and use it to
diff --git a/src/distutils2/metadata.py b/src/distutils2/metadata.py
--- a/src/distutils2/metadata.py
+++ b/src/distutils2/metadata.py
@@ -384,6 +384,7 @@
 if not is_valid_predicate(v.split(';')[0]):
 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):
 warn('"%s" is not a valid version (field "%s")' %
diff --git a/src/distutils2/tests/Setup.sample b/src/distutils2/tests/Setup.sample
deleted file mode 100755
--- a/src/distutils2/tests/Setup.sample
+++ /dev/null
@@ -1,67 +0,0 @@
-# Setup file from the pygame project
-
-#--StartConfig
-SDL = -I/usr/include/SDL -D_REENTRANT -lSDL
-FONT = -lSDL_ttf
-IMAGE = -lSDL_image
-MIXER = -lSDL_mixer
-SMPEG = -lsmpeg
-PNG = -lpng
-JPEG = -ljpeg
-SCRAP = -lX11
-PORTMIDI = -lportmidi
-PORTTIME = -lporttime
-#--EndConfig
-
-#DEBUG = -C-W -C-Wall
-DEBUG = 
-
-#the following modules are optional. you will want to compile
-#everything you can, but you can ignore ones you don't have
-#dependencies for, just comment them out
-
-imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG)
-font src/font.c $(SDL) $(FONT) $(DEBUG)
-mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG)
-mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG)
-_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG)
-_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG)
-movie src/movie.c $(SDL) $(SMPEG) $(DEBUG)
-scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG)
-_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG)
-pypm src/pypm.c $(SDL) $(PORTMIDI) $(PORTTIME) $(DEBUG)
-
-GFX = src/SDL_gfx/SDL_gfxPrimitives.c 
-#GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c 
-gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG)
-
-
-
-#these modules are required for pygame to run. they only require
-#SDL as a dependency. these should not be altered
-
-base src/base.c $(SDL) $(DEBUG)
-cdrom src/cdrom.c $(SDL) $(DEBUG)
-color src/color.c $(SDL) $(DEBUG)
-constants src/constants.c $(SDL) $(DEBUG)
-display src/display.c $(SDL) $(DEBUG)
-event src/event.c $(SDL) $(DEBUG)
-fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG)
-key src/key.c $(SDL) $(DEBUG)
-mouse src/mouse.c $(SDL) $(DEBUG)
-rect src/rect.c $(SDL) $(DEBUG)
-rwobject src/rwobject.c $(SDL) $(DEBUG)
-surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG)
-surflock src/surflock.c $(SDL) $(DEBUG)
-time src/time.c $(SDL) $(DEBUG)
-joystick src/joystick.c $(SDL) $(DEBUG)
-draw src/draw.c $(SDL) $(DEBUG)
-image src/image.c $(SDL) $(DEBUG)
-overlay src/overlay.c $(SDL) $(DEBUG)
-transform src/transform.c src/rotozoom.c src/scale2x.c src/scale_mmx.c $(SDL) $(DEBUG)
-mask src/mask.c src/bitmask.c $(SDL) $(DEBUG)
-bufferproxy src/bufferproxy.c $(SDL) $(DEBUG)
-pixelarray src/pixelarray.c $(SDL) $(DEBUG)
-_arraysurfarray src/_arraysurfarray.c $(SDL) $(DEBUG)
-
-
diff --git a/src/distutils2/tests/conversions/05_before.py b/src/distutils2/tests/conversions/05_before.py
old mode 100755
new mode 100644
diff --git a/src/distutils2/tests/fixer/__init__.py b/src/distutils2/tests/fixer/__init__.py
new file mode 100644
diff --git a/src/distutils2/tests/fixer/fix_idioms.py b/src/distutils2/tests/fixer/fix_idioms.py
new file mode 100644
--- /dev/null
+++ b/src/distutils2/tests/fixer/fix_idioms.py
@@ -0,0 +1,134 @@
+"""Adjust some old Python 2 idioms to their modern counterparts.
+
+* Change some type comparisons to isinstance() calls:
+ type(x) == T -> isinstance(x, T)
+ type(x) is T -> isinstance(x, T)
+ type(x) != T -> not isinstance(x, T)
+ type(x) is not T -> not isinstance(x, T)
+
+* Change "while 1:" into "while True:".
+
+* Change both
+
+ v = list(EXPR)
+ v.sort()
+ foo(v)
+
+and the more general
+
+ v = EXPR
+ v.sort()
+ foo(v)
+
+into
+
+ v = sorted(EXPR)
+ foo(v)
+"""
+# Author: Jacques Frechet, Collin Winter
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Call, Comma, Name, Node, syms
+
+CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)"
+TYPE = "power< 'type' trailer< '(' x=any ')' > >"
+
+class FixIdioms(fixer_base.BaseFix):
+
+ explicit = False # The user must ask for this fixer
+
+ PATTERN = r"""
+ isinstance=comparison< %s %s T=any >
+ |
+ isinstance=comparison< T=any %s %s >
+ |
+ while_stmt< 'while' while='1' ':' any+ >
+ |
+ sorted=any<
+ any*
+ simple_stmt<
+ expr_stmt< id1=any '='
+ power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
+ >
+ '\n'
+ >
+ sort=
+ simple_stmt<
+ power< id2=any
+ trailer< '.' 'sort' > trailer< '(' ')' >
+ >
+ '\n'
+ >
+ next=any*
+ >
+ |
+ sorted=any<
+ any*
+ simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
+ sort=
+ simple_stmt<
+ power< id2=any
+ trailer< '.' 'sort' > trailer< '(' ')' >
+ >
+ '\n'
+ >
+ next=any*
+ >
+ """ % (TYPE, CMP, CMP, TYPE)
+
+ def match(self, node):
+ r = super(FixIdioms, self).match(node)
+ # If we've matched one of the sort/sorted subpatterns above, we
+ # want to reject matches where the initial assignment and the
+ # subsequent .sort() call involve different identifiers.
+ if r and "sorted" in r:
+ if r["id1"] == r["id2"]:
+ return r
+ return None
+ return r
+
+ def transform(self, node, results):
+ if "isinstance" in results:
+ return self.transform_isinstance(node, results)
+ elif "while" in results:
+ return self.transform_while(node, results)
+ elif "sorted" in results:
+ return self.transform_sort(node, results)
+ else:
+ raise RuntimeError("Invalid match")
+
+ def transform_isinstance(self, node, results):
+ x = results["x"].clone() # The thing inside of type()
+ T = results["T"].clone() # The type being compared against
+ x.set_prefix("")
+ T.set_prefix(" ")
+ test = Call(Name("isinstance"), [x, Comma(), T])
+ if "n" in results:
+ test.set_prefix(" ")
+ test = Node(syms.not_test, [Name("not"), test])
+ test.set_prefix(node.get_prefix())
+ return test
+
+ def transform_while(self, node, results):
+ one = results["while"]
+ one.replace(Name("True", prefix=one.get_prefix()))
+
+ def transform_sort(self, node, results):
+ sort_stmt = results["sort"]
+ next_stmt = results["next"]
+ list_call = results.get("list")
+ simple_expr = results.get("expr")
+
+ if list_call:
+ list_call.replace(Name("sorted", prefix=list_call.get_prefix()))
+ elif simple_expr:
+ new = simple_expr.clone()
+ new.set_prefix("")
+ simple_expr.replace(Call(Name("sorted"), [new],
+ prefix=simple_expr.get_prefix()))
+ else:
+ raise RuntimeError("should not have reached here")
+ sort_stmt.remove()
+ if next_stmt:
+ next_stmt[0].set_prefix(sort_stmt.get_prefix())
diff --git a/src/distutils2/tests/support.py b/src/distutils2/tests/support.py
--- a/src/distutils2/tests/support.py
+++ b/src/distutils2/tests/support.py
@@ -4,13 +4,14 @@
 (standard library unittest for 3.2 and higher, third-party unittest2
 release for older versions).
 
-Four helper classes are provided: LoggingSilencer, TempdirManager, EnvironGuard
-and WarningsCatcher. They are written to be used as mixins, e.g. ::
+Four helper classes are provided: LoggingCatcher, TempdirManager,
+EnvironGuard and WarningsCatcher. They are written to be used as mixins,
+e.g. ::
 
 from distutils2.tests.support import unittest
- from distutils2.tests.support import LoggingSilencer
+ from distutils2.tests.support import LoggingCatcher
 
- class SomeTestCase(LoggingSilencer, unittest.TestCase):
+ class SomeTestCase(LoggingCatcher, unittest.TestCase):
 
 If you need to define a setUp method on your test class, you have to
 call the mixin class' setUp method or it won't work (same thing for
@@ -43,11 +44,11 @@
 # external release of same package for older versions
 import unittest2 as unittest
 
-__all__ = ['LoggingSilencer', 'TempdirManager', 'EnvironGuard',
- 'DummyCommand', 'unittest']
+__all__ = ['LoggingCatcher', 'WarningsCatcher', 'TempdirManager',
+ 'EnvironGuard', 'DummyCommand', 'unittest']
 
 
-class LoggingSilencer(object):
+class LoggingCatcher(object):
 """TestCase-compatible mixin to catch logging calls.
 
 Every log message that goes through distutils2.log will get appended to
@@ -57,7 +58,7 @@
 """
 
 def setUp(self):
- super(LoggingSilencer, self).setUp()
+ super(LoggingCatcher, self).setUp()
 self.threshold = log.set_threshold(FATAL)
 # when log is replaced by logging we won't need
 # such monkey-patching anymore
@@ -68,7 +69,7 @@
 def tearDown(self):
 log.set_threshold(self.threshold)
 log.Log._log = self._old_log
- super(LoggingSilencer, self).tearDown()
+ super(LoggingCatcher, self).tearDown()
 
 def _log(self, level, msg, args):
 if level not in (DEBUG, INFO, WARN, ERROR, FATAL):
@@ -92,6 +93,30 @@
 del self.logs[:]
 
 
+class LoggingSilencer(object):
+ "Class that raises an exception to make sure the renaming is noticed."
+
+ def __init__(self, *args):
+ raise DeprecationWarning("LoggingSilencer renamed to LoggingCatcher")
+
+
+class WarningsCatcher(object):
+
+ def setUp(self):
+ self._orig_showwarning = warnings.showwarning
+ warnings.showwarning = self._record_showwarning
+ self.warnings = []
+
+ def _record_showwarning(self, message, category, filename, lineno,
+ file=None, line=None):
+ self.warnings.append({"message": message, "category": category,
+ "filename": filename, "lineno": lineno,
+ "file": file, "line": line})
+
+ def tearDown(self):
+ warnings.showwarning = self._orig_showwarning
+
+
 class TempdirManager(object):
 """TestCase-compatible mixin to create temporary directories and files.
 
@@ -172,25 +197,6 @@
 super(EnvironGuard, self).tearDown()
 
 
-class WarningsCatcher(object):
- 
- def setUp(self):
- self._orig_showwarning = warnings.showwarning
- warnings.showwarning = self._record_showwarning
- self.warnings = []
-
- def _record_showwarning(self, message, category, filename, lineno, file=None, line=None):
- self.warnings.append({"message": message,
- "category": category,
- "filename": filename,
- "lineno": lineno,
- "file": file,
- "line": line})
-
- def tearDown(self):
- warnings.showwarning = self._orig_showwarning
-
-
 class DummyCommand(object):
 """Class to store options for retrieval via set_undefined_options().
 
diff --git a/src/distutils2/tests/test_Mixin2to3.py b/src/distutils2/tests/test_Mixin2to3.py
--- a/src/distutils2/tests/test_Mixin2to3.py
+++ b/src/distutils2/tests/test_Mixin2to3.py
@@ -1,10 +1,11 @@
 """Tests for distutils.command.build_py."""
 import sys
+import logging
 
 import distutils2
 from distutils2.tests import support
 from distutils2.tests.support import unittest
-from distutils2.command.build_py import Mixin2to3
+from distutils2.compat import Mixin2to3
 
 
 class Mixin2to3TestCase(support.TempdirManager, unittest.TestCase):
@@ -46,6 +47,25 @@
 
 self.assertEquals(new_doctest_content, converted_doctest_content)
 
+ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
+ def test_additional_fixers(self):
+ # used to check if use_2to3_fixers works
+ from distutils2.tests import fixer
+ code_content = "type(x) is T"
+ code_handle = self.mktempfile()
+ code_name = code_handle.name
+
+ code_handle.write(code_content)
+ code_handle.flush()
+
+ mixin2to3 = Mixin2to3()
+
+ mixin2to3._run_2to3(files=[code_name],
+ 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)
+
 def test_suite():
 return unittest.makeSuite(Mixin2to3TestCase)
 
diff --git a/src/distutils2/tests/test_bdist_dumb.py b/src/distutils2/tests/test_bdist_dumb.py
--- a/src/distutils2/tests/test_bdist_dumb.py
+++ b/src/distutils2/tests/test_bdist_dumb.py
@@ -27,7 +27,7 @@
 """
 
 class BuildDumbTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.EnvironGuard,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_bdist_msi.py b/src/distutils2/tests/test_bdist_msi.py
--- a/src/distutils2/tests/test_bdist_msi.py
+++ b/src/distutils2/tests/test_bdist_msi.py
@@ -7,7 +7,7 @@
 from distutils2.tests.support import unittest
 
 class BDistMSITestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 @unittest.skipUnless(sys.platform == "win32", "runs only on win32")
diff --git a/src/distutils2/tests/test_bdist_wininst.py b/src/distutils2/tests/test_bdist_wininst.py
--- a/src/distutils2/tests/test_bdist_wininst.py
+++ b/src/distutils2/tests/test_bdist_wininst.py
@@ -7,7 +7,7 @@
 from distutils2.tests.support import unittest
 
 class BuildWinInstTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_get_exe_bytes(self):
diff --git a/src/distutils2/tests/test_build.py b/src/distutils2/tests/test_build.py
--- a/src/distutils2/tests/test_build.py
+++ b/src/distutils2/tests/test_build.py
@@ -11,7 +11,7 @@
 from distutils2._backport.sysconfig import get_platform
 
 class BuildTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_finalize_options(self):
diff --git a/src/distutils2/tests/test_build_clib.py b/src/distutils2/tests/test_build_clib.py
--- a/src/distutils2/tests/test_build_clib.py
+++ b/src/distutils2/tests/test_build_clib.py
@@ -9,7 +9,7 @@
 from distutils2.tests.support import unittest
 
 class BuildCLibTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_check_library_dist(self):
diff --git a/src/distutils2/tests/test_build_ext.py b/src/distutils2/tests/test_build_ext.py
--- a/src/distutils2/tests/test_build_ext.py
+++ b/src/distutils2/tests/test_build_ext.py
@@ -26,7 +26,7 @@
 return os.path.join(CURDIR, 'xxmodule.c')
 
 class BuildExtTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 def setUp(self):
 # Create a simple test environment
diff --git a/src/distutils2/tests/test_build_py.py b/src/distutils2/tests/test_build_py.py
--- a/src/distutils2/tests/test_build_py.py
+++ b/src/distutils2/tests/test_build_py.py
@@ -13,7 +13,7 @@
 
 
 class BuildPyTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_package_data(self):
@@ -37,7 +37,10 @@
 dist.script_name = os.path.join(sources, "setup.py")
 dist.command_obj["build"] = support.DummyCommand(
 force=0,
- build_lib=destination)
+ build_lib=destination,
+ use_2to3_fixers=None,
+ convert_2to3_doctests=None,
+ use_2to3=False)
 dist.packages = ["pkg"]
 dist.package_data = {"pkg": ["README.txt"]}
 dist.package_dir = {"pkg": sources}
diff --git a/src/distutils2/tests/test_build_scripts.py b/src/distutils2/tests/test_build_scripts.py
--- a/src/distutils2/tests/test_build_scripts.py
+++ b/src/distutils2/tests/test_build_scripts.py
@@ -14,7 +14,7 @@
 
 
 class BuildScriptsTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_default_settings(self):
@@ -49,7 +49,10 @@
 dist.command_obj["build"] = support.DummyCommand(
 build_scripts=target,
 force=1,
- executable=sys.executable
+ executable=sys.executable,
+ use_2to3=False,
+ use_2to3_fixers=None,
+ convert_2to3_doctests=None
 )
 return build_scripts(dist)
 
diff --git a/src/distutils2/tests/test_check.py b/src/distutils2/tests/test_check.py
--- a/src/distutils2/tests/test_check.py
+++ b/src/distutils2/tests/test_check.py
@@ -6,7 +6,7 @@
 from distutils2.tests.support import unittest
 from distutils2.errors import DistutilsSetupError
 
-class CheckTestCase(support.LoggingSilencer,
+class CheckTestCase(support.LoggingCatcher,
 support.TempdirManager,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_clean.py b/src/distutils2/tests/test_clean.py
old mode 100755
new mode 100644
--- a/src/distutils2/tests/test_clean.py
+++ b/src/distutils2/tests/test_clean.py
@@ -8,7 +8,7 @@
 from distutils2.tests.support import unittest
 
 class cleanTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_simple_run(self):
diff --git a/src/distutils2/tests/test_config_cmd.py b/src/distutils2/tests/test_config_cmd.py
--- a/src/distutils2/tests/test_config_cmd.py
+++ b/src/distutils2/tests/test_config_cmd.py
@@ -7,7 +7,7 @@
 from distutils2.tests.support import unittest
 from distutils2 import log
 
-class ConfigTestCase(support.LoggingSilencer,
+class ConfigTestCase(support.LoggingCatcher,
 support.TempdirManager,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_converter.py b/src/distutils2/tests/test_converter.py
deleted file mode 100644
--- a/src/distutils2/tests/test_converter.py
+++ /dev/null
@@ -1,39 +0,0 @@
-"""Tests for distutils.converter."""
-import os
-import sys
-from distutils2.converter import DistutilsRefactoringTool
-from distutils2.tests.support import unittest
-
-_CURDIR = os.path.dirname(__file__)
-
-def _read_file(path):
- # yes, distutils2 is 2.4 compatible, so, no with...
- f = open(path)
- try:
- return f.read()
- finally:
- f.close()
-
-
-class ConverterTestCase(unittest.TestCase):
-
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
- def test_conversions(self):
- # for all XX_before in the conversions/ dir
- # we run the refactoring tool
- ref = DistutilsRefactoringTool()
- convdir = os.path.join(_CURDIR, 'conversions')
- for file_ in os.listdir(convdir):
- if 'after' in file_ or not file_.endswith('py'):
- continue
- original = _read_file(os.path.join(convdir, file_))
- wanted = file_.replace('before', 'after')
- wanted = _read_file(os.path.join(convdir, wanted))
- res = ref.refactor_string(original, 'setup.py')
- self.assertEqual(str(res), wanted)
-
-def test_suite():
- return unittest.makeSuite(ConverterTestCase)
-
-if __name__ == '__main__':
- unittest.main(defaultTest="test_suite")
diff --git a/src/distutils2/tests/test_depgraph.py b/src/distutils2/tests/test_depgraph.py
--- a/src/distutils2/tests/test_depgraph.py
+++ b/src/distutils2/tests/test_depgraph.py
@@ -13,7 +13,7 @@
 except ImportError:
 import StringIO
 
-class DepGraphTestCase(support.LoggingSilencer,
+class DepGraphTestCase(support.LoggingCatcher,
 unittest.TestCase):
 
 DISTROS_DIST = ('choxie', 'grammar', 'towel-stuff')
diff --git a/src/distutils2/tests/test_dist.py b/src/distutils2/tests/test_dist.py
--- a/src/distutils2/tests/test_dist.py
+++ b/src/distutils2/tests/test_dist.py
@@ -4,15 +4,18 @@
 import os
 import StringIO
 import sys
+import warnings
 import textwrap
 
-from distutils2.dist import Distribution, fix_help_options, DistributionMetadata
+import distutils2.dist
+from distutils2.dist import Distribution, fix_help_options
 from distutils2.command.cmd import Command
-import distutils2.dist
+from distutils2.errors import DistutilsModuleError, DistutilsOptionError
 from distutils2.tests import TESTFN, captured_stdout
 from distutils2.tests import support
 from distutils2.tests.support import unittest
 
+
 class test_dist(Command):
 """Sample distutils2 extension command."""
 
@@ -22,7 +25,9 @@
 
 def initialize_options(self):
 self.sample_option = None
- def finalize_options(self): pass
+
+ def finalize_options(self):
+ pass
 
 
 class TestDistribution(Distribution):
@@ -38,7 +43,7 @@
 
 
 class DistributionTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.WarningsCatcher,
 support.EnvironGuard,
 unittest.TestCase):
@@ -63,7 +68,7 @@
 def test_debug_mode(self):
 f = open(TESTFN, "w")
 try:
- f.write("[global]")
+ f.write("[global]\n")
 f.write("command_packages = foo.bar, splat")
 finally:
 f.close()
@@ -104,8 +109,8 @@
 sys.argv.append("build")
 f = open(TESTFN, "w")
 try:
- print >>f, "[global]"
- print >>f, "command_packages = foo.bar, splat"
+ print >> f, "[global]"
+ print >> f, "command_packages = foo.bar, splat"
 f.close()
 d = self.create_distribution([TESTFN])
 self.assertEqual(d.get_command_packages(),
@@ -138,7 +143,6 @@
 'summary': u'Café torréfié',
 'description': u'Héhéhé'})
 
-
 # let's make sure the file can be written
 # with Unicode fields. they are encoded with
 # PKG_INFO_ENCODING
@@ -186,6 +190,7 @@
 
 # Here is an example of how it's used out there: 
 # http://svn.pythonmac.org/py2app/py2app/trunk/doc/index.html#specifying-customizations
+ # index.html#specifying-customizations
 cls = Distribution
 dist = cls(attrs={'author': 'xxx',
 'name': 'xxx',
@@ -218,7 +223,6 @@
 cmds = dist.get_command_packages()
 self.assertEqual(cmds, ['distutils2.command', 'one', 'two'])
 
-
 def test_announce(self):
 # make sure the level is known
 dist = Distribution()
@@ -256,7 +260,7 @@
 os.path.expanduser = old_expander
 
 # make sure --no-user-cfg disables the user cfg file
- self.assertEqual(len(all_files)-1, len(files))
+ self.assertEqual(len(all_files) - 1, len(files))
 
 def test_special_hooks_parsing(self):
 temp_home = self.mkdtemp()
@@ -264,46 +268,67 @@
 os.path.join(temp_home, "config2.cfg")]
 
 # Store two aliased hooks in config files
- self.write_file((temp_home, "config1.cfg"), '[test_dist]\npre-hook.a = type')
- self.write_file((temp_home, "config2.cfg"), '[test_dist]\npre-hook.b = type')
+ self.write_file((temp_home, "config1.cfg"),
+ '[test_dist]\npre-hook.a = type')
+ self.write_file((temp_home, "config2.cfg"),
+ '[test_dist]\npre-hook.b = type')
 
 sys.argv.extend(["--command-packages",
 "distutils2.tests",
 "test_dist"])
- cmd = self.create_distribution(config_files).get_command_obj("test_dist")
+ dist = self.create_distribution(config_files)
+ cmd = dist.get_command_obj("test_dist")
+
 self.assertEqual(cmd.pre_hook, {"a": 'type', "b": 'type'})
 
 
 def test_hooks_get_run(self):
 temp_home = self.mkdtemp()
 config_file = os.path.join(temp_home, "config1.cfg")
+ hooks_module = os.path.join(temp_home, "testhooks.py")
 
- self.write_file((temp_home, "config1.cfg"), textwrap.dedent('''
+ self.write_file(config_file, textwrap.dedent('''
 [test_dist]
- pre-hook.test = distutils2.tests.test_dist.DistributionTestCase.log_pre_call
- post-hook.test = distutils2.tests.test_dist.DistributionTestCase.log_post_call'''))
+ pre-hook.test = testhooks.log_pre_call
+ post-hook.test = testhooks.log_post_call'''))
+
+ self.write_file(hooks_module, textwrap.dedent('''
+ record = []
+
+ def log_pre_call(cmd):
+ record.append('pre-%s' % cmd.get_command_name())
+
+ def log_post_call(cmd):
+ record.append('post-%s' % cmd.get_command_name())
+ '''))
 
 sys.argv.extend(["--command-packages",
 "distutils2.tests",
 "test_dist"])
+
 d = self.create_distribution([config_file])
 cmd = d.get_command_obj("test_dist")
 
 # prepare the call recorders
- record = []
- DistributionTestCase.log_pre_call = staticmethod(lambda _cmd: record.append(('pre', _cmd)))
- DistributionTestCase.log_post_call = staticmethod(lambda _cmd: record.append(('post', _cmd)))
- test_dist.run = lambda _cmd: record.append(('run', _cmd))
- test_dist.finalize_options = lambda _cmd: record.append(('finalize_options', _cmd))
+ sys.path.append(temp_home)
+ from testhooks import record
+
+ self.addCleanup(setattr, cmd, 'run', cmd.run)
+ self.addCleanup(setattr, cmd, 'finalize_options',
+ cmd.finalize_options)
+
+ cmd.run = lambda: record.append('run')
+ cmd.finalize_options = lambda: record.append('finalize')
 
 d.run_command('test_dist')
- self.assertEqual(record, [('finalize_options', cmd),
- ('pre', cmd),
- ('run', cmd),
- ('post', cmd)])
+
+ self.assertEqual(record, ['finalize',
+ 'pre-test_dist',
+ 'run',
+ 'post-test_dist'])
 
 class MetadataTestCase(support.TempdirManager, support.EnvironGuard,
- support.LoggingSilencer, unittest.TestCase):
+ support.LoggingCatcher, unittest.TestCase):
 
 def setUp(self):
 super(MetadataTestCase, self).setUp()
@@ -484,6 +509,7 @@
 self.assertEqual(metadata['obsoletes'], [])
 self.assertEqual(metadata['requires-dist'], ['foo'])
 
+
 def test_suite():
 suite = unittest.TestSuite()
 suite.addTest(unittest.makeSuite(DistributionTestCase))
diff --git a/src/distutils2/tests/test_extension.py b/src/distutils2/tests/test_extension.py
old mode 100755
new mode 100644
diff --git a/src/distutils2/tests/test_install.py b/src/distutils2/tests/test_install.py
--- a/src/distutils2/tests/test_install.py
+++ b/src/distutils2/tests/test_install.py
@@ -25,7 +25,7 @@
 
 class InstallTestCase(support.TempdirManager,
 support.EnvironGuard,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_home_installation_scheme(self):
diff --git a/src/distutils2/tests/test_install_data.py b/src/distutils2/tests/test_install_data.py
--- a/src/distutils2/tests/test_install_data.py
+++ b/src/distutils2/tests/test_install_data.py
@@ -8,7 +8,7 @@
 from distutils2.tests.support import unittest
 
 class InstallDataTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.EnvironGuard,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_install_distinfo.py b/src/distutils2/tests/test_install_distinfo.py
--- a/src/distutils2/tests/test_install_distinfo.py
+++ b/src/distutils2/tests/test_install_distinfo.py
@@ -34,7 +34,7 @@
 
 
 class InstallDistinfoTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.EnvironGuard,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_install_headers.py b/src/distutils2/tests/test_install_headers.py
--- a/src/distutils2/tests/test_install_headers.py
+++ b/src/distutils2/tests/test_install_headers.py
@@ -8,7 +8,7 @@
 from distutils2.tests.support import unittest
 
 class InstallHeadersTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.EnvironGuard,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_install_lib.py b/src/distutils2/tests/test_install_lib.py
--- a/src/distutils2/tests/test_install_lib.py
+++ b/src/distutils2/tests/test_install_lib.py
@@ -16,7 +16,7 @@
 bytecode_support = False
 
 class InstallLibTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 support.EnvironGuard,
 unittest.TestCase):
 
diff --git a/src/distutils2/tests/test_install_scripts.py b/src/distutils2/tests/test_install_scripts.py
--- a/src/distutils2/tests/test_install_scripts.py
+++ b/src/distutils2/tests/test_install_scripts.py
@@ -10,7 +10,7 @@
 
 
 class InstallScriptsTestCase(support.TempdirManager,
- support.LoggingSilencer,
+ support.LoggingCatcher,
 unittest.TestCase):
 
 def test_default_settings(self):
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
@@ -7,11 +7,11 @@
 from distutils2.metadata import (DistributionMetadata, _interpret,
 PKG_INFO_PREFERRED_VERSION)
 from distutils2.tests import run_unittest
-from distutils2.tests.support import unittest, LoggingSilencer
+from distutils2.tests.support import unittest, LoggingCatcher
 from distutils2.errors import (MetadataConflictError,
 MetadataUnrecognizedVersionError)
 
-class DistributionMetadataTestCase(LoggingSilencer, unittest.TestCase):
+class DistributionMetadataTestCase(LoggingCatcher, unittest.TestCase):
 
 def test_instantiation(self):
 PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
diff --git a/src/distutils2/tests/test_register.py b/src/distutils2/tests/test_register.py
--- a/src/distutils2/tests/test_register.py
+++ b/src/distutils2/tests/test_register.py
@@ -167,6 +167,8 @@
 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
diff --git a/src/distutils2/tests/test_sdist.py b/src/distutils2/tests/test_sdist.py
--- a/src/distutils2/tests/test_sdist.py
+++ b/src/distutils2/tests/test_sdist.py
@@ -44,6 +44,7 @@
 """
 
 MANIFEST = """\
+# file GENERATED by distutils, do NOT edit
 README
 inroot.txt
 setup.py
@@ -56,7 +57,7 @@
 somecode%(sep)sdoc.txt
 """
 
-class SDistTestCase(support.TempdirManager, support.LoggingSilencer,
+class SDistTestCase(support.TempdirManager, support.LoggingCatcher,
 support.EnvironGuard, unittest.TestCase):
 
 def setUp(self):
@@ -344,17 +345,76 @@
 archive.close()
 
 def test_get_file_list(self):
+ # make sure MANIFEST is recalculated
 dist, cmd = self.get_cmd()
- cmd.finalize_options()
- cmd.template = os.path.join(self.tmp_dir, 'MANIFEST.in')
- f = open(cmd.template, 'w')
+
+ # filling data_files by pointing files in package_data
+ dist.package_data = {'somecode': ['*.txt']}
+ self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
+ cmd.ensure_finalized()
+ cmd.run()
+
+ f = open(cmd.manifest)
 try:
- f.write('include MANIFEST.in\n')
+ manifest = [line.strip() for line in f.read().split('\n')
+ if line.strip() != '']
 finally:
 f.close()
 
- cmd.get_file_list()
- self.assertIn('MANIFEST.in', cmd.filelist.files)
+ self.assertEquals(len(manifest), 5)
+
+ # adding a file
+ self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#')
+
+ # make sure build_py is reinitinialized, like a fresh run
+ build_py = dist.get_command_obj('build_py')
+ build_py.finalized = False
+ build_py.ensure_finalized()
+
+ cmd.run()
+
+ f = open(cmd.manifest)
+ try:
+ manifest2 = [line.strip() for line in f.read().split('\n')
+ if line.strip() != '']
+ finally:
+ f.close()
+
+ # do we have the new file in MANIFEST ?
+ self.assertEquals(len(manifest2), 6)
+ self.assertIn('doc2.txt', manifest2[-1])
+
+ def test_manifest_marker(self):
+ # check that autogenerated MANIFESTs have a marker
+ dist, cmd = self.get_cmd()
+ cmd.ensure_finalized()
+ cmd.run()
+
+ f = open(cmd.manifest)
+ try:
+ manifest = [line.strip() for line in f.read().split('\n')
+ if line.strip() != '']
+ finally:
+ f.close()
+
+ self.assertEqual(manifest[0],
+ '# file GENERATED by distutils, do NOT edit')
+
+ def test_manual_manifest(self):
+ # check that a MANIFEST without a marker is left alone
+ dist, cmd = self.get_cmd()
+ cmd.ensure_finalized()
+ self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
+ cmd.run()
+
+ f = open(cmd.manifest)
+ try:
+ manifest = [line.strip() for line in f.read().split('\n')
+ if line.strip() != '']
+ finally:
+ f.close()
+
+ self.assertEqual(manifest, ['README.manual'])
 
 def test_suite():
 return unittest.makeSuite(SDistTestCase)
diff --git a/src/distutils2/tests/test_upload.py b/src/distutils2/tests/test_upload.py
--- a/src/distutils2/tests/test_upload.py
+++ b/src/distutils2/tests/test_upload.py
@@ -41,7 +41,7 @@
 
 
 class UploadTestCase(support.TempdirManager, support.EnvironGuard,
- PyPIServerTestCase):
+ support.LoggingCatcher, PyPIServerTestCase):
 
 def setUp(self):
 super(UploadTestCase, self).setUp()
diff --git a/src/distutils2/tests/test_upload_docs.py b/src/distutils2/tests/test_upload_docs.py
--- a/src/distutils2/tests/test_upload_docs.py
+++ b/src/distutils2/tests/test_upload_docs.py
@@ -53,7 +53,7 @@
 """
 
 class UploadDocsTestCase(support.TempdirManager, support.EnvironGuard,
- PyPIServerTestCase):
+ support.LoggingCatcher, PyPIServerTestCase):
 
 def setUp(self):
 super(UploadDocsTestCase, self).setUp()
diff --git a/src/distutils2/tests/test_util.py b/src/distutils2/tests/test_util.py
--- a/src/distutils2/tests/test_util.py
+++ b/src/distutils2/tests/test_util.py
@@ -343,9 +343,13 @@
 self.assertEqual(set(res), set(['pkg1', 'pkg5', 'pkg1.pkg3', 'pkg1.pkg3.pkg6']))
 
 def test_resolve_name(self):
- self.assertEqual(UtilTestCase, resolve_name("distutils2.tests.test_util.UtilTestCase"))
- self.assertEqual(UtilTestCase.test_resolve_name,
- resolve_name("distutils2.tests.test_util.UtilTestCase.test_resolve_name"))
+ self.assertEqual(str(42), resolve_name('__builtin__.str')(42))
+ self.assertEqual(
+ UtilTestCase.__name__,
+ resolve_name("distutils2.tests.test_util.UtilTestCase").__name__)
+ self.assertEqual(
+ UtilTestCase.test_resolve_name.__name__,
+ resolve_name("distutils2.tests.test_util.UtilTestCase.test_resolve_name").__name__)
 
 self.assertRaises(ImportError, resolve_name,
 "distutils2.tests.test_util.UtilTestCaseNot")
diff --git a/src/distutils2/util.py b/src/distutils2/util.py
--- a/src/distutils2/util.py
+++ b/src/distutils2/util.py
@@ -637,7 +637,10 @@
 return packages
 
 def resolve_name(name):
- """Resolve a name like ``module.object`` to an object and return it."""
+ """Resolve a name like ``module.object`` to an object and return it.
+
+ Raise ImportError if the module or name is not found.
+ """
 parts = name.split('.')
 cursor = len(parts)
 module_name, rest = parts[:cursor], parts[cursor:]
@@ -652,62 +655,16 @@
 cursor -= 1
 module_name = parts[:cursor]
 rest = parts[cursor:]
+ ret = ''
 
 for part in parts[1:]:
 try:
 ret = getattr(ret, part)
 except AttributeError:
 raise ImportError
+
 return ret
 
-# utility functions for 2to3 support
-
-def run_2to3(files, doctests_only=False, fixer_names=None, options=None,
- explicit=None):
- """ Wrapper function around the refactor() class which
- performs the conversions on a list of python files.
- Invoke 2to3 on a list of Python files. The files should all come
- from the build area, as the modification is done in-place."""
-
- if not files:
- return
-
- # Make this class local, to delay import of 2to3
- from lib2to3.refactor import get_fixers_from_package
- from distutils2.converter.refactor import DistutilsRefactoringTool
-
- if fixer_names is None:
- fixer_names = get_fixers_from_package('lib2to3.fixes')
-
- r = DistutilsRefactoringTool(fixer_names, options=options)
- if doctests_only:
- r.refactor(files, doctests_only=True, write=True)
- else:
- r.refactor(files, write=True)
-
-
-class Mixin2to3:
- """ Wrapper class for commands that run 2to3.
- To configure 2to3, setup scripts may either change
- the class variables, or inherit from this class
- to override how 2to3 is invoked.
- """
- # provide list of fixers to run.
- # defaults to all from lib2to3.fixers
- fixer_names = None
-
- # options dictionary
- options = None
-
- # list of fixers to invoke even though they are marked as explicit
- explicit = None
-
- def run_2to3(self, files, doctests_only=False):
- """ Issues a call to util.run_2to3. """
- return run_2to3(files, doctests_only, self.fixer_names,
- self.options, self.explicit)
-
-
 def splitext(path):
 """Like os.path.splitext, but take off .tar too"""
 base, ext = posixpath.splitext(path)
@@ -757,7 +714,7 @@
 os.makedirs(location)
 if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'):
 mode = 'r:gz'
- elif (filename.lower().endswith('.bz2') 
+ elif (filename.lower().endswith('.bz2')
 or filename.lower().endswith('.tbz')):
 mode = 'r:bz2'
 elif filename.lower().endswith('.tar'):
@@ -1122,3 +1079,51 @@
 data['obsoletes'] = meta['Obsoletes']
 
 return data
+
+# utility functions for 2to3 support
+
+def run_2to3(files, doctests_only=False, fixer_names=None, options=None,
+ explicit=None):
+ """ Wrapper function around the refactor() class which
+ performs the conversions on a list of python files.
+ Invoke 2to3 on a list of Python files. The files should all come
+ from the build area, as the modification is done in-place."""
+
+ #if not files:
+ # return
+
+ # Make this class local, to delay import of 2to3
+ from lib2to3.refactor import get_fixers_from_package, RefactoringTool
+ fixers = []
+ fixers = get_fixers_from_package('lib2to3.fixes')
+
+
+ if fixer_names:
+ for fixername in fixer_names:
+ fixers.extend([fixer for fixer in get_fixers_from_package(fixername)])
+ r = RefactoringTool(fixers, options=options)
+ if doctests_only:
+ r.refactor(files, doctests_only=True, write=True)
+ else:
+ r.refactor(files, write=True)
+
+class Mixin2to3:
+ """ Wrapper class for commands that run 2to3.
+ To configure 2to3, setup scripts may either change
+ the class variables, or inherit from this class
+ to override how 2to3 is invoked.
+ """
+ # provide list of fixers to run.
+ # defaults to all from lib2to3.fixers
+ fixer_names = None
+
+ # options dictionary
+ options = None
+
+ # list of fixers to invoke even though they are marked as explicit
+ explicit = None
+
+ def run_2to3(self, files, doctests_only=False):
+ """ Issues a call to util.run_2to3. """
+ return run_2to3(files, doctests_only, self.fixer_names,
+ self.options, self.explicit)
diff --git a/src/runtests-cov.py b/src/runtests-cov.py
old mode 100755
new mode 100644
--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list

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