[Python-checkins] distutils2: Use `setup.cfg` as the canonical source for installation
alexis.metaireau
python-checkins at python.org
Mon Sep 12 19:13:45 CEST 2011
http://hg.python.org/distutils2/rev/288640098ea8
changeset: 1139:288640098ea8
user: Jeremy Kloth <jeremy.kloth at gmail.com>
date: Mon Sep 12 05:37:52 2011 -0600
summary:
Use `setup.cfg` as the canonical source for installation
files:
distutils2/config.py | 3 +-
setup.cfg | 35 ++-
setup.py | 383 +++++++++++++-----------------
3 files changed, 204 insertions(+), 217 deletions(-)
diff --git a/distutils2/config.py b/distutils2/config.py
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -221,7 +221,8 @@
if len(data) != 2:
continue # XXX error should never pass silently
key, value = data
- self.dist.package_data[key.strip()] = value.strip()
+ globs = self.dist.package_data.setdefault(key.strip(), [])
+ globs.extend([v.strip() for v in value.split(',')])
self.dist.data_files = []
for data in files.get('data_files', []):
diff --git a/setup.cfg b/setup.cfg
--- a/setup.cfg
+++ b/setup.cfg
@@ -8,5 +8,36 @@
[metadata]
name = Distutils2
version = 1.0a3
-home-page = http://xxx
-author = Ok
+summary = Python Distribution Utilities
+description-file = README.txt
+home-page = http://bitbucket.org/tarek/distutils2/wiki/Home
+author = Tarek Ziade
+author-email = tarek at ziade.org
+classifier =
+ Development Status :: 3 - Alpha
+ Intended Audience :: Developers
+ License :: OSI Approved :: Python Software Foundation License
+ Operating System :: OS Independent
+ Programming Language :: Python
+ Topic :: Software Development :: Libraries :: Python Modules
+ Topic :: System :: Archiving :: Packaging
+ Topic :: System :: Systems Administration
+ Topic :: Utilities
+license = PSF
+keywords = packaging,distutils
+
+[files]
+packages =
+ distutils2
+ distutils2.command
+ distutils2.compiler
+ distutils2.pypi
+ distutils2.tests
+ distutils2.tests.fixer
+ distutils2._backport
+ distutils2._backport.tests
+package_data =
+ distutils2._backport = sysconfig.cfg
+ distutils2.command = wininst*.exe
+scripts =
+ pysetup
\ No newline at end of file
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1,249 +1,204 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
-import sys
import os
import re
+import sys
+import codecs
+from distutils import sysconfig
+from distutils.core import setup, Extension
+from distutils.ccompiler import new_compiler
+try:
+ from configparser import RawConfigParser
+except ImportError: #<3.0
+ from ConfigParser import RawConfigParser
-from distutils2 import __version__ as VERSION
-from distutils import log
-from distutils.ccompiler import new_compiler
-from distutils.command.sdist import sdist
-from distutils.command.install import install
+def cfg_to_args(path='setup.cfg'):
+ from distutils2.util import split_multiline
+ def split_elements(value):
+ return [ v.strip() for v in value.split(',') ]
+ def split_files(value):
+ return [ str(v) for v in split_multiline(value) ]
+ opts_to_args = {
+ 'metadata': (
+ ('name', 'name', None),
+ ('version', 'version', None),
+ ('author', 'author', None),
+ ('author-email', 'author_email', None),
+ ('maintainer', 'maintainer', None),
+ ('maintainer-email', 'maintainer_email', None),
+ ('home-page', 'url', None),
+ ('summary', 'description', None),
+ ('description', 'long_description', None),
+ ('download-url', 'download_url', None),
+ ('classifier', 'classifiers', split_multiline),
+ ('platform', 'platforms', split_multiline),
+ ('license', 'license', None),
+ ('keywords', 'keywords', split_elements),
+ ),
+ 'files': (
+ ('packages', 'packages', split_files),
+ ('modules', 'py_modules', split_files),
+ ('scripts', 'scripts', split_files),
+ ('package_data', 'package_data', split_files),
+ ),
+ }
+ config = RawConfigParser()
+ config.optionxform = lambda x: x.lower().replace('_', '-')
+ fp = codecs.open(path, encoding='utf-8')
+ try:
+ config.readfp(fp)
+ finally:
+ fp.close()
+ kwargs = {}
+ for section in opts_to_args:
+ for optname, argname, xform in opts_to_args[section]:
+ if config.has_option(section, optname):
+ value = config.get(section, optname)
+ if xform:
+ value = xform(value)
+ kwargs[argname] = value
+ # Handle `description-file`
+ if ('long_description' not in kwargs and
+ config.has_option('metadata', 'description-file')):
+ filenames = config.get('metadata', 'description-file')
+ for filename in split_multiline(filenames):
+ descriptions = []
+ fp = open(filename)
+ try:
+ descriptions.append(fp.read())
+ finally:
+ fp.close()
+ kwargs['long_description'] = '\n\n'.join(descriptions)
+ # Handle `package_data`
+ if 'package_data' in kwargs:
+ package_data = {}
+ for data in kwargs['package_data']:
+ key, value = data.split('=', 1)
+ globs = package_data.setdefault(key.strip(), [])
+ globs.extend(split_elements(value))
+ kwargs['package_data'] = package_data
+ return kwargs
-# Python 3.x hook to run 2to3 automatically
-try:
- from distutils.command.build_py import build_py_2to3 as build_py
- from distutils.core import setup, Extension
-except ImportError:
- # 2.x, try to use setuptools if available
- try :
- from setuptools.command.build_py import build_py
- from setuptools import setup, Extension
- except ImportError:
- from distutils.command.build_py import build_py
- from distutils.core import setup, Extension
-
-
-f = open('README.txt')
-try:
- README = f.read()
-finally:
- f.close()
-
-def get_tip_revision(path=os.getcwd()):
- from subprocess import Popen, PIPE
- try:
- cmd = Popen(['hg', 'tip', '--template', '{rev}', '-R', path],
- stdout=PIPE, stderr=PIPE)
- except OSError:
- return 0
- rev = cmd.stdout.read()
- if not rev :
- # there has been an error in the command
- return 0
- return int(rev)
-
-DEV_SUFFIX = '.dev%d' % get_tip_revision('..')
-
-
-class install_hg(install):
-
- user_options = install.user_options + [
- ('dev', None, "Add a dev marker")
- ]
-
- def initialize_options(self):
- install.initialize_options(self)
- self.dev = 0
-
- def run(self):
- if self.dev:
- self.distribution.metadata.version += DEV_SUFFIX
- install.run(self)
-
-
-class sdist_hg(sdist):
-
- user_options = sdist.user_options + [
- ('dev', None, "Add a dev marker")
- ]
-
- def initialize_options(self):
- sdist.initialize_options(self)
- self.dev = 0
-
- def run(self):
- if self.dev:
- self.distribution.metadata.version += DEV_SUFFIX
- sdist.run(self)
-
-
-# additional paths to check, set from the command line
-SSL_INCDIR = '' # --openssl-incdir=
-SSL_LIBDIR = '' # --openssl-libdir=
-SSL_DIR = '' # --openssl-prefix=
-
-def add_dir_to_list(dirlist, dir):
- """Add the directory 'dir' to the list 'dirlist' (at the front) if
- 'dir' actually exists and is a directory. If 'dir' is already in
- 'dirlist' it is moved to the front.
- """
- if dir is not None and os.path.isdir(dir) and dir not in dirlist:
- if dir in dirlist:
- dirlist.remove(dir)
- dirlist.insert(0, dir)
-
-
+# (from Python's setup.py, in PyBuildExt.detect_modules())
def prepare_hashlib_extensions():
"""Decide which C extensions to build and create the appropriate
Extension objects to build them. Return a list of Extensions.
"""
- # this CCompiler object is only used to locate include files
- compiler = new_compiler()
+ ssl_libs = None
+ ssl_inc_dir = None
+ ssl_lib_dirs = []
+ ssl_inc_dirs = []
+ if os.name == 'posix':
+ # (from Python's setup.py, in PyBuildExt.detect_modules())
+ # lib_dirs and inc_dirs are used to search for files;
+ # if a file is found in one of those directories, it can
+ # be assumed that no additional -I,-L directives are needed.
+ lib_dirs = []
+ inc_dirs = []
+ if os.path.normpath(sys.prefix) != '/usr':
+ lib_dirs.append(sysconfig.get_config_var('LIBDIR'))
+ inc_dirs.append(sysconfig.get_config_var('INCLUDEDIR'))
+ # Ensure that /usr/local is always used
+ lib_dirs.append('/usr/local/lib')
+ inc_dirs.append('/usr/local/include')
+ # Add the compiler defaults; this compiler object is only used
+ # to locate the OpenSSL files.
+ compiler = new_compiler()
+ lib_dirs.extend(compiler.library_dirs)
+ inc_dirs.extend(compiler.include_dirs)
+ # Now the platform defaults
+ lib_dirs.extend(['/lib64', '/usr/lib64', '/lib', '/usr/lib'])
+ inc_dirs.extend(['/usr/include'])
+ # Find the SSL library directory
+ ssl_libs = ['ssl', 'crypto']
+ ssl_lib = compiler.find_library_file(lib_dirs, 'ssl')
+ if ssl_lib is None:
+ ssl_lib_dirs = ['/usr/local/ssl/lib', '/usr/contrib/ssl/lib']
+ ssl_lib = compiler.find_library_file(ssl_lib_dirs, 'ssl')
+ if ssl_lib is not None:
+ ssl_lib_dirs.append(os.path.dirname(ssl_lib))
+ else:
+ ssl_libs = None
+ # Locate the SSL headers
+ for ssl_inc_dir in inc_dirs + ['/usr/local/ssl/include',
+ '/usr/contrib/ssl/include']:
+ ssl_h = os.path.join(ssl_inc_dir, 'openssl', 'ssl.h')
+ if os.path.exists(ssl_h):
+ if ssl_inc_dir not in inc_dirs:
+ ssl_inc_dirs.append(ssl_inc_dir)
+ break
+ elif os.name == 'nt':
+ # (from Python's PCbuild/build_ssl.py, in find_best_ssl_dir())
+ # Look for SSL 1 level up from here. That is, the same place the
+ # other externals for Python core live.
+ # note: do not abspath src_dir; the build will fail if any
+ # higher up directory name has spaces in it.
+ src_dir = '..'
+ try:
+ fnames = os.listdir(src_dir)
+ except OSError:
+ fnames = []
+ ssl_dir = None
+ best_parts = []
+ for fname in fnames:
+ fqn = os.path.join(src_dir, fname)
+ if os.path.isdir(fqn) and fname.startswith("openssl-"):
+ # We have a candidate, determine the best
+ parts = re.split("[.-]", fname)[1:]
+ # Ignore all "beta" or any other qualifiers;
+ # eg - openssl-0.9.7-beta1
+ if len(parts) < 4 and parts > best_parts:
+ best_parts = parts
+ ssl_dir = fqn
+ if ssl_dir is not None:
+ ssl_libs = ['gdi32', 'user32', 'advapi32',
+ os.path.join(ssl_dir, 'out32', 'libeay32')]
+ ssl_inc_dir = os.path.join(ssl_dir, 'inc32')
+ ssl_inc_dirs.append(ssl_inc_dir)
- # Ensure that these paths are always checked
- if os.name == 'posix':
- add_dir_to_list(compiler.library_dirs, '/usr/local/lib')
- add_dir_to_list(compiler.include_dirs, '/usr/local/include')
-
- add_dir_to_list(compiler.library_dirs, '/usr/local/ssl/lib')
- add_dir_to_list(compiler.include_dirs, '/usr/local/ssl/include')
-
- add_dir_to_list(compiler.library_dirs, '/usr/contrib/ssl/lib')
- add_dir_to_list(compiler.include_dirs, '/usr/contrib/ssl/include')
-
- add_dir_to_list(compiler.library_dirs, '/usr/lib')
- add_dir_to_list(compiler.include_dirs, '/usr/include')
-
- # look in paths supplied on the command line
- if SSL_LIBDIR:
- add_dir_to_list(compiler.library_dirs, SSL_LIBDIR)
- if SSL_INCDIR:
- add_dir_to_list(compiler.include_dirs, SSL_INCDIR)
- if SSL_DIR:
- if os.name == 'nt':
- add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'out32dll'))
- # prefer the static library
- add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'out32'))
- else:
- add_dir_to_list(compiler.library_dirs, os.path.join(SSL_DIR, 'lib'))
- add_dir_to_list(compiler.include_dirs, os.path.join(SSL_DIR, 'include'))
-
- oslibs = {'posix': ['ssl', 'crypto'],
- 'nt': ['libeay32', 'gdi32', 'advapi32', 'user32']}
-
- if os.name not in oslibs:
- sys.stderr.write(
- 'unknown operating system, impossible to compile _hashlib')
- sys.exit(1)
-
- exts = []
-
- ssl_inc_dirs = []
- ssl_incs = []
- for inc_dir in compiler.include_dirs:
- f = os.path.join(inc_dir, 'openssl', 'ssl.h')
- if os.path.exists(f):
- ssl_incs.append(f)
- ssl_inc_dirs.append(inc_dir)
-
- ssl_lib = compiler.find_library_file(compiler.library_dirs, oslibs[os.name][0])
-
- # find out which version of OpenSSL we have
+ # Find out which version of OpenSSL we have
openssl_ver = 0
openssl_ver_re = re.compile(
'^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
- ssl_inc_dir = ''
- for ssl_inc_dir in ssl_inc_dirs:
- name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
- if os.path.isfile(name):
- try:
- incfile = open(name, 'r')
- for line in incfile:
- m = openssl_ver_re.match(line)
- if m:
- openssl_ver = int(m.group(1), 16)
- break
- except IOError:
- pass
+ if ssl_inc_dir is not None:
+ opensslv_h = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
+ try:
+ incfile = open(opensslv_h, 'r')
+ for line in incfile:
+ m = openssl_ver_re.match(line)
+ if m:
+ openssl_ver = int(m.group(1), 16)
+ except IOError:
+ e = str(sys.last_value)
+ print("IOError while reading %s: %s" % (opensslv_h, e))
- # first version found is what we'll use
- if openssl_ver:
- break
-
- if (ssl_inc_dir and ssl_lib is not None and openssl_ver >= 0x00907000):
-
- log.info('Using OpenSSL version 0x%08x from', openssl_ver)
- log.info(' Headers:\t%s', ssl_inc_dir)
- log.info(' Library:\t%s', ssl_lib)
-
+ # Now we can determine which extension modules need to be built.
+ exts = []
+ if ssl_libs is not None and openssl_ver >= 0x907000:
# The _hashlib module wraps optimized implementations
# of hash functions from the OpenSSL library.
exts.append(Extension('distutils2._backport._hashlib',
['distutils2/_backport/_hashopenssl.c'],
- include_dirs = [ssl_inc_dir],
- library_dirs = [os.path.dirname(ssl_lib)],
- libraries = oslibs[os.name]))
+ include_dirs=ssl_inc_dirs,
+ library_dirs=ssl_lib_dirs,
+ libraries=ssl_libs))
else:
+ # no openssl at all, use our own md5 and sha1
exts.append(Extension('distutils2._backport._sha',
['distutils2/_backport/shamodule.c']))
exts.append(Extension('distutils2._backport._md5',
sources=['distutils2/_backport/md5module.c',
'distutils2/_backport/md5.c'],
depends=['distutils2/_backport/md5.h']) )
-
- if (not ssl_lib or openssl_ver < 0x00908000):
+ if openssl_ver < 0x908000:
# OpenSSL doesn't do these until 0.9.8 so we'll bring our own
exts.append(Extension('distutils2._backport._sha256',
['distutils2/_backport/sha256module.c']))
exts.append(Extension('distutils2._backport._sha512',
['distutils2/_backport/sha512module.c']))
-
return exts
-setup_kwargs = {'scripts': ['scripts/pysetup']}
-
-if sys.version < '2.6':
- setup_kwargs['scripts'].append('distutils2/create.py')
-
+setup_kwargs = cfg_to_args('setup.cfg')
if sys.version < '2.5':
setup_kwargs['ext_modules'] = prepare_hashlib_extensions()
-
-_CLASSIFIERS = """\
-Development Status :: 3 - Alpha
-Intended Audience :: Developers
-License :: OSI Approved :: Python Software Foundation License
-Operating System :: OS Independent
-Programming Language :: Python
-Topic :: Software Development :: Libraries :: Python Modules
-Topic :: System :: Archiving :: Packaging
-Topic :: System :: Systems Administration
-Topic :: Utilities"""
-
-setup(name="Distutils2",
- version=VERSION,
- description="Python Distribution Utilities",
- keywords=['packaging', 'distutils'],
- author="Tarek Ziade",
- author_email="tarek at ziade.org",
- url="http://bitbucket.org/tarek/distutils2/wiki/Home",
- license="PSF",
- long_description=README,
- classifiers=_CLASSIFIERS.split('\n'),
- packages=[
- 'distutils2',
- 'distutils2.tests',
- 'distutils2.compiler',
- 'distutils2.command',
- 'distutils2._backport',
- 'distutils2.pypi',
- 'distutils2.tests.fixer',
- 'distutils2._backport.tests',
- ],
- cmdclass={
- 'build_py':build_py,
- 'install_hg': install_hg,
- 'sdist_hg': sdist_hg,
- },
- package_data={'distutils2._backport': ['sysconfig.cfg']},
- **setup_kwargs)
+setup(**setup_kwargs)
--
Repository URL: http://hg.python.org/distutils2
More information about the Python-checkins
mailing list