d2to1-0.2.12/0000755001134200020070000000000012551770444013442 5ustar embrayscience00000000000000d2to1-0.2.12/ez_setup25.py0000644001134200020070000002757312551553446016040 0ustar embrayscience00000000000000#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os import shutil import sys import tempfile import tarfile import optparse import subprocess import platform from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None DEFAULT_VERSION = "1.4.2" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 def _check_call_py24(cmd, *args, **kwargs): res = subprocess.call(cmd, *args, **kwargs) class CalledProcessError(Exception): pass if not res == 0: msg = "Command '%s' return non-zero exit status %d" % (cmd, res) raise CalledProcessError(msg) vars(subprocess).setdefault('check_call', _check_call_py24) def _install(tarball, install_args=()): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # installing log.warn('Installing Setuptools') if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') # exitcode will be 2 return 2 finally: os.chdir(old_wd) shutil.rmtree(tmpdir) def _build_egg(egg, tarball, to_dir): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # building an egg log.warn('Building a Setuptools egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) shutil.rmtree(tmpdir) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): tarball = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, tarball, to_dir) sys.path.insert(0, egg) # Remove previously-imported pkg_resources if present (see # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). if 'pkg_resources' in sys.modules: del sys.modules['pkg_resources'] import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15): # making sure we use the absolute path to_dir = os.path.abspath(to_dir) was_imported = 'pkg_resources' in sys.modules or \ 'setuptools' in sys.modules try: import pkg_resources except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("setuptools>=" + version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of setuptools (>=%s) is not available,\n" "and can't be installed while this script is running. Please\n" "install a more recent version first, using\n" "'easy_install -U setuptools'." "\n\n(Currently using %r)\n" % (version, e.args[0])) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return _do_download(version, download_base, to_dir, download_delay) except pkg_resources.DistributionNotFound: return _do_download(version, download_base, to_dir, download_delay) def _clean_check(cmd, target): """ Run the command to download target. If the command fails, clean up before re-raising the error. """ try: subprocess.check_call(cmd) except subprocess.CalledProcessError: if os.access(target, os.F_OK): os.unlink(target) raise def download_file_powershell(url, target): """ Download the file at url to target using Powershell (which will validate trust). Raise an exception if the command cannot complete. """ target = os.path.abspath(target) cmd = [ 'powershell', '-Command', "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), ] _clean_check(cmd, target) def has_powershell(): if platform.system() != 'Windows': return False cmd = ['powershell', '-Command', 'echo test'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_powershell.viable = has_powershell def download_file_curl(url, target): cmd = ['curl', url, '--silent', '--output', target] _clean_check(cmd, target) def has_curl(): cmd = ['curl', '--version'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_curl.viable = has_curl def download_file_wget(url, target): cmd = ['wget', url, '--quiet', '--output-document', target] _clean_check(cmd, target) def has_wget(): cmd = ['wget', '--version'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_wget.viable = has_wget def download_file_insecure(url, target): """ Use Python to download the file, even though it cannot authenticate the connection. """ try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen src = dst = None try: src = urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = src.read() dst = open(target, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() download_file_insecure.viable = lambda: True def get_best_downloader(): downloaders = [ download_file_powershell, download_file_curl, download_file_wget, download_file_insecure, ] for dl in downloaders: if dl.viable(): return dl def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. ``downloader_factory`` should be a function taking no arguments and returning a function for downloading a URL to a target. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) tgz_name = "setuptools-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) if not os.path.exists(saveto): # Avoid repeated downloads log.warn("Downloading %s", url) downloader = downloader_factory() downloader(url, saveto) return os.path.realpath(saveto) def _extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ import copy import operator from tarfile import ExtractError directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. if sys.version_info < (2, 4): def sorter(dir1, dir2): return cmp(dir1.name, dir2.name) directories.sort(sorter) directories.reverse() else: directories.sort(key=operator.attrgetter('name'), reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError: e = sys.exc_info()[1] if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def _build_install_args(options): """ Build the arguments to 'python setup.py install' on the setuptools package """ install_args = [] if options.user_install: if sys.version_info < (2, 6): log.warn("--user requires Python 2.6 or later") raise SystemExit(1) install_args.append('--user') return install_args def _parse_args(): """ Parse the command line for options """ parser = optparse.OptionParser() parser.add_option( '--user', dest='user_install', action='store_true', default=False, help='install in user site package (requires Python 2.6 or later)') parser.add_option( '--download-base', dest='download_base', metavar="URL", default=DEFAULT_URL, help='alternative URL from where to download the setuptools package') parser.add_option( '--insecure', dest='downloader_factory', action='store_const', const=lambda: download_file_insecure, default=get_best_downloader, help='Use internal, non-validating downloader' ) options, args = parser.parse_args() # positional arguments are ignored return options def main(version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" options = _parse_args() tarball = download_setuptools(download_base=options.download_base, downloader_factory=options.downloader_factory) return _install(tarball, _build_install_args(options)) if __name__ == '__main__': sys.exit(main()) d2to1-0.2.12/ez_setup.py0000644001134200020070000002625212551552746015664 0ustar embrayscience00000000000000#!/usr/bin/env python """ Setuptools bootstrapping installer. Run this script to install or upgrade setuptools. """ import os import shutil import sys import tempfile import zipfile import optparse import subprocess import platform import textwrap import contextlib import warnings from distutils import log try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen try: from site import USER_SITE except ImportError: USER_SITE = None DEFAULT_VERSION = "18.0.1" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" DEFAULT_SAVE_DIR = os.curdir def _python_cmd(*args): """ Execute a command. Return True if the command succeeded. """ args = (sys.executable,) + args return subprocess.call(args) == 0 def _install(archive_filename, install_args=()): """Install Setuptools.""" with archive_context(archive_filename): # installing log.warn('Installing Setuptools') if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') # exitcode will be 2 return 2 def _build_egg(egg, archive_filename, to_dir): """Build Setuptools egg.""" with archive_context(archive_filename): # building an egg log.warn('Building a Setuptools egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') class ContextualZipFile(zipfile.ZipFile): """Supplement ZipFile class to support context manager for Python 2.6.""" def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() def __new__(cls, *args, **kwargs): """Construct a ZipFile or ContextualZipFile as appropriate.""" if hasattr(zipfile.ZipFile, '__exit__'): return zipfile.ZipFile(*args, **kwargs) return super(ContextualZipFile, cls).__new__(cls) @contextlib.contextmanager def archive_context(filename): """ Unzip filename to a temporary directory, set to the cwd. The unzipped target is cleaned up after. """ tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) with ContextualZipFile(filename) as archive: archive.extractall() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) yield finally: os.chdir(old_wd) shutil.rmtree(tmpdir) def _do_download(version, download_base, to_dir, download_delay): """Download Setuptools.""" egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): archive = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, archive, to_dir) sys.path.insert(0, egg) # Remove previously-imported pkg_resources if present (see # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). if 'pkg_resources' in sys.modules: del sys.modules['pkg_resources'] import setuptools setuptools.bootstrap_install_from = egg def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=DEFAULT_SAVE_DIR, download_delay=15): """ Ensure that a setuptools version is installed. Return None. Raise SystemExit if the requested version or later cannot be installed. """ to_dir = os.path.abspath(to_dir) # prior to importing, capture the module state for # representative modules. rep_modules = 'pkg_resources', 'setuptools' imported = set(sys.modules).intersection(rep_modules) try: import pkg_resources pkg_resources.require("setuptools>=" + version) # a suitable version is already installed return except ImportError: # pkg_resources not available; setuptools is not installed; download pass except pkg_resources.DistributionNotFound: # no version of setuptools was found; allow download pass except pkg_resources.VersionConflict as VC_err: if imported: _conflict_bail(VC_err, version) # otherwise, unload pkg_resources to allow the downloaded version to # take precedence. del pkg_resources _unload_pkg_resources() return _do_download(version, download_base, to_dir, download_delay) def _conflict_bail(VC_err, version): """ Setuptools was imported prior to invocation, so it is unsafe to unload it. Bail out. """ conflict_tmpl = textwrap.dedent(""" The required version of setuptools (>={version}) is not available, and can't be installed while this script is running. Please install a more recent version first, using 'easy_install -U setuptools'. (Currently using {VC_err.args[0]!r}) """) msg = conflict_tmpl.format(**locals()) sys.stderr.write(msg) sys.exit(2) def _unload_pkg_resources(): del_modules = [ name for name in sys.modules if name.startswith('pkg_resources') ] for mod_name in del_modules: del sys.modules[mod_name] def _clean_check(cmd, target): """ Run the command to download target. If the command fails, clean up before re-raising the error. """ try: subprocess.check_call(cmd) except subprocess.CalledProcessError: if os.access(target, os.F_OK): os.unlink(target) raise def download_file_powershell(url, target): """ Download the file at url to target using Powershell. Powershell will validate trust. Raise an exception if the command cannot complete. """ target = os.path.abspath(target) ps_cmd = ( "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " "[System.Net.CredentialCache]::DefaultCredentials; " "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars() ) cmd = [ 'powershell', '-Command', ps_cmd, ] _clean_check(cmd, target) def has_powershell(): """Determine if Powershell is available.""" if platform.system() != 'Windows': return False cmd = ['powershell', '-Command', 'echo test'] with open(os.path.devnull, 'wb') as devnull: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except Exception: return False return True download_file_powershell.viable = has_powershell def download_file_curl(url, target): cmd = ['curl', url, '--silent', '--output', target] _clean_check(cmd, target) def has_curl(): cmd = ['curl', '--version'] with open(os.path.devnull, 'wb') as devnull: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except Exception: return False return True download_file_curl.viable = has_curl def download_file_wget(url, target): cmd = ['wget', url, '--quiet', '--output-document', target] _clean_check(cmd, target) def has_wget(): cmd = ['wget', '--version'] with open(os.path.devnull, 'wb') as devnull: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except Exception: return False return True download_file_wget.viable = has_wget def download_file_insecure(url, target): """Use Python to download the file, without connection authentication.""" src = urlopen(url) try: # Read all the data in one block. data = src.read() finally: src.close() # Write all the data in one block to avoid creating a partial file. with open(target, "wb") as dst: dst.write(data) download_file_insecure.viable = lambda: True def get_best_downloader(): downloaders = ( download_file_powershell, download_file_curl, download_file_wget, download_file_insecure, ) viable_downloaders = (dl for dl in downloaders if dl.viable()) return next(viable_downloaders, None) def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=DEFAULT_SAVE_DIR, delay=15, downloader_factory=get_best_downloader): """ Download setuptools from a specified location and return its filename. `version` should be a valid setuptools version number that is available as an sdist for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. ``downloader_factory`` should be a function taking no arguments and returning a function for downloading a URL to a target. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) zip_name = "setuptools-%s.zip" % version url = download_base + zip_name saveto = os.path.join(to_dir, zip_name) if not os.path.exists(saveto): # Avoid repeated downloads log.warn("Downloading %s", url) downloader = downloader_factory() downloader(url, saveto) return os.path.realpath(saveto) def _build_install_args(options): """ Build the arguments to 'python setup.py install' on the setuptools package. Returns list of command line arguments. """ return ['--user'] if options.user_install else [] def _parse_args(): """Parse the command line for options.""" parser = optparse.OptionParser() parser.add_option( '--user', dest='user_install', action='store_true', default=False, help='install in user site package (requires Python 2.6 or later)') parser.add_option( '--download-base', dest='download_base', metavar="URL", default=DEFAULT_URL, help='alternative URL from where to download the setuptools package') parser.add_option( '--insecure', dest='downloader_factory', action='store_const', const=lambda: download_file_insecure, default=get_best_downloader, help='Use internal, non-validating downloader' ) parser.add_option( '--version', help="Specify which version to download", default=DEFAULT_VERSION, ) parser.add_option( '--to-dir', help="Directory to save (and re-use) package", default=DEFAULT_SAVE_DIR, ) options, args = parser.parse_args() # positional arguments are ignored return options def _download_args(options): """Return args for download_setuptools function from cmdline args.""" return dict( version=options.version, download_base=options.download_base, downloader_factory=options.downloader_factory, to_dir=options.to_dir, ) def main(): """Install or upgrade setuptools and EasyInstall.""" options = _parse_args() archive = download_setuptools(**_download_args(options)) return _install(archive, _build_install_args(options)) if __name__ == '__main__': sys.exit(main()) d2to1-0.2.12/README.rst0000644001134200020070000001177312551554501015134 0ustar embrayscience00000000000000Introduction ============== .. image:: https://travis-ci.org/embray/d2to1.png?branch=master :alt: travis build status :target: https://travis-ci.org/embray/d2to1 d2to1 (the 'd' is for 'distutils') allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py script. It works by providing a distutils2-formatted setup.cfg file containing all of a package's metadata, and a very minimal setup.py which will slurp its arguments from the setup.cfg. Note: distutils2 has been merged into the CPython standard library, where it is now known as 'packaging'. This project was started before that change was finalized. So all references to distutils2 should also be assumed to refer to packaging. Rationale =========== I'm currently in the progress of redoing the packaging of a sizeable number of projects. I wanted to use distutils2-like setup.cfg files for all these projects, as they will hopefully be the future, and I much prefer them overall to using an executable setup.py. So forward-support for distutils2 is appealing both as future-proofing, and simply the aesthetics of using a flat text file to describe a project's metadata. However, I did not want any of these projects to require distutils2 for installation yet--it is too unstable, and not widely installed. So projects should still be installable using the familiar `./setup.py install`, for example. Furthermore, not all use cases required by some of the packages I support are fully supported by distutils2 yet. Hopefully they will be eventually, either through the distutils2 core or through extensions. But in the meantime d2to1 will try to keep up with the state of the art and "best practices" for distutils2 distributions, while adding support in areas that it's lacking. Usage ======= d2to1 requires a distribution to use distribute or setuptools. Your distribution must include a distutils2-like setup.cfg file, and a minimal setup.py script. For details on writing the setup.cfg, see the `distutils2 documentation`_. A simple sample can be found in d2to1's own setup.cfg (it uses its own machinery to install itself):: [metadata] name = d2to1 version = 0.2.12 author = Erik M. Bray author-email = embray@stsci.edu summary = Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py description-file = README.rst CHANGES.rst home-page = http://pypi.python.org/pypi/d2to1 requires-dist = setuptools classifier = Development Status :: 5 - Production/Stable Environment :: Plugins Framework :: Setuptools Plugin Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = d2to1 d2to1.extern extra_files = CHANGES.rst LICENSE ez_setup.py [backwards_compat] zip-safe = False tests-require = nose [entry_points] distutils.setup_keywords = d2to1 = d2to1.core:d2to1 zest.releaser.prereleaser.middle = d2_version = d2to1.zestreleaser:prereleaser_middle zest.releaser.postreleaser.middle = d2_version = d2to1.zestreleaser:postreleaser_middle The minimal setup.py should look something like this:: #!/usr/bin/env python try: from setuptools import setup except ImportError: from distribute_setup import use_setuptools use_setuptools() from setuptools import setup setup( setup_requires=['d2to1'], d2to1=True ) Note that it's important to specify d2to1=True or else the d2to1 functionality will not be enabled. It is also possible to set d2to1='some_file.cfg' to specify the (relative) path of the setup.cfg file to use. But in general this functionality should not be necessary. It should also work fine if additional arguments are passed to `setup()`, but it should be noted that they will be clobbered by any options in the setup.cfg file. Caveats ======= - The requires-dist option in setup.cfg is implemented through the distribute/setuptools install_requires option, rather than the broken "requires" keyword in normal distutils. - Not all features of distutils2 are supported yet. If something doesn't seem to be working, it's probably not implemented yet. - Does not support distutils2 resources, and probably won't since it relies heavily on the sysconfig module only available in Python 3.2 and up. This is one area in which d2to1 should really be seen as a transitional tool. I don't really want to include a backport like distutils2 does. In the meantime, package_data and data_files may still be used under the [files] section of setup.cfg. .. _distutils2 documentation: http://alexis.notmyidea.org/distutils2/setupcfg.html d2to1-0.2.12/d2to1.egg-info/0000755001134200020070000000000012551770444016065 5ustar embrayscience00000000000000d2to1-0.2.12/d2to1.egg-info/not-zip-safe0000644001134200020070000000000112551770432020310 0ustar embrayscience00000000000000 d2to1-0.2.12/d2to1.egg-info/top_level.txt0000644001134200020070000000000612551770444020613 0ustar embrayscience00000000000000d2to1 d2to1-0.2.12/d2to1.egg-info/entry_points.txt0000644001134200020070000000050612551770444021364 0ustar embrayscience00000000000000[distutils.setup_keywords] d2to1 = d2to1.core:d2to1 [zest.releaser.postreleaser.before] d2to1_dev_version = d2to1.zestreleaser:postreleaser_before [zest.releaser.prereleaser.before] d2to1_version = d2to1.zestreleaser:prereleaser_before [zest.releaser.releaser.middle] d2to1_git_tag = d2to1.zestreleaser:prereleaser_middle d2to1-0.2.12/d2to1.egg-info/SOURCES.txt0000644001134200020070000000062512551770444017754 0ustar embrayscience00000000000000CHANGES.rst CONTRIBUTORS LICENSE README.rst ez_setup.py ez_setup25.py setup.cfg setup.py d2to1/__init__.py d2to1/core.py d2to1/util.py d2to1/zestreleaser.py d2to1.egg-info/PKG-INFO d2to1.egg-info/SOURCES.txt d2to1.egg-info/dependency_links.txt d2to1.egg-info/entry_points.txt d2to1.egg-info/not-zip-safe d2to1.egg-info/requires.txt d2to1.egg-info/top_level.txt d2to1/extern/__init__.py d2to1/extern/six.pyd2to1-0.2.12/d2to1.egg-info/dependency_links.txt0000644001134200020070000000000112551770444022133 0ustar embrayscience00000000000000 d2to1-0.2.12/d2to1.egg-info/requires.txt0000644001134200020070000000001312551770444020457 0ustar embrayscience00000000000000setuptools d2to1-0.2.12/d2to1.egg-info/PKG-INFO0000644001134200020070000004320612551770444017167 0ustar embrayscience00000000000000Metadata-Version: 1.1 Name: d2to1 Version: 0.2.12 Summary: Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py Home-page: http://pypi.python.org/pypi/d2to1 Author: Erik M. Bray Author-email: embray@stsci.edu License: UNKNOWN Description: Introduction ============== .. image:: https://travis-ci.org/embray/d2to1.png?branch=master :alt: travis build status :target: https://travis-ci.org/embray/d2to1 d2to1 (the 'd' is for 'distutils') allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py script. It works by providing a distutils2-formatted setup.cfg file containing all of a package's metadata, and a very minimal setup.py which will slurp its arguments from the setup.cfg. Note: distutils2 has been merged into the CPython standard library, where it is now known as 'packaging'. This project was started before that change was finalized. So all references to distutils2 should also be assumed to refer to packaging. Rationale =========== I'm currently in the progress of redoing the packaging of a sizeable number of projects. I wanted to use distutils2-like setup.cfg files for all these projects, as they will hopefully be the future, and I much prefer them overall to using an executable setup.py. So forward-support for distutils2 is appealing both as future-proofing, and simply the aesthetics of using a flat text file to describe a project's metadata. However, I did not want any of these projects to require distutils2 for installation yet--it is too unstable, and not widely installed. So projects should still be installable using the familiar `./setup.py install`, for example. Furthermore, not all use cases required by some of the packages I support are fully supported by distutils2 yet. Hopefully they will be eventually, either through the distutils2 core or through extensions. But in the meantime d2to1 will try to keep up with the state of the art and "best practices" for distutils2 distributions, while adding support in areas that it's lacking. Usage ======= d2to1 requires a distribution to use distribute or setuptools. Your distribution must include a distutils2-like setup.cfg file, and a minimal setup.py script. For details on writing the setup.cfg, see the `distutils2 documentation`_. A simple sample can be found in d2to1's own setup.cfg (it uses its own machinery to install itself):: [metadata] name = d2to1 version = 0.2.12 author = Erik M. Bray author-email = embray@stsci.edu summary = Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py description-file = README.rst CHANGES.rst home-page = http://pypi.python.org/pypi/d2to1 requires-dist = setuptools classifier = Development Status :: 5 - Production/Stable Environment :: Plugins Framework :: Setuptools Plugin Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = d2to1 d2to1.extern extra_files = CHANGES.rst LICENSE ez_setup.py [backwards_compat] zip-safe = False tests-require = nose [entry_points] distutils.setup_keywords = d2to1 = d2to1.core:d2to1 zest.releaser.prereleaser.middle = d2_version = d2to1.zestreleaser:prereleaser_middle zest.releaser.postreleaser.middle = d2_version = d2to1.zestreleaser:postreleaser_middle The minimal setup.py should look something like this:: #!/usr/bin/env python try: from setuptools import setup except ImportError: from distribute_setup import use_setuptools use_setuptools() from setuptools import setup setup( setup_requires=['d2to1'], d2to1=True ) Note that it's important to specify d2to1=True or else the d2to1 functionality will not be enabled. It is also possible to set d2to1='some_file.cfg' to specify the (relative) path of the setup.cfg file to use. But in general this functionality should not be necessary. It should also work fine if additional arguments are passed to `setup()`, but it should be noted that they will be clobbered by any options in the setup.cfg file. Caveats ======= - The requires-dist option in setup.cfg is implemented through the distribute/setuptools install_requires option, rather than the broken "requires" keyword in normal distutils. - Not all features of distutils2 are supported yet. If something doesn't seem to be working, it's probably not implemented yet. - Does not support distutils2 resources, and probably won't since it relies heavily on the sysconfig module only available in Python 3.2 and up. This is one area in which d2to1 should really be seen as a transitional tool. I don't really want to include a backport like distutils2 does. In the meantime, package_data and data_files may still be used under the [files] section of setup.cfg. .. _distutils2 documentation: http://alexis.notmyidea.org/distutils2/setupcfg.html Changes ========= 0.2.12 (2015-07-16) ------------------- - Fixed a corner case where depending on the order of events when installing multiple packages (i.e. when installing packages with dependencies, some of which might also use d2to1) we would end up calling the incorrect Distribution class (the patched version from setuptools, where d2to1 needs to get to the unpatched version from distutils for some cases). - Upgraded bundled copy of the ``six`` module to the current version (1.9.0). This fixes incompatibility between d2to1 and other packages that import different versions of ``six`` during their setup (the older version of ``six`` had a habit of fighting with other ``six`` instances over ``sys.modules``, which is fixed in newer versions). - Upgraded to latest ``ez_setup.py`` so that the most up to date version of setuptools will be correctly bootstrapped in the rare cases that it is needed. - Included some miscellaneous hacks to keep d2to1 working, nominally, with Python 2.5 despite the broad move away from Python 2.5 support in the Python community. The d2to1 v0.2.x releases will be the last to continue Python 2.5 support, given that testing it has become more difficult (and the overhead is probably no longer worth it). 0.2.11 (2013-08-29) ------------------- - Replaced ``distribute_setup.py`` with ``ez_setup.py`` in order to bootstrap with modern setuptools when necessary. - Fixed a couple minor Python 3-specific issues. In particular the ``data_files`` option could be passed to ``setup()`` as a ``dict_items`` object instead of a ``list`` which is what would normally be expected. - Added a tox.ini (frankly I thought there already was one). 0.2.10 (2013-04-10) ------------------- - Added support for the ``setup-requires-dist`` option in the ``[metadata]`` section of setup.cfg. This is analogous to the Setup-Requires-Dist metadata field supported by PEP-426 and uses the ``setup_requires`` argument to setuptools' ``setup()`` to implement it. - Added support for the ``dependency_links`` and ``include_package_data`` arguments to setuptools' ``setup()`` in the ``[backwards_compat]`` section of setup.cfg. - When a setup_hook calls sys.exit() don't show a traceback for the SystemExit exception. - Fixed a bug in the exception formatting when exceptions occur in setup.cfg handling. 0.2.9 (2013-03-05) ------------------ - Fixed a bug in the extra-files supported added in 0.2.8. Makes sure that monkey-patches can't be installed more than once and that the log reference is properly encapsulated. 0.2.8 (2013-03-05) ------------------ - Improved handling of packages where the packages_root option is set. That is, the Python package is not directly in the root of the source tree, but is in some sub-directory. Now the packages_root directory is prepended to sys.path while processing the setup.cfg and running setup hooks. - Added support for the Keywords metadata field via the keywords option in the ``[metadata]`` section of setup.cfg. - Fixed a missing import that caused a misleading exception when setup.cfg is missing. - Upgraded the shipped distribute_setup.py to the latest for distribute 0.6.28 - Added a few basic functional tests, along with an infrastructure to add more as needed. They can be run with nose and possibly with py.test though the latter hasn't been tested. - Improved hook imports to work better with namespace packages. - Added support for the extra_files option of the ``[files]`` section in setup.cfg. This was a feature from distutils2 that provided an alternative to MANIFEST.in for including additional files in source distributions (it does not yet support wildcard patterns but maybe it should?) - Added support for the tests_require setup argument from setuptools via the [backwards_compat] section in setup.cfg. - Supports Python 3 natively without 2to3. This makes Python 3 testing of d2to1 easier to support. 0.2.7 (2012-02-20) ------------------ - If no extension modules or entry points are defined in the setup.cfg, don't clobber any extension modules/entry points that may be defined in setup.py. 0.2.6 (2012-02-17) ------------------ - Added support for setuptools entry points in an ``[entry_points]`` section of setup.cfg--this is just for backwards-compatibility purposes, as packaging/distutils2 does not yet have a standard replacement for the entry points system. - Added a [backwards_compat] section for setup.cfg for other options that are supported by setuptools/distribute, but that aren't part of the distutils2 standard. So far the only options supported here are zip_safe and use_2to3. (Note: packaging does support a use-2to3 option to the build command, but if we tried to use that, distutils would not recognize it as a valid build option.) - Added support for the new (and presumably final) extension section format used by packaging. In this format, extensions should be specified in config sections of the format ``[extension: ext_mod_name]``, where any whitespace is optional. The old format used an ``=`` instead of ``:`` and is still supported, but should be considered deprecated. - Added support for the new syntax used by packaging for the package_data option (which is deprecated in packaging in favor of the resources system, but still supported). The new syntax is like:: package_data = packagename = pattern1 pattern2 pattern3 packagename.subpack = pattern1 pattern2 pattern3 That is, after ``package_data =``, give the name of a package, followed by an ``=``, followed by any number of whitespace separated wildcard patterns (or actual filenames relative to the package). Under this scheme, whitespace is not allowed in the patterns themselves. 0.2.5 (2011-07-21) ------------------ - Made the call to pkg_resources.get_distribution() to set __version__ more robust, so that it doesn't fail on, for example, VersionConflict errors 0.2.4 (2011-07-05) ------------------ - Fixed some bugs with installation on Python 3 0.2.3 (2011-06-23) ------------------ - Renamed 'setup_hook' to 'setup_hooks' as is now the case in the packaging module. Added support for multiple setup_hooks 0.2.2 (2011-06-15) ------------------ - Fixed a bug in DefaultGetDict where it didn't actually save the returned default in the dictionary--so any command options would get lost - Fixed a KeyError when the distribution does not have any custom commands specified 0.2.1 (2011-06-15) ------------------ - Reimplemented command hooks without monkey-patching and more reliably in general (though it's still a flaming hack). The previous monkey patch-based solution would break if d2to1 were entered multiple times, which could happen in some scenarios 0.2.0 (2011-06-14) ------------------ - Version bump to start using micro-version numbers for bug fixes only, now that the my primary feature goals are complete 0.1.5 (2011-06-02) ------------------ - Adds support for the data_files option under [files]. Though this is considered deprecated and may go away at some point, it can be useful in the absence of resources support - Adds support for command pre/post-hooks. Warning: this monkey-patches distutils.dist.Distribution a little bit... :( - Adds (slightly naive) support for PEP 345-style version specifiers in requires-dist (environment markers not supported yet) - Fixed a bug where not enough newlines were inserted between description files 0.1.4 (2011-05-24) ------------------ - Adds support for custom command classes specified in the 'commands' option under the [global] section in setup.cfg - Adds preliminary support for custom compilers specified in the 'compilers' option under the [global] section in setup.cfg. This functionality doesn't exist in distutils/setuptools/distribute, so adding support for it is a flaming hack. It hasn't really been tested beyond seeing that the custom compilers come up in `setup.py build_ext --help-compiler`, so any real-world testing of this feature would be appreciated 0.1.3 (2011-04-20) ------------------ - Adds zest.releaser entry points for updating the version number in a setup.cfg file; only useful if you use zest.releaser--otherwise harmless (might eventually move this functionality out into a separate product) - Though version 0.1.2 worked in Python3, use_2to3 wasn't added to the setup.py so 2to3 had to be run manually - Fixed a crash on projects that don't have a description-file option 0.1.2 (2011-04-13) ------------------ - Fixed the self-installation--it did not work if a d2to1 version was not already installed, due to the use of `pkg_resources.require()` - Adds nominal Python3 support - Fixes the 'classifier' option in setup.cfg 0.1.1 (2011-04-12) ------------------ - Fixed an unhelpful error message when a setup_hook fails to import - Made d2to1 able to use its own machinery to install itself Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Plugins Classifier: Framework :: Setuptools Plugin Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging d2to1-0.2.12/CONTRIBUTORS0000644001134200020070000000007312131301561015302 0ustar embrayscience00000000000000Erik M. Bray Mark Sienkiewicz Monty Taylor Thomas Grainger d2to1-0.2.12/LICENSE0000644001134200020070000000267612112744301014444 0ustar embrayscience00000000000000Copyright (C) 2013 Association of Universities for Research in Astronomy (AURA) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of AURA and its representatives may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. d2to1-0.2.12/setup.py0000755001134200020070000000065012551770254015157 0ustar embrayscience00000000000000#!/usr/bin/env python try: from setuptools import setup except ImportError: import sys if sys.version_info[:2] < (2, 6): from ez_setup25 import use_setuptools else: from ez_setup import use_setuptools use_setuptools() from setuptools import setup # d2to1 basically installs itself! See setup.cfg for the project metadata. from d2to1.util import cfg_to_args setup(**cfg_to_args()) d2to1-0.2.12/setup.cfg0000644001134200020070000000306212551770444015264 0ustar embrayscience00000000000000[metadata] name = d2to1 version = 0.2.12 author = Erik M. Bray author-email = embray@stsci.edu summary = Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py description-file = README.rst CHANGES.rst home-page = http://pypi.python.org/pypi/d2to1 requires-dist = setuptools classifier = Development Status :: 5 - Production/Stable Environment :: Plugins Framework :: Setuptools Plugin Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = d2to1 d2to1.extern extra_files = CHANGES.rst CONTRIBUTORS LICENSE ez_setup.py ez_setup25.py [backwards_compat] zip-safe = False tests-require = nose [entry_points] distutils.setup_keywords = d2to1 = d2to1.core:d2to1 zest.releaser.prereleaser.before = d2to1_version = d2to1.zestreleaser:prereleaser_before zest.releaser.releaser.middle = d2to1_git_tag = d2to1.zestreleaser:prereleaser_middle zest.releaser.postreleaser.before = d2to1_dev_version = d2to1.zestreleaser:postreleaser_before [test] test-suite = nose.collector [zest.releaser] prereleaser.before = d2to1.zestreleaser.prereleaser_before releaser.middle = d2to1.zestreleaser.releaser_middle postreleaser.before = d2to1.zestreleaser.postreleaser_before [egg_info] tag_svn_revision = 0 tag_build = tag_date = 0 d2to1-0.2.12/d2to1/0000755001134200020070000000000012551770444014373 5ustar embrayscience00000000000000d2to1-0.2.12/d2to1/util.py0000644001134200020070000004773312207723325015732 0ustar embrayscience00000000000000"""The code in this module is mostly copy/pasted out of the distutils2 source code, as recommended by Tarek Ziade. As such, it may be subject to some change as distutils2 development continues, and will have to be kept up to date. I didn't want to use it directly from distutils2 itself, since I do not want it to be an installation dependency for our packages yet--it is still too unstable (the latest version on PyPI doesn't even install). """ # These first two imports are not used, but are needed to get around an # irritating Python bug that can crop up when using ./setup.py test. # See: http://www.eby-sarna.com/pipermail/peak/2010-May/003355.html try: import multiprocessing except ImportError: pass import logging import os import re import sys import traceback from collections import defaultdict import distutils.ccompiler from distutils import log from distutils.errors import (DistutilsOptionError, DistutilsModuleError, DistutilsFileError) from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution from setuptools.extension import Extension from .extern.six import moves as m RawConfigParser = m.configparser.RawConfigParser # A simplified RE for this; just checks that the line ends with version # predicates in () _VERSION_SPEC_RE = re.compile(r'\s*(.*?)\s*\((.*)\)\s*$') # Mappings from setup() keyword arguments to setup.cfg options; # The values are (section, option) tuples, or simply (section,) tuples if # the option has the same name as the setup() argument D1_D2_SETUP_ARGS = { "name": ("metadata",), "version": ("metadata",), "author": ("metadata",), "author_email": ("metadata",), "maintainer": ("metadata",), "maintainer_email": ("metadata",), "url": ("metadata", "home_page"), "description": ("metadata", "summary"), "keywords": ("metadata",), "long_description": ("metadata", "description"), "download-url": ("metadata",), "classifiers": ("metadata", "classifier"), "platforms": ("metadata", "platform"), # ** "license": ("metadata",), # Use setuptools install_requires, not # broken distutils requires "install_requires": ("metadata", "requires_dist"), "setup_requires": ("metadata", "setup_requires_dist"), "provides": ("metadata", "provides_dist"), # ** "obsoletes": ("metadata", "obsoletes_dist"), # ** "package_dir": ("files", 'packages_root'), "packages": ("files",), "package_data": ("files",), "data_files": ("files",), "scripts": ("files",), "py_modules": ("files", "modules"), # ** "cmdclass": ("global", "commands"), # Not supported in distutils2, but provided for # backwards compatibility with setuptools "use_2to3": ("backwards_compat", "use_2to3"), "zip_safe": ("backwards_compat", "zip_safe"), "tests_require": ("backwards_compat", "tests_require"), "dependency_links": ("backwards_compat",), "include_package_data": ("backwards_compat",), } # setup() arguments that can have multiple values in setup.cfg MULTI_FIELDS = ("classifiers", "platforms", "install_requires", "provides", "obsoletes", "packages", "package_data", "data_files", "scripts", "py_modules", "dependency_links", "setup_requires", "tests_require", "cmdclass") # setup() arguments that contain boolean values BOOL_FIELDS = ("use_2to3", "zip_safe", "include_package_data") CSV_FIELDS = ("keywords",) log.set_verbosity(log.INFO) def resolve_name(name): """Resolve a name like ``module.object`` to an object and return it. Raise ImportError if the module or name is not found. """ parts = name.split('.') cursor = len(parts) - 1 module_name = parts[:cursor] attr_name = parts[-1] while cursor > 0: try: ret = __import__('.'.join(module_name), fromlist=[attr_name]) break except ImportError: if cursor == 0: raise cursor -= 1 module_name = parts[:cursor] attr_name = parts[cursor] ret = '' for part in parts[cursor:]: try: ret = getattr(ret, part) except AttributeError: raise ImportError(name) return ret def cfg_to_args(path='setup.cfg'): """ Distutils2 to distutils1 compatibility util. This method uses an existing setup.cfg to generate a dictionary of keywords that can be used by distutils.core.setup(kwargs**). :param file: The setup.cfg path. :raises DistutilsFileError: When the setup.cfg file is not found. """ # The method source code really starts here. parser = RawConfigParser() if not os.path.exists(path): raise DistutilsFileError("file '%s' does not exist" % os.path.abspath(path)) parser.read(path) config = {} for section in parser.sections(): config[section] = dict(parser.items(section)) # Run setup_hooks, if configured setup_hooks = has_get_option(config, 'global', 'setup_hooks') package_dir = has_get_option(config, 'files', 'packages_root') # Add the source package directory to sys.path in case it contains # additional hooks, and to make sure it's on the path before any existing # installations of the package if package_dir: package_dir = os.path.abspath(package_dir) sys.path.insert(0, package_dir) try: if setup_hooks: setup_hooks = split_multiline(setup_hooks) for hook in setup_hooks: hook_fn = resolve_name(hook) try : hook_fn(config) except SystemExit: log.error('setup hook %s terminated the installation') except: e = sys.exc_info()[1] log.error('setup hook %s raised exception: %s\n' % (hook, e)) log.error(traceback.format_exc()) sys.exit(1) kwargs = setup_cfg_to_setup_kwargs(config) register_custom_compilers(config) ext_modules = get_extension_modules(config) if ext_modules: kwargs['ext_modules'] = ext_modules entry_points = get_entry_points(config) if entry_points: kwargs['entry_points'] = entry_points wrap_commands(kwargs) # Handle the [files]/extra_files option extra_files = has_get_option(config, 'files', 'extra_files') if extra_files: extra_files = split_multiline(extra_files) # Let's do a sanity check for filename in extra_files: if not os.path.exists(filename): raise DistutilsFileError( '%s from the extra_files option in setup.cfg does not ' 'exist' % filename) # Unfortunately the only really sensible way to do this is to # monkey-patch the manifest_maker class @monkeypatch_method(manifest_maker) def add_defaults(self, extra_files=extra_files, log=log): log.info('[d2to1] running patched manifest_maker command ' 'with extra_files support') add_defaults._orig(self) self.filelist.extend(extra_files) finally: # Perform cleanup if any paths were added to sys.path if package_dir: sys.path.pop(0) return kwargs def setup_cfg_to_setup_kwargs(config): """Processes the setup.cfg options and converts them to arguments accepted by setuptools' setup() function. """ kwargs = {} for arg in D1_D2_SETUP_ARGS: if len(D1_D2_SETUP_ARGS[arg]) == 2: # The distutils field name is different than distutils2's. section, option = D1_D2_SETUP_ARGS[arg] elif len(D1_D2_SETUP_ARGS[arg]) == 1: # The distutils field name is the same thant distutils2's. section = D1_D2_SETUP_ARGS[arg][0] option = arg in_cfg_value = has_get_option(config, section, option) if not in_cfg_value: # There is no such option in the setup.cfg if arg == "long_description": in_cfg_value = has_get_option(config, section, "description_file") if in_cfg_value: in_cfg_value = split_multiline(in_cfg_value) value = '' for filename in in_cfg_value: description_file = open(filename) try: value += description_file.read().strip() + '\n\n' finally: description_file.close() in_cfg_value = value else: continue if arg in CSV_FIELDS: in_cfg_value = split_csv(in_cfg_value) if arg in MULTI_FIELDS: in_cfg_value = split_multiline(in_cfg_value) elif arg in BOOL_FIELDS: # Provide some flexibility here... if in_cfg_value.lower() in ('true', 't', '1', 'yes', 'y'): in_cfg_value = True else: in_cfg_value = False if in_cfg_value: if arg in ('install_requires', 'tests_require'): # Replaces PEP345-style version specs with the sort expected by # setuptools in_cfg_value = [_VERSION_SPEC_RE.sub(r'\1\2', pred) for pred in in_cfg_value] elif arg == 'package_dir': in_cfg_value = {'': in_cfg_value} elif arg in ('package_data', 'data_files'): data_files = {} firstline = True prev = None for line in in_cfg_value: if '=' in line: key, value = line.split('=', 1) key, value = (key.strip(), value.strip()) if key in data_files: # Multiple duplicates of the same package name; # this is for backwards compatibility of the old # format prior to d2to1 0.2.6. prev = data_files[key] prev.extend(value.split()) else: prev = data_files[key.strip()] = value.split() elif firstline: raise DistutilsOptionError( 'malformed package_data first line %r (misses ' '"=")' % line) else: prev.extend(line.strip().split()) firstline = False if arg == 'data_files': # the data_files value is a pointlessly different structure # from the package_data value data_files = list(data_files.items()) in_cfg_value = data_files elif arg == 'cmdclass': cmdclass = {} dist = Distribution() for cls in in_cfg_value: cls = resolve_name(cls) cmd = cls(dist) cmdclass[cmd.get_command_name()] = cls in_cfg_value = cmdclass kwargs[arg] = in_cfg_value return kwargs def register_custom_compilers(config): """Handle custom compilers; this has no real equivalent in distutils, where additional compilers could only be added programmatically, so we have to hack it in somehow. """ compilers = has_get_option(config, 'global', 'compilers') if compilers: compilers = split_multiline(compilers) for compiler in compilers: compiler = resolve_name(compiler) # In distutils2 compilers these class attributes exist; for # distutils1 we just have to make something up if hasattr(compiler, 'name'): name = compiler.name else: name = compiler.__name__ if hasattr(compiler, 'description'): desc = compiler.description else: desc = 'custom compiler %s' % name module_name = compiler.__module__ # Note; this *will* override built in compilers with the same name # TODO: Maybe display a warning about this? cc = distutils.ccompiler.compiler_class cc[name] = (module_name, compiler.__name__, desc) # HACK!!!! Distutils assumes all compiler modules are in the # distutils package sys.modules['distutils.' + module_name] = sys.modules[module_name] def get_extension_modules(config): """Handle extension modules""" EXTENSION_FIELDS = ("sources", "include_dirs", "define_macros", "undef_macros", "library_dirs", "libraries", "runtime_library_dirs", "extra_objects", "extra_compile_args", "extra_link_args", "export_symbols", "swig_opts", "depends") ext_modules = [] for section in config: if ':' in section: labels = section.split(':', 1) else: # Backwards compatibility for old syntax; don't use this though labels = section.split('=', 1) labels = [l.strip() for l in labels] if (len(labels) == 2) and (labels[0] == 'extension'): ext_args = {} for field in EXTENSION_FIELDS: value = has_get_option(config, section, field) # All extension module options besides name can have multiple # values if not value: continue value = split_multiline(value) if field == 'define_macros': macros = [] for macro in value: macro = macro.split('=', 1) if len(macro) == 1: macro = (macro[0].strip(), None) else: macro = (macro[0].strip(), macro[1].strip()) macros.append(macro) value = macros ext_args[field] = value if ext_args: if 'name' not in ext_args: ext_args['name'] = labels[1] ext_modules.append(Extension(ext_args.pop('name'), **ext_args)) return ext_modules def get_entry_points(config): """Process the [entry_points] section of setup.cfg to handle setuptools entry points. This is, of course, not a standard feature of distutils2/packaging, but as there is not currently a standard alternative in packaging, we provide support for them. """ if not 'entry_points' in config: return {} return dict((option, split_multiline(value)) for option, value in config['entry_points'].items()) def wrap_commands(kwargs): dist = Distribution() # This should suffice to get the same config values and command classes # that the actual Distribution will see (not counting cmdclass, which is # handled below) dist.parse_config_files() for cmd, _ in dist.get_command_list(): hooks = {} for opt, val in dist.get_option_dict(cmd).items(): val = val[1] if opt.startswith('pre_hook.') or opt.startswith('post_hook.'): hook_type, alias = opt.split('.', 1) hook_dict = hooks.setdefault(hook_type, {}) hook_dict[alias] = val if not hooks: continue if 'cmdclass' in kwargs and cmd in kwargs['cmdclass']: cmdclass = kwargs['cmdclass'][cmd] else: cmdclass = dist.get_command_class(cmd) new_cmdclass = wrap_command(cmd, cmdclass, hooks) kwargs.setdefault('cmdclass', {})[cmd] = new_cmdclass def wrap_command(cmd, cmdclass, hooks): def run(self, cmdclass=cmdclass): self.run_command_hooks('pre_hook') cmdclass.run(self) self.run_command_hooks('post_hook') return type(cmd, (cmdclass, object), {'run': run, 'run_command_hooks': run_command_hooks, 'pre_hook': hooks.get('pre_hook'), 'post_hook': hooks.get('post_hook')}) def run_command_hooks(cmd_obj, hook_kind): """Run hooks registered for that command and phase. *cmd_obj* is a finalized command object; *hook_kind* is either 'pre_hook' or 'post_hook'. """ if hook_kind not in ('pre_hook', 'post_hook'): raise ValueError('invalid hook kind: %r' % hook_kind) hooks = getattr(cmd_obj, hook_kind, None) if hooks is None: return for hook in hooks.values(): if isinstance(hook, str): try: hook_obj = resolve_name(hook) except ImportError: err = sys.exc_info()[1] # For py3k raise DistutilsModuleError('cannot find hook %s: %s' % (hook,err)) else: hook_obj = hook if not hasattr(hook_obj, '__call__'): raise DistutilsOptionError('hook %r is not callable' % hook) log.info('running %s %s for command %s', hook_kind, hook, cmd_obj.get_command_name()) try : hook_obj(cmd_obj) except: e = sys.exc_info()[1] log.error('hook %s raised exception: %s\n' % (hook, e)) log.error(traceback.format_exc()) sys.exit(1) def has_get_option(config, section, option): if section in config and option in config[section]: return config[section][option] elif section in config and option.replace('_', '-') in config[section]: return config[section][option.replace('_', '-')] else: return False def split_multiline(value): """Special behaviour when we have a multi line options""" value = [element for element in (line.strip() for line in value.split('\n')) if element] return value def split_csv(value): """Special behaviour when we have a comma separated options""" value = [element for element in (chunk.strip() for chunk in value.split(',')) if element] return value def monkeypatch_method(cls): """A function decorator to monkey-patch a method of the same name on the given class. """ def wrapper(func): orig = getattr(cls, func.__name__, None) if orig and not hasattr(orig, '_orig'): # Already patched setattr(func, '_orig', orig) setattr(cls, func.__name__, func) return func return wrapper # The following classes are used to hack Distribution.command_options a bit class DefaultGetDict(defaultdict): """Like defaultdict, but the get() method also sets and returns the default value. """ def get(self, key, default=None): if default is None: default = self.default_factory() return super(DefaultGetDict, self).setdefault(key, default) class IgnoreDict(dict): """A dictionary that ignores any insertions in which the key is a string matching any string in `ignore`. The ignore list can also contain wildcard patterns using '*'. """ def __init__(self, ignore): self.__ignore = re.compile(r'(%s)' % ('|'.join( [pat.replace('*', '.*') for pat in ignore]))) def __setitem__(self, key, val): if self.__ignore.match(key): return super(IgnoreDict, self).__setitem__(key, val) d2to1-0.2.12/d2to1/core.py0000644001134200020070000000637512551540213015675 0ustar embrayscience00000000000000import os import sys import warnings from distutils.errors import DistutilsFileError, DistutilsSetupError from .extern import six from .util import DefaultGetDict, IgnoreDict, cfg_to_args def d2to1(dist, attr, value): """Implements the actual d2to1 setup() keyword. When used, this should be the only keyword in your setup() aside from `setup_requires`. If given as a string, the value of d2to1 is assumed to be the relative path to the setup.cfg file to use. Otherwise, if it evaluates to true, it simply assumes that d2to1 should be used, and the default 'setup.cfg' is used. This works by reading the setup.cfg file, parsing out the supported metadata and command options, and using them to rebuild the `DistributionMetadata` object and set the newly added command options. The reason for doing things this way is that a custom `Distribution` class will not play nicely with setup_requires; however, this implementation may not work well with distributions that do use a `Distribution` subclass. """ from distutils.core import Distribution from setuptools.dist import _get_unpatched _Distribution = _get_unpatched(Distribution) if not value: return if isinstance(value, six.string_types): path = os.path.abspath(value) else: path = os.path.abspath('setup.cfg') if not os.path.exists(path): raise DistutilsFileError( 'The setup.cfg file %s does not exist.' % path) # Converts the setup.cfg file to setup() arguments try: attrs = cfg_to_args(path) except: e = sys.exc_info()[1] raise DistutilsSetupError( 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e.args[0])) # Repeat some of the Distribution initialization code with the newly # provided attrs if attrs: # Skips 'options' and 'licence' support which are rarely used; may add # back in later if demanded for key, val in six.iteritems(attrs): if hasattr(dist.metadata, 'set_' + key): getattr(dist.metadata, 'set_' + key)(val) elif hasattr(dist.metadata, key): setattr(dist.metadata, key, val) elif hasattr(dist, key): setattr(dist, key, val) else: msg = 'Unknown distribution option: %s' % repr(key) warnings.warn(msg) # Re-finalize the underlying Distribution _Distribution.finalize_options(dist) # This bit comes out of distribute/setuptools if isinstance(dist.metadata.version, six.integer_types + (float,)): # Some people apparently take "version number" too literally :) dist.metadata.version = str(dist.metadata.version) # This bit of hackery is necessary so that the Distribution will ignore # normally unsupport command options (namely pre-hooks and post-hooks). # dist.command_options is normally a dict mapping command names to dicts of # their options. Now it will be a defaultdict that returns IgnoreDicts for # the each command's options so we can pass through the unsupported options ignore = ['pre_hook.*', 'post_hook.*'] dist.command_options = DefaultGetDict(lambda: IgnoreDict(ignore)) d2to1-0.2.12/d2to1/zestreleaser.py0000644001134200020070000001515412551770226017461 0ustar embrayscience00000000000000"""zest.releaser entry points to support projects using distutils2-like setup.cfg files. The only actual functionality this adds is to update the version option in a setup.cfg file, if it exists. If setup.cfg does not exist, or does not contain a version option, then this does nothing. TODO: d2to1 theoretically supports using a different filename for setup.cfg; this does not support that. We could hack in support, though I'm not sure how useful the original functionality is to begin with (and it might be removed) so we ignore that for now. TODO: There exists a proposal (http://mail.python.org/pipermail/distutils-sig/2011-March/017628.html) to add a 'version-from-file' option (or something of the like) to distutils2; if this is added then support for it should be included here as well. """ import logging import os from .extern.six import print_ from .extern.six import moves as m ConfigParser = m.configparser.ConfigParser logger = logging.getLogger(__name__) def prereleaser_before(data): # This monkey-patches the BaseVersionControl system class to support # getting and setting a version string from the setup.cfg file from zest.releaser.vcs import BaseVersionControl orig_extract_version = BaseVersionControl._extract_version orig_update_version = BaseVersionControl._update_version def _extract_version(self): return get_setupcfg_version() or orig_extract_version(self) def _update_version(self, version): if get_setupcfg_version(): update_setupcfg_version(version) return return orig_update_version(self, version) BaseVersionControl._extract_version = _extract_version BaseVersionControl._update_version = _update_version BaseVersionControl.version = property(_extract_version, _update_version) def get_setupcfg_version(): from zest.releaser.pypi import SetupConfig setup_cfg = SetupConfig() if setup_cfg.config.has_option('metadata', 'version'): return setup_cfg.config.get('metadata', 'version').strip() return '' def update_setupcfg_version(version): """Opens the given setup.cfg file, locates the version option in the [metadata] section, updates it to the new version. """ from zest.releaser.pypi import SetupConfig setup_cfg = SetupConfig() filename = setup_cfg.config_filename setup_cfg_lines = open(filename).readlines() current_section = None updated = False for idx, line in enumerate(setup_cfg_lines): m = ConfigParser.SECTCRE.match(line) if m: if current_section == 'metadata': # We already parsed the entire metadata section without finding # a version line, and are now moving into a new section break current_section = m.group('header') continue if '=' not in line: continue opt, val = line.split('=', 1) opt, val = opt.strip(), val.strip() if current_section == 'metadata' and opt == 'version': setup_cfg_lines[idx] = 'version = %s\n' % version updated = True break if updated: open(filename, 'w').writelines(setup_cfg_lines) logger.info("Set %s's version to %r" % (os.path.basename(filename), version)) def releaser_middle(data): """ releaser.middle hook to monkey-patch zest.releaser to support signed tagging--currently this is the only way to do this. Also monkey-patches to disable an annoyance where zest.releaser only creates .zip source distributions. This is supposedly a workaround for a bug in Python 2.4, but we don't care about Python 2.4. """ import os import sys from zest.releaser.git import Git from zest.releaser.release import Releaser # Copied verbatim from zest.releaser, but with the cmd string modified to # use the -s option to create a signed tag def _my_create_tag(self, version): msg = "Tagging %s" % (version,) cmd = 'git tag -s %s -m "%s"' % (version, msg) if os.path.isdir('.git/svn'): print_("\nEXPERIMENTAL support for git-svn tagging!\n") cur_branch = open('.git/HEAD').read().strip().split('/')[-1] print_("You are on branch %s." % (cur_branch,)) if cur_branch != 'master': print_("Only the master branch is supported for git-svn " "tagging.") print_("Please tag yourself.") print_("'git tag' needs to list tag named %s." % (version,)) sys.exit() cmd = [cmd] local_head = open('.git/refs/heads/master').read() trunk = open('.git/refs/remotes/trunk').read() if local_head != trunk: print_("Your local master diverges from trunk.\n") # dcommit before local tagging cmd.insert(0, 'git svn dcommit') # create tag in svn cmd.append('git svn tag -m "%s" %s' % (msg, version)) return cmd # Similarly copied from zer.releaser to support use of 'v' in front # of the version number def _my_make_tag(self): from zest.releaser import utils from os import system if self.data['tag_already_exists']: return cmds = self.vcs.cmd_create_tag(self.data['version']) if not isinstance(cmds, list): cmds = [cmds] if len(cmds) == 1: print_("Tag needed to proceed, you can use the following command:") for cmd in cmds: print_(cmd) if utils.ask("Run this command"): print_(system(cmd)) else: # all commands are needed in order to proceed normally print_("Please create a tag for %s yourself and rerun." % \ (self.data['version'],)) sys.exit() if not self.vcs.tag_exists(self.data['version']): print_("\nFailed to create tag %s!" % (self.data['version'],)) sys.exit() # Normally all this does is to return '--formats=zip', which is currently # hard-coded as an option to always add to the sdist command; they ought to # make this actually optional def _my_sdist_options(self): return '' Git.cmd_create_tag = _my_create_tag Releaser._make_tag = _my_make_tag Releaser._sdist_options = _my_sdist_options def postreleaser_before(data): """ Fix the irritating .dev0 default appended to new development versions by zest.releaser to just append ".dev" without the "0". """ data['dev_version_template'] = '%(new_version)s.dev' d2to1-0.2.12/d2to1/extern/0000755001134200020070000000000012551770444015700 5ustar embrayscience00000000000000d2to1-0.2.12/d2to1/extern/six.py0000644001134200020070000007174012551540213017053 0ustar embrayscience00000000000000"""Utilities for writing code that runs on Python 2 and 3""" # Copyright (c) 2010-2015 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import absolute_import import functools import itertools import operator import sys import types __author__ = "Benjamin Peterson " __version__ = "1.9.0" # Useful for very coarse version differentiation. PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 if PY3: string_types = str, integer_types = int, class_types = type, text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: string_types = basestring, integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode binary_type = str if sys.platform.startswith("java"): # Jython always uses 32 bits. MAXSIZE = int((1 << 31) - 1) else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). class X(object): def __len__(self): return 1 << 31 try: len(X()) except OverflowError: # 32-bit MAXSIZE = int((1 << 31) - 1) else: # 64-bit MAXSIZE = int((1 << 63) - 1) del X def _add_doc(func, doc): """Add documentation to a function.""" func.__doc__ = doc def _import_module(name): """Import module, returning the module after the last dot.""" __import__(name) return sys.modules[name] class _LazyDescr(object): def __init__(self, name): self.name = name def __get__(self, obj, tp): result = self._resolve() setattr(obj, self.name, result) # Invokes __set__. try: # This is a bit ugly, but it avoids running this again by # removing this descriptor. delattr(obj.__class__, self.name) except AttributeError: pass return result class MovedModule(_LazyDescr): def __init__(self, name, old, new=None): super(MovedModule, self).__init__(name) if PY3: if new is None: new = name self.mod = new else: self.mod = old def _resolve(self): return _import_module(self.mod) def __getattr__(self, attr): _module = self._resolve() value = getattr(_module, attr) setattr(self, attr, value) return value class _LazyModule(types.ModuleType): def __init__(self, name): super(_LazyModule, self).__init__(name) self.__doc__ = self.__class__.__doc__ def __dir__(self): attrs = ["__doc__", "__name__"] attrs += [attr.name for attr in self._moved_attributes] return attrs # Subclasses should override this _moved_attributes = [] class MovedAttribute(_LazyDescr): def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): super(MovedAttribute, self).__init__(name) if PY3: if new_mod is None: new_mod = name self.mod = new_mod if new_attr is None: if old_attr is None: new_attr = name else: new_attr = old_attr self.attr = new_attr else: self.mod = old_mod if old_attr is None: old_attr = name self.attr = old_attr def _resolve(self): module = _import_module(self.mod) return getattr(module, self.attr) class _SixMetaPathImporter(object): """ A meta path importer to import six.moves and its submodules. This class implements a PEP302 finder and loader. It should be compatible with Python 2.5 and all existing versions of Python3 """ def __init__(self, six_module_name): self.name = six_module_name self.known_modules = {} def _add_module(self, mod, *fullnames): for fullname in fullnames: self.known_modules[self.name + "." + fullname] = mod def _get_module(self, fullname): return self.known_modules[self.name + "." + fullname] def find_module(self, fullname, path=None): if fullname in self.known_modules: return self return None def __get_module(self, fullname): try: return self.known_modules[fullname] except KeyError: raise ImportError("This loader does not know module " + fullname) def load_module(self, fullname): try: # in case of a reload return sys.modules[fullname] except KeyError: pass mod = self.__get_module(fullname) if isinstance(mod, MovedModule): mod = mod._resolve() else: mod.__loader__ = self sys.modules[fullname] = mod return mod def is_package(self, fullname): """ Return true, if the named module is a package. We need this method to get correct spec objects with Python 3.4 (see PEP451) """ return hasattr(self.__get_module(fullname), "__path__") def get_code(self, fullname): """Return None Required, if is_package is implemented""" self.__get_module(fullname) # eventually raises ImportError return None get_source = get_code # same as get_code _importer = _SixMetaPathImporter(__name__) class _MovedItems(_LazyModule): """Lazy loading of moved objects""" __path__ = [] # mark as package _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("reload_module", "__builtin__", "imp", "reload"), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), MovedAttribute("UserDict", "UserDict", "collections"), MovedAttribute("UserList", "UserList", "collections"), MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), MovedModule("html_parser", "HTMLParser", "html.parser"), MovedModule("http_client", "httplib", "http.client"), MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), MovedModule("cPickle", "cPickle", "pickle"), MovedModule("queue", "Queue"), MovedModule("reprlib", "repr"), MovedModule("socketserver", "SocketServer"), MovedModule("_thread", "thread", "_thread"), MovedModule("tkinter", "Tkinter"), MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), MovedModule("tkinter_tix", "Tix", "tkinter.tix"), MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), MovedModule("winreg", "_winreg"), ] for attr in _moved_attributes: setattr(_MovedItems, attr.name, attr) if isinstance(attr, MovedModule): _importer._add_module(attr, "moves." + attr.name) del attr _MovedItems._moved_attributes = _moved_attributes moves = _MovedItems(__name__ + ".moves") _importer._add_module(moves, "moves") class Module_six_moves_urllib_parse(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_parse""" _urllib_parse_moved_attributes = [ MovedAttribute("ParseResult", "urlparse", "urllib.parse"), MovedAttribute("SplitResult", "urlparse", "urllib.parse"), MovedAttribute("parse_qs", "urlparse", "urllib.parse"), MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), MovedAttribute("urldefrag", "urlparse", "urllib.parse"), MovedAttribute("urljoin", "urlparse", "urllib.parse"), MovedAttribute("urlparse", "urlparse", "urllib.parse"), MovedAttribute("urlsplit", "urlparse", "urllib.parse"), MovedAttribute("urlunparse", "urlparse", "urllib.parse"), MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), MovedAttribute("quote", "urllib", "urllib.parse"), MovedAttribute("quote_plus", "urllib", "urllib.parse"), MovedAttribute("unquote", "urllib", "urllib.parse"), MovedAttribute("unquote_plus", "urllib", "urllib.parse"), MovedAttribute("urlencode", "urllib", "urllib.parse"), MovedAttribute("splitquery", "urllib", "urllib.parse"), MovedAttribute("splittag", "urllib", "urllib.parse"), MovedAttribute("splituser", "urllib", "urllib.parse"), MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), MovedAttribute("uses_params", "urlparse", "urllib.parse"), MovedAttribute("uses_query", "urlparse", "urllib.parse"), MovedAttribute("uses_relative", "urlparse", "urllib.parse"), ] for attr in _urllib_parse_moved_attributes: setattr(Module_six_moves_urllib_parse, attr.name, attr) del attr Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes _importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), "moves.urllib_parse", "moves.urllib.parse") class Module_six_moves_urllib_error(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_error""" _urllib_error_moved_attributes = [ MovedAttribute("URLError", "urllib2", "urllib.error"), MovedAttribute("HTTPError", "urllib2", "urllib.error"), MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), ] for attr in _urllib_error_moved_attributes: setattr(Module_six_moves_urllib_error, attr.name, attr) del attr Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes _importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), "moves.urllib_error", "moves.urllib.error") class Module_six_moves_urllib_request(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_request""" _urllib_request_moved_attributes = [ MovedAttribute("urlopen", "urllib2", "urllib.request"), MovedAttribute("install_opener", "urllib2", "urllib.request"), MovedAttribute("build_opener", "urllib2", "urllib.request"), MovedAttribute("pathname2url", "urllib", "urllib.request"), MovedAttribute("url2pathname", "urllib", "urllib.request"), MovedAttribute("getproxies", "urllib", "urllib.request"), MovedAttribute("Request", "urllib2", "urllib.request"), MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), MovedAttribute("BaseHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), MovedAttribute("FileHandler", "urllib2", "urllib.request"), MovedAttribute("FTPHandler", "urllib2", "urllib.request"), MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), MovedAttribute("urlretrieve", "urllib", "urllib.request"), MovedAttribute("urlcleanup", "urllib", "urllib.request"), MovedAttribute("URLopener", "urllib", "urllib.request"), MovedAttribute("FancyURLopener", "urllib", "urllib.request"), MovedAttribute("proxy_bypass", "urllib", "urllib.request"), ] for attr in _urllib_request_moved_attributes: setattr(Module_six_moves_urllib_request, attr.name, attr) del attr Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes _importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), "moves.urllib_request", "moves.urllib.request") class Module_six_moves_urllib_response(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_response""" _urllib_response_moved_attributes = [ MovedAttribute("addbase", "urllib", "urllib.response"), MovedAttribute("addclosehook", "urllib", "urllib.response"), MovedAttribute("addinfo", "urllib", "urllib.response"), MovedAttribute("addinfourl", "urllib", "urllib.response"), ] for attr in _urllib_response_moved_attributes: setattr(Module_six_moves_urllib_response, attr.name, attr) del attr Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes _importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), "moves.urllib_response", "moves.urllib.response") class Module_six_moves_urllib_robotparser(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_robotparser""" _urllib_robotparser_moved_attributes = [ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), ] for attr in _urllib_robotparser_moved_attributes: setattr(Module_six_moves_urllib_robotparser, attr.name, attr) del attr Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes _importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), "moves.urllib_robotparser", "moves.urllib.robotparser") class Module_six_moves_urllib(types.ModuleType): """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" __path__ = [] # mark as package parse = _importer._get_module("moves.urllib_parse") error = _importer._get_module("moves.urllib_error") request = _importer._get_module("moves.urllib_request") response = _importer._get_module("moves.urllib_response") robotparser = _importer._get_module("moves.urllib_robotparser") def __dir__(self): return ['parse', 'error', 'request', 'response', 'robotparser'] _importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib") def add_move(move): """Add an item to six.moves.""" setattr(_MovedItems, move.name, move) def remove_move(name): """Remove item from six.moves.""" try: delattr(_MovedItems, name) except AttributeError: try: del moves.__dict__[name] except KeyError: raise AttributeError("no such move, %r" % (name,)) if PY3: _meth_func = "__func__" _meth_self = "__self__" _func_closure = "__closure__" _func_code = "__code__" _func_defaults = "__defaults__" _func_globals = "__globals__" else: _meth_func = "im_func" _meth_self = "im_self" _func_closure = "func_closure" _func_code = "func_code" _func_defaults = "func_defaults" _func_globals = "func_globals" try: advance_iterator = next except NameError: def advance_iterator(it): return it.next() next = advance_iterator try: callable = callable except NameError: def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) if PY3: def get_unbound_function(unbound): return unbound create_bound_method = types.MethodType Iterator = object else: def get_unbound_function(unbound): return unbound.im_func def create_bound_method(func, obj): return types.MethodType(func, obj, obj.__class__) class Iterator(object): def next(self): return type(self).__next__(self) callable = callable _add_doc(get_unbound_function, """Get the function out of a possibly unbound function""") get_method_function = operator.attrgetter(_meth_func) get_method_self = operator.attrgetter(_meth_self) get_function_closure = operator.attrgetter(_func_closure) get_function_code = operator.attrgetter(_func_code) get_function_defaults = operator.attrgetter(_func_defaults) get_function_globals = operator.attrgetter(_func_globals) if PY3: def iterkeys(d, **kw): return iter(d.keys(**kw)) def itervalues(d, **kw): return iter(d.values(**kw)) def iteritems(d, **kw): return iter(d.items(**kw)) def iterlists(d, **kw): return iter(d.lists(**kw)) viewkeys = operator.methodcaller("keys") viewvalues = operator.methodcaller("values") viewitems = operator.methodcaller("items") else: def iterkeys(d, **kw): return iter(d.iterkeys(**kw)) def itervalues(d, **kw): return iter(d.itervalues(**kw)) def iteritems(d, **kw): return iter(d.iteritems(**kw)) def iterlists(d, **kw): return iter(d.iterlists(**kw)) viewkeys = operator.methodcaller("viewkeys") viewvalues = operator.methodcaller("viewvalues") viewitems = operator.methodcaller("viewitems") _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") _add_doc(iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary.") if PY3: def b(s): return s.encode("latin-1") def u(s): return s unichr = chr if sys.version_info[1] <= 1: def int2byte(i): return bytes((i,)) else: # This is about 2x faster than the implementation above on 3.2+ int2byte = operator.methodcaller("to_bytes", 1, "big") byte2int = operator.itemgetter(0) indexbytes = operator.getitem iterbytes = iter import io StringIO = io.StringIO BytesIO = io.BytesIO _assertCountEqual = "assertCountEqual" _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" else: def b(s): return s # Workaround for standalone backslash def u(s): return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") unichr = unichr int2byte = chr def byte2int(bs): return ord(bs[0]) def indexbytes(buf, i): return ord(buf[i]) iterbytes = functools.partial(itertools.imap, ord) import StringIO StringIO = BytesIO = StringIO.StringIO _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") def assertCountEqual(self, *args, **kwargs): return getattr(self, _assertCountEqual)(*args, **kwargs) def assertRaisesRegex(self, *args, **kwargs): return getattr(self, _assertRaisesRegex)(*args, **kwargs) def assertRegex(self, *args, **kwargs): return getattr(self, _assertRegex)(*args, **kwargs) if PY3: exec_ = getattr(moves.builtins, "exec") def reraise(tp, value, tb=None): if value is None: value = tp() if value.__traceback__ is not tb: raise value.with_traceback(tb) raise value else: def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: frame = sys._getframe(1) _globs_ = frame.f_globals if _locs_ is None: _locs_ = frame.f_locals del frame elif _locs_ is None: _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") exec_("""def reraise(tp, value, tb=None): raise tp, value, tb """) if sys.version_info[:2] == (3, 2): exec_("""def raise_from(value, from_value): if from_value is None: raise value raise value from from_value """) elif sys.version_info[:2] > (3, 2): exec_("""def raise_from(value, from_value): raise value from from_value """) else: def raise_from(value, from_value): raise value print_ = getattr(moves.builtins, "print", None) if print_ is None: def print_(*args, **kwargs): """The new-style print function for Python 2.4 and 2.5.""" fp = kwargs.pop("file", sys.stdout) if fp is None: return def write(data): if not isinstance(data, basestring): data = str(data) # If the file has an encoding, encode unicode with it. if (isinstance(fp, file) and isinstance(data, unicode) and fp.encoding is not None): errors = getattr(fp, "errors", None) if errors is None: errors = "strict" data = data.encode(fp.encoding, errors) fp.write(data) want_unicode = False sep = kwargs.pop("sep", None) if sep is not None: if isinstance(sep, unicode): want_unicode = True elif not isinstance(sep, str): raise TypeError("sep must be None or a string") end = kwargs.pop("end", None) if end is not None: if isinstance(end, unicode): want_unicode = True elif not isinstance(end, str): raise TypeError("end must be None or a string") if kwargs: raise TypeError("invalid keyword arguments to print()") if not want_unicode: for arg in args: if isinstance(arg, unicode): want_unicode = True break if want_unicode: newline = unicode("\n") space = unicode(" ") else: newline = "\n" space = " " if sep is None: sep = space if end is None: end = newline for i, arg in enumerate(args): if i: write(sep) write(arg) write(end) if sys.version_info[:2] < (3, 3): _print = print_ def print_(*args, **kwargs): fp = kwargs.get("file", sys.stdout) flush = kwargs.pop("flush", False) _print(*args, **kwargs) if flush and fp is not None: fp.flush() _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): f = functools.wraps(wrapped, assigned, updated)(f) f.__wrapped__ = wrapped return f return wrapper else: wraps = functools.wraps def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. class metaclass(meta): def __new__(cls, name, this_bases, d): return meta(name, bases, d) return type.__new__(metaclass, 'temporary_class', (), {}) def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method returning text and apply this decorator to the class. """ if PY2: if '__str__' not in klass.__dict__: raise ValueError("@python_2_unicode_compatible cannot be applied " "to %s because it doesn't define __str__()." % klass.__name__) klass.__unicode__ = klass.__str__ klass.__str__ = lambda self: self.__unicode__().encode('utf-8') return klass # Complete the moves implementation. # This code is at the end of this module to speed up module loading. # Turn this module into a package. __path__ = [] # required for PEP 302 and PEP 451 __package__ = __name__ # see PEP 366 @ReservedAssignment if globals().get("__spec__") is not None: __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable # Remove other six meta path importers, since they cause problems. This can # happen if six is removed from sys.modules and then reloaded. (Setuptools does # this for some reason.) if sys.meta_path: for i, importer in enumerate(sys.meta_path): # Here's some real nastiness: Another "instance" of the six module might # be floating around. Therefore, we can't use isinstance() to check for # the six meta path importer, since the other six instance will have # inserted an importer with different class. if (type(importer).__name__ == "_SixMetaPathImporter" and importer.name == __name__): del sys.meta_path[i] break del i, importer # Finally, add the importer to the meta path import hook. sys.meta_path.append(_importer) d2to1-0.2.12/d2to1/extern/__init__.py0000644001134200020070000000204412551552546020012 0ustar embrayscience00000000000000import sys if sys.version_info[:2] < (2, 6): # Python 2.5 doesn't have operator.methodcaller, which six # relies on in a few places (six doesn't technically support # Python 2.5 anymore either but this is one of the only major # stumbling blocks) # As a special case, also creates emulators for dict.viewkeys # dict.viewvalues and dict.viewitems, for which six uses methodcaller, # though these are not supported on Python 2.5; this isn't really # quite correct, but is sufficient for any cases that are likely to # arise def methodcaller(name, *args, **kwargs): if name in ('viewkeys', 'viewvalues', 'viewitems'): name = name[4:] def methodcaller(obj): return getattr(obj, name)(*args, **kwargs) return methodcaller import operator operator.methodcaller = methodcaller from . import six # Now that six has been loaded we can get rid of the sneaky monkeypatched # operator.methodcaller del operator.methodcaller else: from . import six d2to1-0.2.12/d2to1/__init__.py0000644001134200020070000000016212115406274016474 0ustar embrayscience00000000000000try: __version__ = __import__('pkg_resources').get_distribution('d2to1').version except: __version__ = '' d2to1-0.2.12/PKG-INFO0000644001134200020070000004320612551770444014544 0ustar embrayscience00000000000000Metadata-Version: 1.1 Name: d2to1 Version: 0.2.12 Summary: Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py Home-page: http://pypi.python.org/pypi/d2to1 Author: Erik M. Bray Author-email: embray@stsci.edu License: UNKNOWN Description: Introduction ============== .. image:: https://travis-ci.org/embray/d2to1.png?branch=master :alt: travis build status :target: https://travis-ci.org/embray/d2to1 d2to1 (the 'd' is for 'distutils') allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py script. It works by providing a distutils2-formatted setup.cfg file containing all of a package's metadata, and a very minimal setup.py which will slurp its arguments from the setup.cfg. Note: distutils2 has been merged into the CPython standard library, where it is now known as 'packaging'. This project was started before that change was finalized. So all references to distutils2 should also be assumed to refer to packaging. Rationale =========== I'm currently in the progress of redoing the packaging of a sizeable number of projects. I wanted to use distutils2-like setup.cfg files for all these projects, as they will hopefully be the future, and I much prefer them overall to using an executable setup.py. So forward-support for distutils2 is appealing both as future-proofing, and simply the aesthetics of using a flat text file to describe a project's metadata. However, I did not want any of these projects to require distutils2 for installation yet--it is too unstable, and not widely installed. So projects should still be installable using the familiar `./setup.py install`, for example. Furthermore, not all use cases required by some of the packages I support are fully supported by distutils2 yet. Hopefully they will be eventually, either through the distutils2 core or through extensions. But in the meantime d2to1 will try to keep up with the state of the art and "best practices" for distutils2 distributions, while adding support in areas that it's lacking. Usage ======= d2to1 requires a distribution to use distribute or setuptools. Your distribution must include a distutils2-like setup.cfg file, and a minimal setup.py script. For details on writing the setup.cfg, see the `distutils2 documentation`_. A simple sample can be found in d2to1's own setup.cfg (it uses its own machinery to install itself):: [metadata] name = d2to1 version = 0.2.12 author = Erik M. Bray author-email = embray@stsci.edu summary = Allows using distutils2-like setup.cfg files for a package's metadata with a distribute/setuptools setup.py description-file = README.rst CHANGES.rst home-page = http://pypi.python.org/pypi/d2to1 requires-dist = setuptools classifier = Development Status :: 5 - Production/Stable Environment :: Plugins Framework :: Setuptools Plugin Intended Audience :: Developers License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python Programming Language :: Python :: 3 Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = d2to1 d2to1.extern extra_files = CHANGES.rst LICENSE ez_setup.py [backwards_compat] zip-safe = False tests-require = nose [entry_points] distutils.setup_keywords = d2to1 = d2to1.core:d2to1 zest.releaser.prereleaser.middle = d2_version = d2to1.zestreleaser:prereleaser_middle zest.releaser.postreleaser.middle = d2_version = d2to1.zestreleaser:postreleaser_middle The minimal setup.py should look something like this:: #!/usr/bin/env python try: from setuptools import setup except ImportError: from distribute_setup import use_setuptools use_setuptools() from setuptools import setup setup( setup_requires=['d2to1'], d2to1=True ) Note that it's important to specify d2to1=True or else the d2to1 functionality will not be enabled. It is also possible to set d2to1='some_file.cfg' to specify the (relative) path of the setup.cfg file to use. But in general this functionality should not be necessary. It should also work fine if additional arguments are passed to `setup()`, but it should be noted that they will be clobbered by any options in the setup.cfg file. Caveats ======= - The requires-dist option in setup.cfg is implemented through the distribute/setuptools install_requires option, rather than the broken "requires" keyword in normal distutils. - Not all features of distutils2 are supported yet. If something doesn't seem to be working, it's probably not implemented yet. - Does not support distutils2 resources, and probably won't since it relies heavily on the sysconfig module only available in Python 3.2 and up. This is one area in which d2to1 should really be seen as a transitional tool. I don't really want to include a backport like distutils2 does. In the meantime, package_data and data_files may still be used under the [files] section of setup.cfg. .. _distutils2 documentation: http://alexis.notmyidea.org/distutils2/setupcfg.html Changes ========= 0.2.12 (2015-07-16) ------------------- - Fixed a corner case where depending on the order of events when installing multiple packages (i.e. when installing packages with dependencies, some of which might also use d2to1) we would end up calling the incorrect Distribution class (the patched version from setuptools, where d2to1 needs to get to the unpatched version from distutils for some cases). - Upgraded bundled copy of the ``six`` module to the current version (1.9.0). This fixes incompatibility between d2to1 and other packages that import different versions of ``six`` during their setup (the older version of ``six`` had a habit of fighting with other ``six`` instances over ``sys.modules``, which is fixed in newer versions). - Upgraded to latest ``ez_setup.py`` so that the most up to date version of setuptools will be correctly bootstrapped in the rare cases that it is needed. - Included some miscellaneous hacks to keep d2to1 working, nominally, with Python 2.5 despite the broad move away from Python 2.5 support in the Python community. The d2to1 v0.2.x releases will be the last to continue Python 2.5 support, given that testing it has become more difficult (and the overhead is probably no longer worth it). 0.2.11 (2013-08-29) ------------------- - Replaced ``distribute_setup.py`` with ``ez_setup.py`` in order to bootstrap with modern setuptools when necessary. - Fixed a couple minor Python 3-specific issues. In particular the ``data_files`` option could be passed to ``setup()`` as a ``dict_items`` object instead of a ``list`` which is what would normally be expected. - Added a tox.ini (frankly I thought there already was one). 0.2.10 (2013-04-10) ------------------- - Added support for the ``setup-requires-dist`` option in the ``[metadata]`` section of setup.cfg. This is analogous to the Setup-Requires-Dist metadata field supported by PEP-426 and uses the ``setup_requires`` argument to setuptools' ``setup()`` to implement it. - Added support for the ``dependency_links`` and ``include_package_data`` arguments to setuptools' ``setup()`` in the ``[backwards_compat]`` section of setup.cfg. - When a setup_hook calls sys.exit() don't show a traceback for the SystemExit exception. - Fixed a bug in the exception formatting when exceptions occur in setup.cfg handling. 0.2.9 (2013-03-05) ------------------ - Fixed a bug in the extra-files supported added in 0.2.8. Makes sure that monkey-patches can't be installed more than once and that the log reference is properly encapsulated. 0.2.8 (2013-03-05) ------------------ - Improved handling of packages where the packages_root option is set. That is, the Python package is not directly in the root of the source tree, but is in some sub-directory. Now the packages_root directory is prepended to sys.path while processing the setup.cfg and running setup hooks. - Added support for the Keywords metadata field via the keywords option in the ``[metadata]`` section of setup.cfg. - Fixed a missing import that caused a misleading exception when setup.cfg is missing. - Upgraded the shipped distribute_setup.py to the latest for distribute 0.6.28 - Added a few basic functional tests, along with an infrastructure to add more as needed. They can be run with nose and possibly with py.test though the latter hasn't been tested. - Improved hook imports to work better with namespace packages. - Added support for the extra_files option of the ``[files]`` section in setup.cfg. This was a feature from distutils2 that provided an alternative to MANIFEST.in for including additional files in source distributions (it does not yet support wildcard patterns but maybe it should?) - Added support for the tests_require setup argument from setuptools via the [backwards_compat] section in setup.cfg. - Supports Python 3 natively without 2to3. This makes Python 3 testing of d2to1 easier to support. 0.2.7 (2012-02-20) ------------------ - If no extension modules or entry points are defined in the setup.cfg, don't clobber any extension modules/entry points that may be defined in setup.py. 0.2.6 (2012-02-17) ------------------ - Added support for setuptools entry points in an ``[entry_points]`` section of setup.cfg--this is just for backwards-compatibility purposes, as packaging/distutils2 does not yet have a standard replacement for the entry points system. - Added a [backwards_compat] section for setup.cfg for other options that are supported by setuptools/distribute, but that aren't part of the distutils2 standard. So far the only options supported here are zip_safe and use_2to3. (Note: packaging does support a use-2to3 option to the build command, but if we tried to use that, distutils would not recognize it as a valid build option.) - Added support for the new (and presumably final) extension section format used by packaging. In this format, extensions should be specified in config sections of the format ``[extension: ext_mod_name]``, where any whitespace is optional. The old format used an ``=`` instead of ``:`` and is still supported, but should be considered deprecated. - Added support for the new syntax used by packaging for the package_data option (which is deprecated in packaging in favor of the resources system, but still supported). The new syntax is like:: package_data = packagename = pattern1 pattern2 pattern3 packagename.subpack = pattern1 pattern2 pattern3 That is, after ``package_data =``, give the name of a package, followed by an ``=``, followed by any number of whitespace separated wildcard patterns (or actual filenames relative to the package). Under this scheme, whitespace is not allowed in the patterns themselves. 0.2.5 (2011-07-21) ------------------ - Made the call to pkg_resources.get_distribution() to set __version__ more robust, so that it doesn't fail on, for example, VersionConflict errors 0.2.4 (2011-07-05) ------------------ - Fixed some bugs with installation on Python 3 0.2.3 (2011-06-23) ------------------ - Renamed 'setup_hook' to 'setup_hooks' as is now the case in the packaging module. Added support for multiple setup_hooks 0.2.2 (2011-06-15) ------------------ - Fixed a bug in DefaultGetDict where it didn't actually save the returned default in the dictionary--so any command options would get lost - Fixed a KeyError when the distribution does not have any custom commands specified 0.2.1 (2011-06-15) ------------------ - Reimplemented command hooks without monkey-patching and more reliably in general (though it's still a flaming hack). The previous monkey patch-based solution would break if d2to1 were entered multiple times, which could happen in some scenarios 0.2.0 (2011-06-14) ------------------ - Version bump to start using micro-version numbers for bug fixes only, now that the my primary feature goals are complete 0.1.5 (2011-06-02) ------------------ - Adds support for the data_files option under [files]. Though this is considered deprecated and may go away at some point, it can be useful in the absence of resources support - Adds support for command pre/post-hooks. Warning: this monkey-patches distutils.dist.Distribution a little bit... :( - Adds (slightly naive) support for PEP 345-style version specifiers in requires-dist (environment markers not supported yet) - Fixed a bug where not enough newlines were inserted between description files 0.1.4 (2011-05-24) ------------------ - Adds support for custom command classes specified in the 'commands' option under the [global] section in setup.cfg - Adds preliminary support for custom compilers specified in the 'compilers' option under the [global] section in setup.cfg. This functionality doesn't exist in distutils/setuptools/distribute, so adding support for it is a flaming hack. It hasn't really been tested beyond seeing that the custom compilers come up in `setup.py build_ext --help-compiler`, so any real-world testing of this feature would be appreciated 0.1.3 (2011-04-20) ------------------ - Adds zest.releaser entry points for updating the version number in a setup.cfg file; only useful if you use zest.releaser--otherwise harmless (might eventually move this functionality out into a separate product) - Though version 0.1.2 worked in Python3, use_2to3 wasn't added to the setup.py so 2to3 had to be run manually - Fixed a crash on projects that don't have a description-file option 0.1.2 (2011-04-13) ------------------ - Fixed the self-installation--it did not work if a d2to1 version was not already installed, due to the use of `pkg_resources.require()` - Adds nominal Python3 support - Fixes the 'classifier' option in setup.cfg 0.1.1 (2011-04-12) ------------------ - Fixed an unhelpful error message when a setup_hook fails to import - Made d2to1 able to use its own machinery to install itself Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Plugins Classifier: Framework :: Setuptools Plugin Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging d2to1-0.2.12/CHANGES.rst0000644001134200020070000002160212551770421015240 0ustar embrayscience00000000000000Changes ========= 0.2.12 (2015-07-16) ------------------- - Fixed a corner case where depending on the order of events when installing multiple packages (i.e. when installing packages with dependencies, some of which might also use d2to1) we would end up calling the incorrect Distribution class (the patched version from setuptools, where d2to1 needs to get to the unpatched version from distutils for some cases). - Upgraded bundled copy of the ``six`` module to the current version (1.9.0). This fixes incompatibility between d2to1 and other packages that import different versions of ``six`` during their setup (the older version of ``six`` had a habit of fighting with other ``six`` instances over ``sys.modules``, which is fixed in newer versions). - Upgraded to latest ``ez_setup.py`` so that the most up to date version of setuptools will be correctly bootstrapped in the rare cases that it is needed. - Included some miscellaneous hacks to keep d2to1 working, nominally, with Python 2.5 despite the broad move away from Python 2.5 support in the Python community. The d2to1 v0.2.x releases will be the last to continue Python 2.5 support, given that testing it has become more difficult (and the overhead is probably no longer worth it). 0.2.11 (2013-08-29) ------------------- - Replaced ``distribute_setup.py`` with ``ez_setup.py`` in order to bootstrap with modern setuptools when necessary. - Fixed a couple minor Python 3-specific issues. In particular the ``data_files`` option could be passed to ``setup()`` as a ``dict_items`` object instead of a ``list`` which is what would normally be expected. - Added a tox.ini (frankly I thought there already was one). 0.2.10 (2013-04-10) ------------------- - Added support for the ``setup-requires-dist`` option in the ``[metadata]`` section of setup.cfg. This is analogous to the Setup-Requires-Dist metadata field supported by PEP-426 and uses the ``setup_requires`` argument to setuptools' ``setup()`` to implement it. - Added support for the ``dependency_links`` and ``include_package_data`` arguments to setuptools' ``setup()`` in the ``[backwards_compat]`` section of setup.cfg. - When a setup_hook calls sys.exit() don't show a traceback for the SystemExit exception. - Fixed a bug in the exception formatting when exceptions occur in setup.cfg handling. 0.2.9 (2013-03-05) ------------------ - Fixed a bug in the extra-files supported added in 0.2.8. Makes sure that monkey-patches can't be installed more than once and that the log reference is properly encapsulated. 0.2.8 (2013-03-05) ------------------ - Improved handling of packages where the packages_root option is set. That is, the Python package is not directly in the root of the source tree, but is in some sub-directory. Now the packages_root directory is prepended to sys.path while processing the setup.cfg and running setup hooks. - Added support for the Keywords metadata field via the keywords option in the ``[metadata]`` section of setup.cfg. - Fixed a missing import that caused a misleading exception when setup.cfg is missing. - Upgraded the shipped distribute_setup.py to the latest for distribute 0.6.28 - Added a few basic functional tests, along with an infrastructure to add more as needed. They can be run with nose and possibly with py.test though the latter hasn't been tested. - Improved hook imports to work better with namespace packages. - Added support for the extra_files option of the ``[files]`` section in setup.cfg. This was a feature from distutils2 that provided an alternative to MANIFEST.in for including additional files in source distributions (it does not yet support wildcard patterns but maybe it should?) - Added support for the tests_require setup argument from setuptools via the [backwards_compat] section in setup.cfg. - Supports Python 3 natively without 2to3. This makes Python 3 testing of d2to1 easier to support. 0.2.7 (2012-02-20) ------------------ - If no extension modules or entry points are defined in the setup.cfg, don't clobber any extension modules/entry points that may be defined in setup.py. 0.2.6 (2012-02-17) ------------------ - Added support for setuptools entry points in an ``[entry_points]`` section of setup.cfg--this is just for backwards-compatibility purposes, as packaging/distutils2 does not yet have a standard replacement for the entry points system. - Added a [backwards_compat] section for setup.cfg for other options that are supported by setuptools/distribute, but that aren't part of the distutils2 standard. So far the only options supported here are zip_safe and use_2to3. (Note: packaging does support a use-2to3 option to the build command, but if we tried to use that, distutils would not recognize it as a valid build option.) - Added support for the new (and presumably final) extension section format used by packaging. In this format, extensions should be specified in config sections of the format ``[extension: ext_mod_name]``, where any whitespace is optional. The old format used an ``=`` instead of ``:`` and is still supported, but should be considered deprecated. - Added support for the new syntax used by packaging for the package_data option (which is deprecated in packaging in favor of the resources system, but still supported). The new syntax is like:: package_data = packagename = pattern1 pattern2 pattern3 packagename.subpack = pattern1 pattern2 pattern3 That is, after ``package_data =``, give the name of a package, followed by an ``=``, followed by any number of whitespace separated wildcard patterns (or actual filenames relative to the package). Under this scheme, whitespace is not allowed in the patterns themselves. 0.2.5 (2011-07-21) ------------------ - Made the call to pkg_resources.get_distribution() to set __version__ more robust, so that it doesn't fail on, for example, VersionConflict errors 0.2.4 (2011-07-05) ------------------ - Fixed some bugs with installation on Python 3 0.2.3 (2011-06-23) ------------------ - Renamed 'setup_hook' to 'setup_hooks' as is now the case in the packaging module. Added support for multiple setup_hooks 0.2.2 (2011-06-15) ------------------ - Fixed a bug in DefaultGetDict where it didn't actually save the returned default in the dictionary--so any command options would get lost - Fixed a KeyError when the distribution does not have any custom commands specified 0.2.1 (2011-06-15) ------------------ - Reimplemented command hooks without monkey-patching and more reliably in general (though it's still a flaming hack). The previous monkey patch-based solution would break if d2to1 were entered multiple times, which could happen in some scenarios 0.2.0 (2011-06-14) ------------------ - Version bump to start using micro-version numbers for bug fixes only, now that the my primary feature goals are complete 0.1.5 (2011-06-02) ------------------ - Adds support for the data_files option under [files]. Though this is considered deprecated and may go away at some point, it can be useful in the absence of resources support - Adds support for command pre/post-hooks. Warning: this monkey-patches distutils.dist.Distribution a little bit... :( - Adds (slightly naive) support for PEP 345-style version specifiers in requires-dist (environment markers not supported yet) - Fixed a bug where not enough newlines were inserted between description files 0.1.4 (2011-05-24) ------------------ - Adds support for custom command classes specified in the 'commands' option under the [global] section in setup.cfg - Adds preliminary support for custom compilers specified in the 'compilers' option under the [global] section in setup.cfg. This functionality doesn't exist in distutils/setuptools/distribute, so adding support for it is a flaming hack. It hasn't really been tested beyond seeing that the custom compilers come up in `setup.py build_ext --help-compiler`, so any real-world testing of this feature would be appreciated 0.1.3 (2011-04-20) ------------------ - Adds zest.releaser entry points for updating the version number in a setup.cfg file; only useful if you use zest.releaser--otherwise harmless (might eventually move this functionality out into a separate product) - Though version 0.1.2 worked in Python3, use_2to3 wasn't added to the setup.py so 2to3 had to be run manually - Fixed a crash on projects that don't have a description-file option 0.1.2 (2011-04-13) ------------------ - Fixed the self-installation--it did not work if a d2to1 version was not already installed, due to the use of `pkg_resources.require()` - Adds nominal Python3 support - Fixes the 'classifier' option in setup.cfg 0.1.1 (2011-04-12) ------------------ - Fixed an unhelpful error message when a setup_hook fails to import - Made d2to1 able to use its own machinery to install itself