summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit869bf47971914d36b6ccd785432c83ce088ddc9d (patch)
tree68dd04bc9c470866299938e3fe831084f94e7ce5
parent388b499a2b99bcd6e409bd0d593144faa0d52f40 (diff)
parent1ec58bd7f0e3ce8d6d906e9e8f1f582d5fe9253c (diff)
downloaddisutils2-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.py9
-rw-r--r--distutils2/tests/test_util.py43
-rw-r--r--distutils2/util.py50
-rw-r--r--setup.cfg2
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
diff --git a/setup.cfg b/setup.cfg
index dcb77e6..827c3df 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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