[Python-checkins] distutils2: Making sure the code works on all Python versions.
tarek.ziade
python-checkins at python.org
Sun Jul 4 11:16:45 CEST 2010
tarek.ziade pushed f696d39e9e86 to distutils2:
http://hg.python.org/distutils2/rev/f696d39e9e86
changeset: 256:f696d39e9e86
tag: tip
user: Tarek Ziade <tarek at ziade.org>
date: Sun Jul 04 11:16:37 2010 +0200
summary: Making sure the code works on all Python versions.
files: src/distutils2/command/build_py.py, src/distutils2/tests/support.py, src/distutils2/tests/test_Mixin2to3.py, src/distutils2/tests/test_util.py, src/distutils2/util.py
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
@@ -28,14 +28,14 @@
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.
+ 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.
+ 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.
@@ -53,7 +53,7 @@
# 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
+ # containing doctests. It is set as
# distutils2.run_2to3_on_doctests
if doctests != [] and distutils2.run_2to3_on_doctests:
@@ -258,8 +258,8 @@
if os.path.isfile(init_py):
return init_py
else:
- log.warn(("package init file '%s' not found " +
- "(or not a regular file)"), init_py)
+ logging.warning(("package init file '%s' not found " +
+ "(or not a regular file)"), init_py)
# Either not in a package at all (__init__.py not expected), or
# __init__.py doesn't exist -- so don't return the filename.
@@ -267,7 +267,8 @@
def check_module(self, module, module_file):
if not os.path.isfile(module_file):
- log.warn("file %s (for module %s) not found", module_file, module)
+ logging.warning("file %s (for module %s) not found",
+ module_file, module)
return False
else:
return True
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
@@ -64,12 +64,22 @@
def setUp(self):
super(TempdirManager, self).setUp()
self.tempdirs = []
+ self.tempfiles = []
def tearDown(self):
super(TempdirManager, self).tearDown()
while self.tempdirs:
d = self.tempdirs.pop()
shutil.rmtree(d, os.name in ('nt', 'cygwin'))
+ for file_ in self.tempfiles:
+ if os.path.exists(file_):
+ os.remove(file_)
+
+ def mktempfile(self):
+ """Create a temporary file that will be cleaned up."""
+ tempfile_ = tempfile.NamedTemporaryFile()
+ self.tempfiles.append(tempfile_.name)
+ return tempfile_
def mkdtemp(self):
"""Create a temporary directory that will be cleaned up.
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,32 +1,37 @@
"""Tests for distutils.command.build_py."""
+import sys
+import tempfile
-import tempfile
import distutils2
from distutils2.tests import support
from distutils2.tests.support import unittest
from distutils2.command.build_py import Mixin2to3
-class Mixin2to3TestCase(unittest.TestCase):
+
+class Mixin2to3TestCase(support.TempdirManager, unittest.TestCase):
+
+ @unittest.skipUnless(sys.version > '2.6', 'Need >= 2.6')
def test_convert_code_only(self):
# used to check if code gets converted properly.
code_content = "print 'test'\n"
- code_handle = tempfile.NamedTemporaryFile(delete=True)
+ code_handle = self.mktempfile()
code_name = code_handle.name
code_handle.write(code_content)
code_handle.flush()
- mixin2to3 = Mixin2to3()
+ mixin2to3 = Mixin2to3()
mixin2to3._run_2to3([code_name])
converted_code_content = "print('test')\n"
new_code_content = "".join(open(code_name).readlines())
self.assertEquals(new_code_content, converted_code_content)
+ @unittest.skipUnless(sys.version > '2.6', 'Need >= 2.6')
def test_doctests_only(self):
# used to check if doctests gets converted properly.
doctest_content = '"""\n>>> print test\ntest\n"""\nprint test\n\n'
- doctest_handle = tempfile.NamedTemporaryFile(delete=True)
+ doctest_handle = self.mktempfile()
doctest_name = doctest_handle.name
doctest_handle.write(doctest_content)
@@ -35,7 +40,9 @@
mixin2to3 = Mixin2to3()
mixin2to3._run_2to3([doctest_name])
- converted_doctest_content = '"""\n>>> print(test)\ntest\n"""\nprint(test)\n\n\n'
+ converted_doctest_content = ['"""', '>>> print(test)', 'test', '"""',
+ 'print(test)', '', '', '']
+ converted_doctest_content = '\n'.join(converted_doctest_content)
new_doctest_content = "".join(open(doctest_name).readlines())
self.assertEquals(new_doctest_content, converted_doctest_content)
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
@@ -296,10 +296,11 @@
res = find_packages([root], ['pkg1.pkg2'])
self.assertEqual(set(res), set(['pkg1', 'pkg5', 'pkg1.pkg3', 'pkg1.pkg3.pkg6']))
+ @unittest.skipUnless(sys.version > '2.6', 'Need Python 2.6 or more')
def test_run_2to3_on_code(self):
content = "print 'test'"
converted_content = "print('test')"
- file_handle = tempfile.NamedTemporaryFile(delete=True)
+ file_handle = self.mktempfile()
file_name = file_handle.name
file_handle.write(content)
file_handle.flush()
@@ -310,11 +311,12 @@
file_handle.close()
self.assertEquals(new_content, converted_content)
+ @unittest.skipUnless(sys.version > '2.6', 'Need Python 2.6 or more')
def test_run_2to3_on_doctests(self):
# to check if text files containing doctests only get converted.
content = ">>> print 'test'\ntest\n"
converted_content = ">>> print('test')\ntest\n\n"
- file_handle = tempfile.NamedTemporaryFile(delete=True)
+ file_handle = self.mktempfile()
file_name = file_handle.name
file_handle.write(content)
file_handle.flush()
diff --git a/src/distutils2/util.py b/src/distutils2/util.py
--- a/src/distutils2/util.py
+++ b/src/distutils2/util.py
@@ -5,7 +5,10 @@
__revision__ = "$Id: util.py 77761 2010-01-26 22:46:15Z tarek.ziade $"
-import sys, os, string, re
+import sys
+import os
+import string
+import re
from copy import copy
from fnmatch import fnmatchcase
@@ -17,6 +20,7 @@
_PLATFORM = None
+
def newer(source, target):
"""Tells if the target is newer than the source.
@@ -37,6 +41,7 @@
return os.stat(source).st_mtime > os.stat(target).st_mtime
+
def get_platform():
"""Return a string that identifies the current platform.
@@ -48,6 +53,7 @@
_PLATFORM = _sysconfig.get_platform()
return _PLATFORM
+
def set_platform(identifier):
"""Sets the platform string identifier returned by get_platform().
@@ -57,6 +63,7 @@
global _PLATFORM
_PLATFORM = identifier
+
def convert_path(pathname):
"""Return 'pathname' as a name that will work on the native filesystem.
@@ -125,6 +132,7 @@
_environ_checked = 0
+
def check_environ():
"""Ensure that 'os.environ' has all the environment variables needed.
@@ -147,6 +155,7 @@
_environ_checked = 1
+
def subst_vars(s, local_vars):
"""Perform shell/Perl-style variable substitution on 'string'.
@@ -158,7 +167,8 @@
variables not found in either 'local_vars' or 'os.environ'.
"""
check_environ()
- def _subst (match, local_vars=local_vars):
+
+ def _subst(match, local_vars=local_vars):
var_name = match.group(1)
if var_name in local_vars:
return str(local_vars[var_name])
@@ -170,6 +180,7 @@
except KeyError, var:
raise ValueError("invalid variable '$%s'" % var)
+
def grok_environment_error(exc, prefix="error: "):
"""Generate a useful error message from an EnvironmentError.
@@ -196,12 +207,14 @@
# Needed by 'split_quoted()'
_wordchars_re = _squote_re = _dquote_re = None
+
def _init_regex():
global _wordchars_re, _squote_re, _dquote_re
_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace)
_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'")
_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"')
+
def split_quoted(s):
"""Split a string up according to Unix shell-like rules for quotes and
backslashes.
@@ -217,7 +230,8 @@
# This is a nice algorithm for splitting up a single string, since it
# doesn't require character-by-character examination. It was a little
# bit of a brain-bender to get it working right, though...
- if _wordchars_re is None: _init_regex()
+ if _wordchars_re is None:
+ _init_regex()
s = s.strip()
words = []
@@ -237,8 +251,8 @@
elif s[end] == '\\': # preserve whatever is being escaped;
# will become part of the current word
- s = s[:end] + s[end+1:]
- pos = end+1
+ s = s[:end] + s[end + 1:]
+ pos = end + 1
else:
if s[end] == "'": # slurp singly-quoted string
@@ -253,7 +267,7 @@
raise ValueError("bad string (mismatched %s quotes?)" % s[end])
(beg, end) = m.span()
- s = s[:beg] + s[beg+1:end-1] + s[end:]
+ s = s[:beg] + s[beg + 1:end - 1] + s[end:]
pos = m.end() - 2
if pos >= len(s):
@@ -296,7 +310,7 @@
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
- raise ValueError, "invalid truth value %r" % (val,)
+ raise ValueError("invalid truth value %r" % (val,))
def byte_compile(py_files, optimize=0, force=0, prefix=None, base_dir=None,
@@ -450,7 +464,9 @@
return sep.join(lines)
_RE_VERSION = re.compile('(\d+\.\d+(\.\d+)*)')
-_MAC_OS_X_LD_VERSION = re.compile('^@\(#\)PROGRAM:ld PROJECT:ld64-((\d+)(\.\d+)*)')
+_MAC_OS_X_LD_VERSION = re.compile('^@\(#\)PROGRAM:ld '
+ 'PROJECT:ld64-((\d+)(\.\d+)*)')
+
def _find_ld_version():
"""Finds the ld version. The version scheme differs under Mac OSX."""
@@ -459,6 +475,7 @@
else:
return _find_exe_version('ld -v')
+
def _find_exe_version(cmd, pattern=_RE_VERSION):
"""Find the version of an executable by running `cmd` in the shell.
@@ -488,6 +505,7 @@
return None
return result.group(1)
+
def get_compiler_versions():
"""Returns a tuple providing the versions of gcc, ld and dllwrap
@@ -499,6 +517,7 @@
dllwrap = _find_exe_version('dllwrap --version')
return gcc, ld, dllwrap
+
def newer_group(sources, target, missing='error'):
"""Return true if 'target' is out-of-date with respect to any file
listed in 'sources'.
@@ -538,6 +557,7 @@
return False
+
def write_file(filename, contents):
"""Create a file with the specified name and write 'contents' (a
sequence of strings without line terminators) to it.
@@ -549,12 +569,14 @@
finally:
f.close()
+
def _is_package(path):
"""Returns True if path is a package (a dir with an __init__ file."""
if not os.path.isdir(path):
return False
return os.path.isfile(os.path.join(path, '__init__.py'))
+
def _under(path, root):
path = path.split(os.sep)
root = root.split(os.sep)
@@ -565,12 +587,14 @@
return False
return True
+
def _package_name(root_path, path):
"""Returns a dotted package name, given a subpath."""
if not _under(path, root_path):
raise ValueError('"%s" is not a subpath of "%s"' % (path, root_path))
return path[len(root_path) + 1:].replace(os.sep, '.')
+
def find_packages(paths=('.',), exclude=()):
"""Return a list all Python packages found recursively within
directories 'paths'
@@ -585,6 +609,7 @@
"""
packages = []
discarded = []
+
def _discarded(path):
for discard in discarded:
if _under(path, discard):
@@ -619,12 +644,12 @@
# utility functions for 2to3 support
-def run_2to3(files, doctests_only=False, fixer_names=None, options=None,
+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."""
+ 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
@@ -642,6 +667,7 @@
else:
r.refactor(files, write=True)
+
class Mixin2to3:
""" Wrapper class for commands that run 2to3.
To configure 2to3, setup scripts may either change
@@ -660,4 +686,5 @@
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)
+ return run_2to3(files, doctests_only, self.fixer_names,
+ self.options, self.explicit)
--
Repository URL: http://hg.python.org/distutils2
More information about the Python-checkins
mailing list