diff options
| author | ?ric Araujo <merwok@netwok.org> | 2012-02-09 21:05:47 +0100 |
|---|---|---|
| committer | ?ric Araujo <merwok@netwok.org> | 2012-02-09 21:05:47 +0100 |
| commit | ce3d2240908c84bbe7b9762b09ba3ffcfe44e7a5 (patch) | |
| tree | a14fae0ba4ac5a3a18ba741abb1edf8a699936ce | |
| parent | 08fd2b17458378aa59677e439a9fc69f38147061 (diff) | |
| parent | 90b039c8d93fe3fb157fc4fe5bb47265dd8a4399 (diff) | |
| download | disutils2-ce3d2240908c84bbe7b9762b09ba3ffcfe44e7a5.tar.gz | |
Merge fixes for #13462 and others from default
24 files changed, 184 insertions, 266 deletions
diff --git a/distutils2/command/__init__.py b/distutils2/command/__init__.py index 5bbdb82..774a424 100644 --- a/distutils2/command/__init__.py +++ b/distutils2/command/__init__.py @@ -6,38 +6,28 @@ from distutils2.util import resolve_name __all__ = ['get_command_names', 'set_command', 'get_command_class', 'STANDARD_COMMANDS'] -_COMMANDS = { - 'check': 'distutils2.command.check.check', - 'test': 'distutils2.command.test.test', - 'build': 'distutils2.command.build.build', - 'build_py': 'distutils2.command.build_py.build_py', - 'build_ext': 'distutils2.command.build_ext.build_ext', - 'build_clib': 'distutils2.command.build_clib.build_clib', - 'build_scripts': 'distutils2.command.build_scripts.build_scripts', - 'clean': 'distutils2.command.clean.clean', - 'install_dist': 'distutils2.command.install_dist.install_dist', - 'install_lib': 'distutils2.command.install_lib.install_lib', - 'install_headers': 'distutils2.command.install_headers.install_headers', - 'install_scripts': 'distutils2.command.install_scripts.install_scripts', - 'install_data': 'distutils2.command.install_data.install_data', - 'install_distinfo': - 'distutils2.command.install_distinfo.install_distinfo', - 'sdist': 'distutils2.command.sdist.sdist', - 'bdist': 'distutils2.command.bdist.bdist', - 'bdist_dumb': 'distutils2.command.bdist_dumb.bdist_dumb', - 'bdist_wininst': 'distutils2.command.bdist_wininst.bdist_wininst', - 'register': 'distutils2.command.register.register', - 'upload': 'distutils2.command.upload.upload', - 'upload_docs': 'distutils2.command.upload_docs.upload_docs', -} - -# XXX this is crappy + +STANDARD_COMMANDS = [ + # packaging + 'check', 'test', + # building + 'build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', + # installing + 'install_dist', 'install_lib', 'install_headers', 'install_scripts', + 'install_data', 'install_distinfo', + # distributing + 'sdist', 'bdist', 'bdist_dumb', 'bdist_wininst', + 'register', 'upload', 'upload_docs', + ] + if os.name == 'nt': - _COMMANDS['bdist_msi'] = 'distutils2.command.bdist_msi.bdist_msi' + STANDARD_COMMANDS.insert(STANDARD_COMMANDS.index('bdist_wininst'), + 'bdist_msi') -# XXX use OrderedDict to preserve the grouping (build-related, install-related, -# distribution-related) -STANDARD_COMMANDS = set(_COMMANDS) +# XXX maybe we need more than one registry, so that --list-comands can display +# standard, custom and overriden standard commands differently +_COMMANDS = dict((name, 'distutils2.command.%s.%s' % (name, name)) + for name in STANDARD_COMMANDS) def get_command_names(): diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py index 43fbe66..ddbc61f 100644 --- a/distutils2/command/bdist_msi.py +++ b/distutils2/command/bdist_msi.py @@ -203,7 +203,7 @@ class bdist_msi(Command): target_version = self.target_version if not target_version: assert self.skip_build, "Should have already checked this" - target_version = sys.version[0:3] + target_version = '%s.%s' % sys.version_info[:2] plat_specifier = ".%s-%s" % (self.plat_name, target_version) build = self.get_finalized_command('build') build.build_lib = os.path.join(build.build_base, diff --git a/distutils2/command/bdist_wininst.py b/distutils2/command/bdist_wininst.py index 4eab6bc..8de798e 100644 --- a/distutils2/command/bdist_wininst.py +++ b/distutils2/command/bdist_wininst.py @@ -136,7 +136,7 @@ class bdist_wininst(Command): target_version = self.target_version if not target_version: assert self.skip_build, "Should have already checked this" - target_version = sys.version[0:3] + target_version = '%s.%s' % sys.version_info[:2] plat_specifier = ".%s-%s" % (self.plat_name, target_version) build = self.get_finalized_command('build') build.build_lib = os.path.join(build.build_base, diff --git a/distutils2/command/build.py b/distutils2/command/build.py index 708b848..d4ace38 100644 --- a/distutils2/command/build.py +++ b/distutils2/command/build.py @@ -82,8 +82,8 @@ class build(Command): raise PackagingOptionError( "--plat-name only supported on Windows (try " "using './configure --help' on your platform)") - - plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3]) + pyversion = '%s.%s' % sys.version_info[:2] + plat_specifier = ".%s-%s" % (self.plat_name, pyversion) # Make it so Python 2.x and Python 2.x with --with-pydebug don't # share the same build directories. Doing so confuses the build @@ -116,7 +116,7 @@ class build(Command): 'temp' + plat_specifier) if self.build_scripts is None: self.build_scripts = os.path.join(self.build_base, - 'scripts-' + sys.version[0:3]) + 'scripts-' + pyversion) if self.executable is None: self.executable = os.path.normpath(sys.executable) diff --git a/distutils2/command/install_dist.py b/distutils2/command/install_dist.py index 8d8b675..3dc481c 100644 --- a/distutils2/command/install_dist.py +++ b/distutils2/command/install_dist.py @@ -242,7 +242,7 @@ class install_dist(Command): # $platbase in the other installation directories and not worry # about needing recursive variable expansion (shudder). - py_version = sys.version.split()[0] + py_version = '%s.%s' % sys.version_info[:2] prefix, exec_prefix, srcdir, projectbase = get_config_vars( 'prefix', 'exec_prefix', 'srcdir', 'projectbase') diff --git a/distutils2/compat.py b/distutils2/compat.py index bcd4f0f..7e4e9e2 100644 --- a/distutils2/compat.py +++ b/distutils2/compat.py @@ -25,7 +25,7 @@ class Mixin2to3(_KLASS): """ if _CONVERT: - def _run_2to3(self, files, doctests=[], fixers=[]): + 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. @@ -35,17 +35,16 @@ class Mixin2to3(_KLASS): if fixers: self.fixer_names = fixers - logger.info('converting Python code') - _KLASS.run_2to3(self, files) + if files: + logger.info('converting Python code and doctests') + _KLASS.run_2to3(self, files) + _KLASS.run_2to3(self, files, doctests_only=True) - logger.info('converting doctests in Python files') - _KLASS.run_2to3(self, files, doctests_only=True) - - if doctests != []: - logger.info('converting doctest in text files') + if doctests: + logger.info('converting doctests in text files') _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=[]): + def _run_2to3(self, files=[], doctests=[], fixers=[]): pass diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py index 9ee775c..71a16a7 100644 --- a/distutils2/compiler/cygwinccompiler.py +++ b/distutils2/compiler/cygwinccompiler.py @@ -56,6 +56,10 @@ from distutils2.errors import PackagingExecError, CompileError, UnknownFileError from distutils2.util import get_compiler_versions from distutils2._backport import sysconfig +# TODO use platform instead of sys.version +# (platform does unholy sys.version parsing too, but at least it gives other +# VMs a chance to override the returned values) + def get_msvcr(): """Include the appropriate MSVC runtime library if Python was built diff --git a/distutils2/markers.py b/distutils2/markers.py index 5fb7027..63fdc19 100644 --- a/distutils2/markers.py +++ b/distutils2/markers.py @@ -26,7 +26,9 @@ def _operate(operation, x, y): # restricted set of variables _VARS = {'sys.platform': sys.platform, - 'python_version': sys.version[:3], + 'python_version': '%s.%s' % sys.version_info[:2], + # FIXME parsing sys.platform is not reliable, but there is no other + # way to get e.g. 2.7.2+, and the PEP is defined with sys.version 'python_full_version': sys.version.split(' ', 1)[0], 'os.name': os.name, 'platform.version': platform.version(), diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py index 5e0b02e..02938ac 100644 --- a/distutils2/pypi/simple.py +++ b/distutils2/pypi/simple.py @@ -35,8 +35,8 @@ __all__ = ['Crawler', 'DEFAULT_SIMPLE_INDEX_URL'] DEFAULT_SIMPLE_INDEX_URL = "http://a.pypi.python.org/simple/" DEFAULT_HOSTS = ("*",) SOCKET_TIMEOUT = 15 -USER_AGENT = "Python-urllib/%s distutils2/%s" % ( - sys.version[:3], distutils2_version) +USER_AGENT = "Python-urllib/%s.%s distutils2/%s" % ( + sys.version_info[0], sys.version_info[1], distutils2_version) # -- Regexps ------------------------------------------------- EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$') diff --git a/distutils2/run.py b/distutils2/run.py index e2529bb..3553fc9 100644 --- a/distutils2/run.py +++ b/distutils2/run.py @@ -255,16 +255,13 @@ def _run(dispatcher, args, **kw): parser = dispatcher.parser args = args[1:] - commands = STANDARD_COMMANDS # + extra commands + commands = STANDARD_COMMANDS # FIXME display extra commands if args == ['--list-commands']: print('List of available commands:') - cmds = sorted(commands) - - for cmd in cmds: + for cmd in commands: cls = dispatcher.cmdclass.get(cmd) or get_command_class(cmd) - desc = getattr(cls, 'description', - '(no description available)') + desc = getattr(cls, 'description', '(no description available)') print(' %s: %s' % (cmd, desc)) return diff --git a/distutils2/tests/fixer/fix_echo.py b/distutils2/tests/fixer/fix_echo.py new file mode 100644 index 0000000..8daae3e --- /dev/null +++ b/distutils2/tests/fixer/fix_echo.py @@ -0,0 +1,16 @@ +# Example custom fixer, derived from fix_raw_input by Andre Roberge + +from lib2to3 import fixer_base +from lib2to3.fixer_util import Name + + +class FixEcho(fixer_base.BaseFix): + + BM_compatible = True + PATTERN = """ + power< name='echo' trailer< '(' [any] ')' > any* > + """ + + def transform(self, node, results): + name = results['name'] + name.replace(Name('print', prefix=name.prefix)) diff --git a/distutils2/tests/fixer/fix_echo2.py b/distutils2/tests/fixer/fix_echo2.py new file mode 100644 index 0000000..1b92891 --- /dev/null +++ b/distutils2/tests/fixer/fix_echo2.py @@ -0,0 +1,16 @@ +# Example custom fixer, derived from fix_raw_input by Andre Roberge + +from lib2to3 import fixer_base +from lib2to3.fixer_util import Name + + +class FixEcho2(fixer_base.BaseFix): + + BM_compatible = True + PATTERN = """ + power< name='echo2' trailer< '(' [any] ')' > any* > + """ + + def transform(self, node, results): + name = results['name'] + name.replace(Name('print', prefix=name.prefix)) diff --git a/distutils2/tests/fixer/fix_idioms.py b/distutils2/tests/fixer/fix_idioms.py deleted file mode 100644 index 759a377..0000000 --- a/distutils2/tests/fixer/fix_idioms.py +++ /dev/null @@ -1,134 +0,0 @@ -"""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.prefix = "" - T.prefix = " " - test = Call(Name("isinstance"), [x, Comma(), T]) - if "n" in results: - test.prefix = " " - test = Node(syms.not_test, [Name("not"), test]) - test.prefix = getattr(node, 'prefix', ' ') - return test - - def transform_while(self, node, results): - one = results["while"] - one.replace(Name("True", prefix=one.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.prefix)) - elif simple_expr: - new = simple_expr.clone() - new.prefix = "" - simple_expr.replace(Call(Name("sorted"), [new], - prefix=simple_expr.prefix)) - else: - raise RuntimeError("should not have reached here") - sort_stmt.remove() - if next_stmt: - next_stmt[0].prefix = sort_stmt._prefix diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py index ec8a694..bbc643a 100644 --- a/distutils2/tests/support.py +++ b/distutils2/tests/support.py @@ -62,8 +62,9 @@ __all__ = [ # misc. functions and decorators 'fake_dec', 'create_distribution', 'use_command', 'copy_xxmodule_c', 'fixup_build_ext', + 'skip_2to3_optimize', # imported from this module for backport purposes - 'unittest', 'requires_zlib', 'skip_2to3_optimize', 'skip_unless_symlink', + 'unittest', 'requires_zlib', 'skip_unless_symlink', ] @@ -361,16 +362,13 @@ def fixup_build_ext(cmd): need their debug attribute set, and it is not done automatically for some reason. - This function handles both of these things. Example use: + This function handles both of these things, and also fixes + cmd.distribution.include_dirs if the running Python is an uninstalled + build. Example use: cmd = build_ext(dist) support.fixup_build_ext(cmd) cmd.ensure_finalized() - - In addition, this function also fixes cmd.distribution.include_dirs if - the running Python is an uninstalled Python 3.3. (This fix is not done in - packaging, which does not need it, nor in distutils2 for Python 2, which - has no in-development version that can't be expected to be installed.) """ if os.name == 'nt': cmd.debug = sys.executable.endswith('_d.exe') @@ -389,8 +387,8 @@ def fixup_build_ext(cmd): name, equals, value = runshared.partition('=') cmd.library_dirs = value.split(os.pathsep) - # Allow tests to run with an uninstalled Python 3.3 - if sys.version_info[:2] == (3, 3) and sysconfig.is_python_build(): + # Allow tests to run with an uninstalled Python + if sysconfig.is_python_build(): pysrcdir = sysconfig.get_config_var('projectbase') cmd.distribution.include_dirs.append(os.path.join(pysrcdir, 'Include')) @@ -401,11 +399,9 @@ except ImportError: skip_unless_symlink = unittest.skip( 'requires test.support.skip_unless_symlink') - skip_2to3_optimize = unittest.skipIf(sys.flags.optimize, "2to3 doesn't work under -O") - requires_zlib = unittest.skipUnless(zlib, 'requires zlib') diff --git a/distutils2/tests/test_command_bdist_dumb.py b/distutils2/tests/test_command_bdist_dumb.py index f77e279..2196139 100644 --- a/distutils2/tests/test_command_bdist_dumb.py +++ b/distutils2/tests/test_command_bdist_dumb.py @@ -65,7 +65,7 @@ class BuildDumbTestCase(support.TempdirManager, finally: fp.close - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): pyc = 'foo.pyc' else: pyc = 'foo.%s.pyc' % imp.get_tag() diff --git a/distutils2/tests/test_command_build.py b/distutils2/tests/test_command_build.py index 08bef58..3a926cd 100644 --- a/distutils2/tests/test_command_build.py +++ b/distutils2/tests/test_command_build.py @@ -26,7 +26,8 @@ class BuildTestCase(support.TempdirManager, # build_platlib is 'build/lib.platform-x.x[-pydebug]' # examples: # build/lib.macosx-10.3-i386-2.7 - plat_spec = '.%s-%s' % (cmd.plat_name, sys.version[0:3]) + pyversion = '%s.%s' % sys.version_info[:2] + plat_spec = '.%s-%s' % (cmd.plat_name, pyversion) if hasattr(sys, 'gettotalrefcount'): self.assertTrue(cmd.build_platlib.endswith('-pydebug')) plat_spec += '-pydebug' @@ -41,7 +42,7 @@ class BuildTestCase(support.TempdirManager, self.assertEqual(cmd.build_temp, wanted) # build_scripts is build/scripts-x.x - wanted = os.path.join(cmd.build_base, 'scripts-' + sys.version[0:3]) + wanted = os.path.join(cmd.build_base, 'scripts-' + pyversion) self.assertEqual(cmd.build_scripts, wanted) # executable is os.path.normpath(sys.executable) diff --git a/distutils2/tests/test_command_build_py.py b/distutils2/tests/test_command_build_py.py index 90a8720..b6b7fd8 100644 --- a/distutils2/tests/test_command_build_py.py +++ b/distutils2/tests/test_command_build_py.py @@ -69,12 +69,12 @@ class BuildPyTestCase(support.TempdirManager, pkgdest = os.path.join(destination, "pkg") files = os.listdir(pkgdest) wanted = ["__init__.py", "HACKING.txt", "README.txt"] - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): wanted.append("__init__.pyc") else: wanted.append("__pycache__") self.assertEqual(sorted(files), sorted(wanted)) - if sys.version_info[1] >= 2: + if sys.version_info[:2] >= (3, 2): pycache_dir = os.path.join(pkgdest, "__pycache__") pyc_files = os.listdir(pycache_dir) self.assertEqual(["__init__.%s.pyc" % imp.get_tag()], pyc_files) @@ -113,7 +113,7 @@ class BuildPyTestCase(support.TempdirManager, cmd.run() found = os.listdir(cmd.build_lib) - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): self.assertEqual(sorted(found), ['boiledeggs.py', 'boiledeggs.pyc']) else: @@ -133,7 +133,7 @@ class BuildPyTestCase(support.TempdirManager, cmd.run() found = os.listdir(cmd.build_lib) - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): self.assertEqual(sorted(found), ['boiledeggs.py', 'boiledeggs.pyc', 'boiledeggs.pyo']) else: diff --git a/distutils2/tests/test_command_install_dist.py b/distutils2/tests/test_command_install_dist.py index 597e10a..079d3cf 100644 --- a/distutils2/tests/test_command_install_dist.py +++ b/distutils2/tests/test_command_install_dist.py @@ -197,7 +197,7 @@ class InstallTestCase(support.TempdirManager, with open(cmd.record) as f: content = f.read() - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): pyc = 'hello.pyc' else: pyc = 'hello.%s.pyc' % imp.get_tag() diff --git a/distutils2/tests/test_command_install_lib.py b/distutils2/tests/test_command_install_lib.py index 160e62e..fcc28c4 100644 --- a/distutils2/tests/test_command_install_lib.py +++ b/distutils2/tests/test_command_install_lib.py @@ -44,7 +44,7 @@ class InstallLibTestCase(support.TempdirManager, f = os.path.join(project_dir, 'foo.py') self.write_file(f, '# python file') cmd.byte_compile([f]) - if sys.version_info[1] == 1: + if sys.version_info[:2] == (3, 1): pyc_file = 'foo.pyc' pyo_file = 'foo.pyo' else: diff --git a/distutils2/tests/test_markers.py b/distutils2/tests/test_markers.py index 0e8b74e..872f54b 100644 --- a/distutils2/tests/test_markers.py +++ b/distutils2/tests/test_markers.py @@ -21,8 +21,6 @@ class MarkersTestCase(LoggingCatcher, self.assertTrue(interpret("sys.platform == '%s'" % sys_platform)) self.assertTrue(interpret( - "sys.platform == '%s' or python_version == '2.4'" % sys_platform)) - self.assertTrue(interpret( "sys.platform == '%s' and python_full_version == '%s'" % (sys_platform, version))) self.assertTrue(interpret("'%s' == sys.platform" % sys_platform)) @@ -41,12 +39,18 @@ class MarkersTestCase(LoggingCatcher, # combined operations OP = 'os.name == "%s"' % os_name + FALSEOP = 'os.name == "buuuu"' AND = ' and ' OR = ' or ' self.assertTrue(interpret(OP + AND + OP)) self.assertTrue(interpret(OP + AND + OP + AND + OP)) self.assertTrue(interpret(OP + OR + OP)) - self.assertTrue(interpret(OP + OR + OP + OR + OP)) + self.assertTrue(interpret(OP + OR + FALSEOP)) + self.assertTrue(interpret(OP + OR + OP + OR + FALSEOP)) + self.assertTrue(interpret(OP + OR + FALSEOP + OR + FALSEOP)) + self.assertTrue(interpret(FALSEOP + OR + OP)) + self.assertFalse(interpret(FALSEOP + AND + FALSEOP)) + self.assertFalse(interpret(FALSEOP + OR + FALSEOP)) # other operators self.assertTrue(interpret("os.name != 'buuuu'")) diff --git a/distutils2/tests/test_mixin2to3.py b/distutils2/tests/test_mixin2to3.py index 76e14d6..3b5be04 100644 --- a/distutils2/tests/test_mixin2to3.py +++ b/distutils2/tests/test_mixin2to3.py @@ -8,70 +8,76 @@ class Mixin2to3TestCase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): - @support.skip_2to3_optimize - def test_convert_code_only(self): - # used to check if code gets converted properly. - code = "print 'test'" + def setUp(self): + super(Mixin2to3TestCase, self).setUp() + self.filename = self.mktempfile().name - with self.mktempfile() as fp: - fp.write(code) + def check(self, source, wanted, **kwargs): + source = textwrap.dedent(source) + with open(self.filename, 'w') as fp: + fp.write(source) - mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([fp.name]) - expected = "print('test')" + Mixin2to3()._run_2to3(**kwargs) - with open(fp.name) as fp: + wanted = textwrap.dedent(wanted) + with open(self.filename) as fp: converted = fp.read() + self.assertMultiLineEqual(converted, wanted) - self.assertEqual(expected, converted) - - def test_doctests_only(self): - # used to check if doctests gets converted properly. - doctest = textwrap.dedent('''\ + def test_conversion(self): + # check that code and doctests get converted + self.check('''\ """Example docstring. >>> print test test It works. - """''') - - with self.mktempfile() as fp: - fp.write(doctest) - - mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([fp.name]) - expected = textwrap.dedent('''\ + """ + print 'test' + ''', + '''\ """Example docstring. >>> print(test) test It works. - """\n''') + """ + print('test') - with open(fp.name) as fp: - converted = fp.read() - - self.assertEqual(expected, converted) - - def test_additional_fixers(self): - # used to check if use_2to3_fixers works - code = 'type(x) is not T' + ''', # 2to3 adds a newline here + files=[self.filename]) - with self.mktempfile() as fp: - fp.write(code) + def test_doctests_conversion(self): + # check that doctest files are converted + self.check('''\ + Welcome to the doc. - mixin2to3 = Mixin2to3() - mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name], - fixers=['distutils2.tests.fixer']) + >>> print test + test + ''', + '''\ + Welcome to the doc. - expected = 'not isinstance(x, T)' + >>> print(test) + test - with open(fp.name) as fp: - converted = fp.read() + ''', + doctests=[self.filename]) - self.assertEqual(expected, converted) + def test_additional_fixers(self): + # make sure the fixers argument works + self.check("""\ + echo('42') + echo2('oh no') + """, + """\ + print('42') + print('oh no') + """, + files=[self.filename], + fixers=['distutils2.tests.fixer']) def test_suite(): diff --git a/distutils2/tests/test_pypi_simple.py b/distutils2/tests/test_pypi_simple.py index 70c3ba3..196f8ec 100644 --- a/distutils2/tests/test_pypi_simple.py +++ b/distutils2/tests/test_pypi_simple.py @@ -87,7 +87,7 @@ class SimpleCrawlerTestCase(TempdirManager, try: crawler._open_url(url) except Exception as v: - if sys.version_info[:2] < (3, 2, 3): + if sys.version_info[:3] < (3, 2, 3): # XXX check versions again wanted = 'nonnumeric port' else: wanted = 'Download error' diff --git a/distutils2/tests/test_run.py b/distutils2/tests/test_run.py index 7433731..d8730fc 100644 --- a/distutils2/tests/test_run.py +++ b/distutils2/tests/test_run.py @@ -60,21 +60,42 @@ class RunTestCase(support.TempdirManager, os.chmod(install_path, old_mod) install.get_path = old_get_path - def test_show_help(self): - # smoke test, just makes sure some help is displayed + def get_pythonpath(self): pythonpath = os.environ.get('PYTHONPATH') d2parent = os.path.dirname(os.path.dirname(__file__)) if pythonpath is not None: pythonpath = os.pathsep.join((pythonpath, d2parent)) else: pythonpath = d2parent + return pythonpath + + def test_show_help(self): + # smoke test, just makes sure some help is displayed + status, out, err = assert_python_ok( + '-m', 'distutils2.run', '--help', + PYTHONPATH=self.get_pythonpath()) + self.assertEqual(status, 0) + self.assertGreater(out, b'') + self.assertEqual(err, b'') - status, out, err = assert_python_ok('-m', 'distutils2.run', '--help', - PYTHONPATH=pythonpath) + def test_list_commands(self): + status, out, err = assert_python_ok( + '-m', 'distutils2.run', 'run', + '--list-commands', PYTHONPATH=self.get_pythonpath()) + # check that something is displayed self.assertEqual(status, 0) self.assertGreater(out, b'') self.assertEqual(err, b'') + # make sure the manual grouping of commands is respected + check_position = out.find(b' check: ') + build_position = out.find(b' build: ') + self.assertTrue(check_position, out) # "out" printed as debugging aid + self.assertTrue(build_position, out) + self.assertLess(check_position, build_position, out) + + # TODO test that custom commands don't break --list-commands + def test_suite(): return unittest.makeSuite(RunTestCase) diff --git a/distutils2/util.py b/distutils2/util.py index 06e94ec..83f211a 100644 --- a/distutils2/util.py +++ b/distutils2/util.py @@ -853,13 +853,11 @@ def run_2to3(files, doctests_only=False, fixer_names=None, # 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)) + fixers.extend(get_fixers_from_package(fixername)) r = RefactoringTool(fixers, options=options) r.refactor(files, write=True, doctests_only=doctests_only) @@ -870,21 +868,23 @@ class Mixin2to3: 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 + # list of fixers to run; defaults to all implicit from lib2to3.fixers fixer_names = None - - # options dictionary + # dict of options options = None - - # list of fixers to invoke even though they are marked as explicit + # list of extra fixers to invoke explicit = None + # TODO need a better way to add just one fixer from a package + # TODO need a way to exclude individual fixers 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) + # TODO provide initialize/finalize_options + + RICH_GLOB = re.compile(r'\{([^}]*)\}') _CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') _CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') |
