diff options
author | ?ric Araujo <merwok@netwok.org> | 2011-10-21 07:08:31 +0200 |
---|---|---|
committer | ?ric Araujo <merwok@netwok.org> | 2011-10-21 07:08:31 +0200 |
commit | 869bf47971914d36b6ccd785432c83ce088ddc9d (patch) | |
tree | 68dd04bc9c470866299938e3fe831084f94e7ce5 | |
parent | 388b499a2b99bcd6e409bd0d593144faa0d52f40 (diff) | |
parent | 1ec58bd7f0e3ce8d6d906e9e8f1f582d5fe9253c (diff) | |
download | disutils2-869bf47971914d36b6ccd785432c83ce088ddc9d.tar.gz |
Merge fix for #13205 and other changes from default.
The deprecation warning emitted by RawConfigParser.readfp (used in util
and config, and from config in many places) will be annoying for
developers using distutils2 as a library; maybe we should drop 3.1
compat (people are expected to switch from 2.7 to 3.2 directly) and
switch to RawConfigParser.read_file.
One test in test_pypi_simple fails on 3.3 due to a recent change (see
#10680); I didn?t fix it because I can?t open the bug report that the
test was written for, and anyway the whole file should be rewritten to
use assertRaises. I have to leave some things for Alexis :)
-rw-r--r-- | distutils2/tests/support.py | 9 | ||||
-rw-r--r-- | distutils2/tests/test_util.py | 43 | ||||
-rw-r--r-- | distutils2/util.py | 50 | ||||
-rw-r--r-- | setup.cfg | 2 |
4 files changed, 85 insertions, 19 deletions
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py index 9938d75..961780d 100644 --- a/distutils2/tests/support.py +++ b/distutils2/tests/support.py @@ -429,6 +429,15 @@ def assert_python_ok(*args, **env_vars): return _assert_python(True, *args, **env_vars) +def assert_python_failure(*args, **env_vars): + """ + Assert that running the interpreter with `args` and optional environment + variables `env_vars` fails and return a (return code, stdout, stderr) + tuple. + """ + return _assert_python(False, *args, **env_vars) + + def unload(name): try: del sys.modules[name] diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py index 74e7ddc..f3432ab 100644 --- a/distutils2/tests/test_util.py +++ b/distutils2/tests/test_util.py @@ -4,11 +4,11 @@ import sys import time import logging import tempfile +import textwrap +import warnings import subprocess from io import StringIO -from distutils2.tests import support, unittest -from distutils2.tests.test_config import SETUP_CFG from distutils2.errors import ( PackagingPlatformError, PackagingByteCompileError, PackagingFileError, PackagingExecError, InstallationException) @@ -19,7 +19,11 @@ from distutils2.util import ( get_compiler_versions, _MAC_OS_X_LD_VERSION, byte_compile, find_packages, spawn, get_pypirc_path, generate_pypirc, read_pypirc, resolve_name, iglob, RICH_GLOB, egginfo_to_distinfo, is_setuptools, is_distutils, is_packaging, - get_install_method, cfg_to_args, encode_multipart) + get_install_method, cfg_to_args, generate_setup_py, encode_multipart) + +from distutils2.tests import support, unittest +from distutils2.tests.test_config import SETUP_CFG +from distutils2.tests.support import assert_python_ok, assert_python_failure PYPIRC = """\ @@ -503,10 +507,14 @@ class UtilTestCase(support.EnvironRestorer, self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') self.write_file('README', 'loooong description') - args = cfg_to_args() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + args = cfg_to_args() # use Distribution to get the contents of the setup.cfg file dist = Distribution() - dist.parse_config_files() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + dist.parse_config_files() metadata = dist.metadata self.assertEqual(args['name'], metadata['Name']) @@ -529,6 +537,26 @@ class UtilTestCase(support.EnvironRestorer, self.assertEqual(args['scripts'], dist.scripts) self.assertEqual(args['py_modules'], dist.py_modules) + def test_generate_setup_py(self): + # undo subprocess.Popen monkey-patching before using assert_python_* + subprocess.Popen = self.old_popen + os.chdir(self.mkdtemp()) + self.write_file('setup.cfg', textwrap.dedent("""\ + [metadata] + name = SPAM + classifier = Programming Language :: Python + """)) + generate_setup_py() + self.assertTrue(os.path.exists('setup.py'), 'setup.py not created') + rc, out, err = assert_python_ok('setup.py', '--name') + self.assertEqual(out, b'SPAM\n') + self.assertEqual(err, b'') + + # a generated setup.py should complain if no setup.cfg is present + os.unlink('setup.cfg') + rc, out, err = assert_python_failure('setup.py', '--name') + self.assertIn(b'setup.cfg', err) + def test_encode_multipart(self): fields = [('username', 'wok'), ('password', 'secret')] files = [('picture', 'wok.png', b'PNG89')] @@ -580,7 +608,6 @@ class GlobTestCase(GlobTestCaseBase): super(GlobTestCase, self).tearDown() def assertGlobMatch(self, glob, spec): - """""" tempdir = self.build_files_tree(spec) expected = self.clean_tree(spec) os.chdir(tempdir) @@ -849,7 +876,9 @@ class PackagingLibChecks(support.TempdirManager, def test_get_install_method_with_packaging_pkg(self): path = self._valid_setup_cfg_pkg() - self.assertEqual("distutils2", get_install_method(path)) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual("distutils2", get_install_method(path)) def test_get_install_method_with_unknown_pkg(self): path = self._invalid_setup_cfg_pkg() diff --git a/distutils2/util.py b/distutils2/util.py index 8c629de..a5111b2 100644 --- a/distutils2/util.py +++ b/distutils2/util.py @@ -6,6 +6,7 @@ import csv import imp import sys import errno +import codecs import shutil import string import hashlib @@ -925,6 +926,24 @@ def _iglob(path_glob): yield file +# HOWTO change cfg_to_args +# +# This function has two major constraints: It is copied by inspect.getsource +# in generate_setup_py; it is used in generated setup.py which may be run by +# any Python version supported by distutils2 (2.4-3.3). +# +# * Keep objects like D1_D2_SETUP_ARGS static, i.e. in the function body +# instead of global. +# * If you use a function from another module, update the imports in +# SETUP_TEMPLATE. Use only modules, classes and functions compatible with +# all versions: codecs.open instead of open, RawConfigParser.readfp instead +# of read, standard exceptions instead of Packaging*Error, etc. +# * If you use a function from this module, update the template and +# generate_setup_py. +# +# test_util tests this function and the generated setup.py, but does not test +# that it's compatible with all Python versions. + def cfg_to_args(path='setup.cfg'): """Compatibility helper to use setup.cfg in setup.py. @@ -935,8 +954,6 @@ def cfg_to_args(path='setup.cfg'): *file* is the path to the setup.cfg file. If it doesn't exist, PackagingFileError is raised. """ - # We need to declare the following constants here so that it's easier to - # generate the setup.py afterwards, using inspect.getsource. # XXX ** == needs testing D1_D2_SETUP_ARGS = {"name": ("metadata",), @@ -980,11 +997,11 @@ def cfg_to_args(path='setup.cfg'): # The real code starts here config = RawConfigParser() - if not os.path.exists(path): - raise PackagingFileError("file '%s' does not exist" % - os.path.abspath(path)) - with open(path, encoding='utf-8') as f: + f = codecs.open(path, encoding='utf-8') + try: config.readfp(f) + finally: + f.close() kwargs = {} for arg in D1_D2_SETUP_ARGS: @@ -1006,8 +1023,11 @@ def cfg_to_args(path='setup.cfg'): filenames = split_multiline(filenames) in_cfg_value = [] for filename in filenames: - with open(filename) as fp: + fp = codecs.open(filename, encoding='utf-8') + try: in_cfg_value.append(fp.read()) + finally: + fp.close() in_cfg_value = '\n\n'.join(in_cfg_value) else: continue @@ -1024,13 +1044,19 @@ def cfg_to_args(path='setup.cfg'): return kwargs -_SETUP_TMPL = """\ +SETUP_TEMPLATE = """\ # This script was automatically generated by distutils2 import os +import codecs from distutils.core import setup -from ConfigParser import RawConfigParser +try: + from ConfigParser import RawConfigParser +except ImportError: + from configparser import RawConfigParser + +%(split_multiline)s -%(func)s +%(cfg_to_args)s setup(**cfg_to_args()) """ @@ -1044,8 +1070,10 @@ def generate_setup_py(): if os.path.exists("setup.py"): raise PackagingFileError("a setup.py file already exists") + source = SETUP_TEMPLATE % {'split_multiline': getsource(split_multiline), + 'cfg_to_args': getsource(cfg_to_args)} with open("setup.py", "w", encoding='utf-8') as fp: - fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)}) + fp.write(source) # Taken from the pip project @@ -1,7 +1,7 @@ [metadata] name = Distutils2 version = 1.0a3 -summary = Python Distribution Utilities +summary = Python Packaging Library description-file = README.txt home-page = http://bitbucket.org/tarek/distutils2/wiki/Home author = The Fellowship of the Packaging |