stsci.distutils-0.3.7/0000755001134200020070000000000012256142707015603 5ustar embrayscience00000000000000stsci.distutils-0.3.7/setup.py0000755001134200020070000000673112256142676017334 0ustar embrayscience00000000000000#!/usr/bin/env python try: from setuptools import setup except ImportError: from distribute_setup import use_setuptools use_setuptools() from setuptools import setup import sys from pkg_resources import get_distribution, Requirement # If stsci.distutils is being used to install another package in the stsci # namespace package, we may need to first re-import the stsci package so that # all the entries (including the current path) are added to stsci.__path__ # Deleting 'stsci' from sys.modules will force such a re-import. if 'stsci' in sys.modules: del sys.modules['stsci'] # This is a workaround for http://bugs.python.org/setuptools/issue20; most # packages that have this package as a setup-requirement also have d2to1 as # a setup-requirement, which can lead to bugginess. # See also http://mail.python.org/pipermail/distutils-sig/2011-May/017812.html # for a description of the problem (in my example, package_A is d2to1 and # package_B is stsci.distutils). # This issue was fixed in distribute 0.6.17 and in setuptools 0.6c10, but # leaving in support for older versions for now. requirements = [Requirement.parse('setuptools<0.6c10'), Requirement.parse('distribute<0.6.19')] # Distribution will actually convert a requirement for any setuptools version # to a requirement for distribute, so if distribute is in use the first # requirement is useless. setuptools does something similar: yes, setuptools # and distribute are actually antagonistic toward each other--ridiculous. if requirements[0].key == requirements[1].key: del requirements[0] try: # Note: If distribute is installed get_distribution('setuptools') returns # the installed distribute distribution has_issue205 = any([get_distribution('setuptools') in req for req in requirements]) except: has_issue205 = False if has_issue205: import sys from pkg_resources import working_set from setuptools import sandbox from setuptools.command import easy_install # Monkey patch setuptools so that subsequent calls to run_setup also # have this patch: _old_run_setup = sandbox.run_setup def run_setup(setup_script, args): save_entries = working_set.entries[:] save_entry_keys = working_set.entry_keys.copy() save_by_key = working_set.by_key.copy() save_modules = sys.modules.copy() try: _old_run_setup(setup_script, args) finally: working_set.entries = save_entries working_set.entry_keys = save_entry_keys working_set.by_key = save_by_key sys.modules.update(save_modules) for key in list(sys.modules): if key not in save_modules: del sys.modules[key] sandbox.run_setup = run_setup easy_install.run_setup = run_setup # Patch the current call to run_setup save_entries = working_set.entries[:] save_entry_keys = working_set.entry_keys.copy() save_by_key = working_set.by_key.copy() save_modules = sys.modules.copy() try: setup( setup_requires=['d2to1>=0.2.9'], namespace_packages=['stsci'], packages=['stsci'], d2to1=True, ) finally: if has_issue205: working_set.entries = save_entries working_set.entry_keys = save_entry_keys working_set.by_key = save_by_key sys.modules.update(save_modules) for key in list(sys.modules): if key not in save_modules: del sys.modules[key] stsci.distutils-0.3.7/PKG-INFO0000644001134200020070000004011012256142707016674 0ustar embrayscience00000000000000Metadata-Version: 1.1 Name: stsci.distutils Version: 0.3.7 Summary: distutils/packaging-related utilities used by some of STScI's packages Home-page: http://www.stsci.edu/resources/software_hardware/stsci_python Author: Erik M. Bray Author-email: embray@stsci.edu License: UNKNOWN Description: Introduction ============ This package contains utilities used to package some of STScI's Python projects; specifically those projects that comprise stsci_python_ and Astrolib_. It currently consists mostly of some setup_hook scripts meant for use with `distutils2/packaging`_ and/or d2to1_, and a customized easy_install command meant for use with distribute_. This package is not meant for general consumption, though it might be worth looking at for examples of how to do certain things with your own packages, but YMMV. Features ======== Hook Scripts ------------ Currently the main features of this package are a couple of setup_hook scripts. In distutils2, a setup_hook is a script that runs at the beginning of any pysetup command, and can modify the package configuration read from setup.cfg. There are also pre- and post-command hooks that only run before/after a specific setup command (eg. build_ext, install) is run. stsci.distutils.hooks.use_packages_root ''''''''''''''''''''''''''''''''''''''' If using the ``packages_root`` option under the ``[files]`` section of setup.cfg, this hook will add that path to ``sys.path`` so that modules in your package can be imported and used in setup. This can be used even if ``packages_root`` is not specified--in this case it adds ``''`` to ``sys.path``. stsci.distutils.hooks.version_setup_hook '''''''''''''''''''''''''''''''''''''''' Creates a Python module called version.py which currently contains four variables: * ``__version__`` (the release version) * ``__svn_revision__`` (the SVN revision info as returned by the ``svnversion`` command) * ``__svn_full_info__`` (as returned by the ``svn info`` command) * ``__setup_datetime__`` (the date and time that setup.py was last run). These variables can be imported in the package's ``__init__.py`` for degugging purposes. The version.py module will *only* be created in a package that imports from the version module in its ``__init__.py``. It should be noted that this is generally preferable to writing these variables directly into ``__init__.py``, since this provides more control and is less likely to unexpectedly break things in ``__init__.py``. stsci.distutils.hooks.version_pre_command_hook '''''''''''''''''''''''''''''''''''''''''''''' Identical to version_setup_hook, but designed to be used as a pre-command hook. stsci.distutils.hooks.version_post_command_hook ''''''''''''''''''''''''''''''''''''''''''''''' The complement to version_pre_command_hook. This will delete any version.py files created during a build in order to prevent them from cluttering an SVN working copy (note, however, that version.py is *not* deleted from the build/ directory, so a copy of it is still preserved). It will also not be deleted if the current directory is not an SVN working copy. For example, if source code extracted from a source tarball it will be preserved. stsci.distutils.hooks.tag_svn_revision '''''''''''''''''''''''''''''''''''''' A setup_hook to add the SVN revision of the current working copy path to the package version string, but only if the version ends in .dev. For example, ``mypackage-1.0.dev`` becomes ``mypackage-1.0.dev1234``. This is in accordance with the version string format standardized by PEP 386. This should be used as a replacement for the ``tag_svn_revision`` option to the egg_info command. This hook is more compatible with packaging/distutils2, which does not include any VCS support. This hook is also more flexible in that it turns the revision number on/off depending on the presence of ``.dev`` in the version string, so that it's not automatically added to the version in final releases. This hook does require the ``svnversion`` command to be available in order to work. It does not examine the working copy metadata directly. stsci.distutils.hooks.numpy_extension_hook '''''''''''''''''''''''''''''''''''''''''' This is a pre-command hook for the build_ext command. To use it, add a ``[build_ext]`` section to your setup.cfg, and add to it:: pre-hook.numpy-extension-hook = stsci.distutils.hooks.numpy_extension_hook This hook must be used to build extension modules that use Numpy. The primary side-effect of this hook is to add the correct numpy include directories to `include_dirs`. To use it, add 'numpy' to the 'include-dirs' option of each extension module that requires numpy to build. The value 'numpy' will be replaced with the actual path to the numpy includes. stsci.distutils.hooks.is_display_option ''''''''''''''''''''''''''''''''''''''' This is not actually a hook, but is a useful utility function that can be used in writing other hooks. Basically, it returns ``True`` if setup.py was run with a "display option" such as --version or --help. This can be used to prevent your hook from running in such cases. stsci.distutils.hooks.glob_data_files ''''''''''''''''''''''''''''''''''''' A pre-command hook for the install_data command. Allows filename wildcards as understood by ``glob.glob()`` to be used in the data_files option. This hook must be used in order to have this functionality since it does not normally exist in distutils. This hook also ensures that data files are installed relative to the package path. data_files shouldn't normally be installed this way, but the functionality is required for a few special cases. Commands -------- build_optional_ext '''''''''''''''''' This serves as an optional replacement for the default built_ext command, which compiles C extension modules. Its purpose is to allow extension modules to be *optional*, so that if their build fails the rest of the package is still allowed to be built and installed. This can be used when an extension module is not definitely required to use the package. To use this custom command, add:: commands = stsci.distutils.command.build_optional_ext.build_optional_ext under the ``[global]`` section of your package's setup.cfg. Then, to mark an individual extension module as optional, under the setup.cfg section for that extension add:: optional = True Optionally, you may also add a custom failure message by adding:: fail_message = The foobar extension module failed to compile. This could be because you lack such and such headers. This package will still work, but such and such features will be disabled. .. _stsci_python: http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python .. _Astrolib: http://www.scipy.org/AstroLib/ .. _distutils2/packaging: http://distutils2.notmyidea.org/ .. _d2to1: http://pypi.python.org/pypi/d2to1 .. _distribute: http://pypi.python.org/pypi/distribute Changelog =========== 0.3.7 (2013-12-23) ------------------ - Avoid using ``Popen.stdout`` directly in the version.py SVN revision auto-update script to avoid possible ResourceWarnings on Python >= 3.2. See https://github.com/spacetelescope/PyFITS/issues/45 0.3.6 (2013-11-21) ------------------ - Fixed a syntax error in Python 3 that was introduced in 0.3.5. This could occur very early in the setup such that it bailed before even 2to3 could run on the rest of the package. 0.3.5 (2013-11-18) ------------------ - Fixed an obscure issue that could occur when trying to install with easy_install on Python 2 systems that have lib2to3 installed but have never used it. 0.3.4 (2013-07-31) ------------------ - Updated the check for ``__loader__`` added in v0.3.3 to only perform that check on Python >= 3.3, since the issue doesn't apply to older Python versions. 0.3.3 (2013-07-25) ------------------ - Updated the import-time SVN revision update mechanism in the ``version.py`` module generated by the ``version_setup_hook`` to avoid running when not in a dev version of the package. This saves time on importing released packages when installed on users' systems. - Added a workaround to a bug on Python 3.3 that could cause stsci.distutils to crash during installation. 0.3.2 (2013-03-27) ------------------ - Fixed a bug in the version hook that could occur if the svnversion command fails. - Updated the template for the version.py module generated by the version hook so that ``from .version import *`` will work for applications. - Added a ``__vdate__`` variable in version.py which may contain a release date string by specifying a ``vdate`` option in the ``[metadata]`` section of setup.cfg. - Added a ``stsci_distutils_version`` variable in version.py containing the version of stsci.distutils used to generate the file--useful primarily for debugging purposes. - Version 0.3.1 added a new zest.releaser hooks to ensure that source distributes are created as tar.gz files instead of zip files--this was left out of the changelog for 0.3.1. - The tar.gz zest.releaser hook is updated in 0.3.2 to only run on stsci packages. 0.3.1 (2012-06-28) ------------------ - Fixed a bug where console output from svn-related programs was assumed to be ascii, leading to possible crashes on non-English systems. 0.3 (2012-02-20) ---------------- - The ``glob_data_files`` hook became a pre-command hook for the install_data command instead of being a setup-hook. This is to support the additional functionality of requiring data_files with relative destination paths to be install relative to the package's install path (i.e. site-packages). - Dropped support for and deprecated the easier_install custom command. Although it should still work, it probably won't be used anymore for stsci_python packages. - Added support for the ``build_optional_ext`` command, which replaces/extends the default ``build_ext`` command. See the README for more details. - Added the ``tag_svn_revision`` setup_hook as a replacement for the setuptools-specific tag_svn_revision option to the egg_info command. This new hook is easier to use than the old tag_svn_revision option: It's automatically enabled by the presence of ``.dev`` in the version string, and disabled otherwise. - The ``svn_info_pre_hook`` and ``svn_info_post_hook`` have been replaced with ``version_pre_command_hook`` and ``version_post_command_hook`` respectively. However, a new ``version_setup_hook``, which has the same purpose, has been added. It is generally easier to use and will give more consistent results in that it will run every time setup.py is run, regardless of which command is used. ``stsci.distutils`` itself uses this hook--see the `setup.cfg` file and `stsci/distutils/__init__.py` for example usage. - Instead of creating an `svninfo.py` module, the new ``version_`` hooks create a file called `version.py`. In addition to the SVN info that was included in `svninfo.py`, it includes a ``__version__`` variable to be used by the package's `__init__.py`. This allows there to be a hard-coded ``__version__`` variable included in the source code, rather than using pkg_resources to get the version. - In `version.py`, the variables previously named ``__svn_version__`` and ``__full_svn_info__`` are now named ``__svn_revision__`` and ``__svn_full_info__``. - Fixed a bug when using stsci.distutils in the installation of other packages in the ``stsci.*`` namespace package. If stsci.distutils was not already installed, and was downloaded automatically by distribute through the setup_requires option, then ``stsci.distutils`` would fail to import. This is because the way the namespace package (nspkg) mechanism currently works, all packages belonging to the nspkg *must* be on the import path at initial import time. So when installing stsci.tools, for example, if ``stsci.tools`` is imported from within the source code at install time, but before ``stsci.distutils`` is downloaded and added to the path, the ``stsci`` package is already imported and can't be extended to include the path of ``stsci.distutils`` after the fact. The easiest way of dealing with this, it seems, is to delete ``stsci`` from ``sys.modules``, which forces it to be reimported, now the its ``__path__`` extended to include ``stsci.distutil``'s path. - Added zest.releaser hooks for tweaking the development version string template, and for uploading new releases to STScI's local package index. 0.2.2 (2011-11-09) ------------------ - Fixed check for the issue205 bug on actual setuptools installs; before it only worked on distribute. setuptools has the issue205 bug prior to version 0.6c10. - Improved the fix for the issue205 bug, especially on setuptools. setuptools, prior to 0.6c10, did not back of sys.modules either before sandboxing, which causes serious problems. In fact, it's so bad that it's not enough to add a sys.modules backup to the current sandbox: It's in fact necessary to monkeypatch setuptools.sandbox.run_setup so that any subsequent calls to it also back up sys.modules. 0.2.1 (2011-09-02) ------------------ - Fixed the dependencies so that setuptools is requirement but 'distribute' specifically. Previously installation could fail if users had plain setuptools installed and not distribute 0.2 (2011-08-23) ------------------ - Initial public release Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging stsci.distutils-0.3.7/distribute_setup.py0000644001134200020070000003764712256142676021601 0ustar embrayscience00000000000000#!python """Bootstrap distribute 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 distribute_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 sys import time import fnmatch import tempfile import tarfile from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None try: import subprocess def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 except ImportError: # will be used for python 2.3 def _python_cmd(*args): args = (sys.executable,) + args # quoting arguments if windows if sys.platform == 'win32': def quote(arg): if ' ' in arg: return '"%s"' % arg return arg args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 DEFAULT_VERSION = "0.6.28" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" SETUPTOOLS_PKG_INFO = """\ Metadata-Version: 1.0 Name: setuptools Version: %s Summary: xxxx Home-page: xxx Author: xxx Author-email: xxx License: xxx Description: xxx """ % SETUPTOOLS_FAKED_VERSION 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 Distribute') if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') finally: os.chdir(old_wd) 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 Distribute egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) # 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, 'distribute-%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) import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15, no_fake=True): # 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: try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): if not no_fake: _fake_setuptools() raise ImportError except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("distribute>=" + version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of distribute (>=%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 distribute'." "\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) finally: if not no_fake: _create_fake_setuptools_pkg_info(to_dir) def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename `version` should be a valid distribute 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. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen tgz_name = "distribute-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: log.warn("Downloading %s", url) 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(saveto, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def _no_sandbox(function): def __no_sandbox(*args, **kw): try: from setuptools.sandbox import DirectorySandbox if not hasattr(DirectorySandbox, '_old'): def violation(*args): pass DirectorySandbox._old = DirectorySandbox._violation DirectorySandbox._violation = violation patched = True else: patched = False except ImportError: patched = False try: return function(*args, **kw) finally: if patched: DirectorySandbox._violation = DirectorySandbox._old del DirectorySandbox._old return __no_sandbox def _patch_file(path, content): """Will backup the file then patch it""" existing_content = open(path).read() if existing_content == content: # already patched log.warn('Already patched.') return False log.warn('Patching...') _rename_path(path) f = open(path, 'w') try: f.write(content) finally: f.close() return True _patch_file = _no_sandbox(_patch_file) def _same_content(path, content): return open(path).read() == content def _rename_path(path): new_name = path + '.OLD.%s' % time.time() log.warn('Renaming %s into %s', path, new_name) os.rename(path, new_name) return new_name def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) return False found = False for file in os.listdir(placeholder): if fnmatch.fnmatch(file, 'setuptools*.egg-info'): found = True break if not found: log.warn('Could not locate setuptools*.egg-info') return log.warn('Removing elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) else: patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) if not patched: log.warn('%s already patched.', pkg_info) return False # now let's move the files out of the way for element in ('setuptools', 'pkg_resources.py', 'site.py'): element = os.path.join(placeholder, element) if os.path.exists(element): _rename_path(element) else: log.warn('Could not find the %s element of the ' 'Setuptools distribution', element) return True _remove_flat_installation = _no_sandbox(_remove_flat_installation) def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') return pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) setuptools_file = 'setuptools-%s-py%s.egg-info' % \ (SETUPTOOLS_FAKED_VERSION, pyver) pkg_info = os.path.join(placeholder, setuptools_file) if os.path.exists(pkg_info): log.warn('%s already exists', pkg_info) return if not os.access(pkg_info, os.W_OK): log.warn("Don't have permissions to write %s, skipping", pkg_info) log.warn('Creating %s', pkg_info) f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() pth_file = os.path.join(placeholder, 'setuptools.pth') log.warn('Creating %s', pth_file) f = open(pth_file, 'w') try: f.write(os.path.join(os.curdir, setuptools_file)) finally: f.close() _create_fake_setuptools_pkg_info = _no_sandbox( _create_fake_setuptools_pkg_info ) def _patch_egg_dir(path): # let's check if it's already patched pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') if os.path.exists(pkg_info): if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): log.warn('%s already patched.', pkg_info) return False _rename_path(path) os.mkdir(path) os.mkdir(os.path.join(path, 'EGG-INFO')) pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() return True _patch_egg_dir = _no_sandbox(_patch_egg_dir) def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() def _under_prefix(location): if 'install' not in sys.argv: return True args = sys.argv[sys.argv.index('install') + 1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): top_dir = arg.split('root=')[-1] return location.startswith(top_dir) elif arg == option: if len(args) > index: top_dir = args[index + 1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) return True def _fake_setuptools(): log.warn('Scanning installed packages') try: import pkg_resources except ImportError: # we're cool log.warn('Setuptools or Distribute does not seem to be installed.') return ws = pkg_resources.working_set try: setuptools_dist = ws.find( pkg_resources.Requirement.parse('setuptools', replacement=False) ) except TypeError: # old distribute API setuptools_dist = ws.find( pkg_resources.Requirement.parse('setuptools') ) if setuptools_dist is None: log.warn('No setuptools distribution found') return # detecting if it was already faked setuptools_location = setuptools_dist.location log.warn('Setuptools installation detected at %s', setuptools_location) # if --root or --preix was provided, and if # setuptools is not located in them, we don't patch it if not _under_prefix(setuptools_location): log.warn('Not patching, --root or --prefix is installing Distribute' ' in another location') return # let's see if its an egg if not setuptools_location.endswith('.egg'): log.warn('Non-egg installation') res = _remove_flat_installation(setuptools_location) if not res: return else: log.warn('Egg installation') pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') if (os.path.exists(pkg_info) and _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): log.warn('Already patched.') return log.warn('Patching...') # let's create a fake egg replacing setuptools one res = _patch_egg_dir(setuptools_location) if not res: return log.warn('Patched done.') _relaunch() def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug _cmd = ['-c', 'install', '--single-version-externally-managed'] if sys.argv[:3] == _cmd: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) 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(argv): install_args = [] user_install = '--user' in argv if user_install and sys.version_info < (2, 6): log.warn("--user requires Python 2.6 or later") raise SystemExit(1) if user_install: install_args.append('--user') return install_args def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" tarball = download_setuptools() _install(tarball, _build_install_args(argv)) if __name__ == '__main__': main(sys.argv[1:]) stsci.distutils-0.3.7/stsci.distutils.egg-info/0000755001134200020070000000000012256142707022445 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci.distutils.egg-info/SOURCES.txt0000644001134200020070000000336012256142702024326 0ustar embrayscience00000000000000CHANGES.txt LICENSE.txt MANIFEST.in README.txt distribute_setup.py setup.cfg setup.py tox.ini docs/Makefile docs/source/api.rst docs/source/changelog.rst docs/source/conf.py docs/source/index.rst stsci/__init__.py stsci.distutils.egg-info/PKG-INFO stsci.distutils.egg-info/SOURCES.txt stsci.distutils.egg-info/dependency_links.txt stsci.distutils.egg-info/entry_points.txt stsci.distutils.egg-info/namespace_packages.txt stsci.distutils.egg-info/not-zip-safe stsci.distutils.egg-info/requires.txt stsci.distutils.egg-info/top_level.txt stsci/distutils/__init__.py stsci/distutils/astutils.py stsci/distutils/hooks.py stsci/distutils/release.py stsci/distutils/svnutils.py stsci/distutils/version.py stsci/distutils/versionutils.py stsci/distutils/command/__init__.py stsci/distutils/command/build_optional_ext.py stsci/distutils/command/easier_install.py stsci/distutils/tests/__init__.py stsci/distutils/tests/test_commands.py stsci/distutils/tests/test_hooks.py stsci/distutils/tests/util.py stsci/distutils/tests/testpackage/CHANGES.txt stsci/distutils/tests/testpackage/LICENSE.txt stsci/distutils/tests/testpackage/MANIFEST.in stsci/distutils/tests/testpackage/README.txt stsci/distutils/tests/testpackage/distribute_setup.py stsci/distutils/tests/testpackage/setup.cfg stsci/distutils/tests/testpackage/setup.py stsci/distutils/tests/testpackage/data_files/a.txt stsci/distutils/tests/testpackage/data_files/b.txt stsci/distutils/tests/testpackage/data_files/c.rst stsci/distutils/tests/testpackage/src/testext.c stsci/distutils/tests/testpackage/stsci/__init__.py stsci/distutils/tests/testpackage/stsci/testpackage/__init__.py stsci/distutils/tests/testpackage/stsci/testpackage/package_data/1.txt stsci/distutils/tests/testpackage/stsci/testpackage/package_data/2.txtstsci.distutils-0.3.7/stsci.distutils.egg-info/dependency_links.txt0000644001134200020070000000000112256142702026506 0ustar embrayscience00000000000000 stsci.distutils-0.3.7/stsci.distutils.egg-info/PKG-INFO0000644001134200020070000004011012256142702023531 0ustar embrayscience00000000000000Metadata-Version: 1.1 Name: stsci.distutils Version: 0.3.7 Summary: distutils/packaging-related utilities used by some of STScI's packages Home-page: http://www.stsci.edu/resources/software_hardware/stsci_python Author: Erik M. Bray Author-email: embray@stsci.edu License: UNKNOWN Description: Introduction ============ This package contains utilities used to package some of STScI's Python projects; specifically those projects that comprise stsci_python_ and Astrolib_. It currently consists mostly of some setup_hook scripts meant for use with `distutils2/packaging`_ and/or d2to1_, and a customized easy_install command meant for use with distribute_. This package is not meant for general consumption, though it might be worth looking at for examples of how to do certain things with your own packages, but YMMV. Features ======== Hook Scripts ------------ Currently the main features of this package are a couple of setup_hook scripts. In distutils2, a setup_hook is a script that runs at the beginning of any pysetup command, and can modify the package configuration read from setup.cfg. There are also pre- and post-command hooks that only run before/after a specific setup command (eg. build_ext, install) is run. stsci.distutils.hooks.use_packages_root ''''''''''''''''''''''''''''''''''''''' If using the ``packages_root`` option under the ``[files]`` section of setup.cfg, this hook will add that path to ``sys.path`` so that modules in your package can be imported and used in setup. This can be used even if ``packages_root`` is not specified--in this case it adds ``''`` to ``sys.path``. stsci.distutils.hooks.version_setup_hook '''''''''''''''''''''''''''''''''''''''' Creates a Python module called version.py which currently contains four variables: * ``__version__`` (the release version) * ``__svn_revision__`` (the SVN revision info as returned by the ``svnversion`` command) * ``__svn_full_info__`` (as returned by the ``svn info`` command) * ``__setup_datetime__`` (the date and time that setup.py was last run). These variables can be imported in the package's ``__init__.py`` for degugging purposes. The version.py module will *only* be created in a package that imports from the version module in its ``__init__.py``. It should be noted that this is generally preferable to writing these variables directly into ``__init__.py``, since this provides more control and is less likely to unexpectedly break things in ``__init__.py``. stsci.distutils.hooks.version_pre_command_hook '''''''''''''''''''''''''''''''''''''''''''''' Identical to version_setup_hook, but designed to be used as a pre-command hook. stsci.distutils.hooks.version_post_command_hook ''''''''''''''''''''''''''''''''''''''''''''''' The complement to version_pre_command_hook. This will delete any version.py files created during a build in order to prevent them from cluttering an SVN working copy (note, however, that version.py is *not* deleted from the build/ directory, so a copy of it is still preserved). It will also not be deleted if the current directory is not an SVN working copy. For example, if source code extracted from a source tarball it will be preserved. stsci.distutils.hooks.tag_svn_revision '''''''''''''''''''''''''''''''''''''' A setup_hook to add the SVN revision of the current working copy path to the package version string, but only if the version ends in .dev. For example, ``mypackage-1.0.dev`` becomes ``mypackage-1.0.dev1234``. This is in accordance with the version string format standardized by PEP 386. This should be used as a replacement for the ``tag_svn_revision`` option to the egg_info command. This hook is more compatible with packaging/distutils2, which does not include any VCS support. This hook is also more flexible in that it turns the revision number on/off depending on the presence of ``.dev`` in the version string, so that it's not automatically added to the version in final releases. This hook does require the ``svnversion`` command to be available in order to work. It does not examine the working copy metadata directly. stsci.distutils.hooks.numpy_extension_hook '''''''''''''''''''''''''''''''''''''''''' This is a pre-command hook for the build_ext command. To use it, add a ``[build_ext]`` section to your setup.cfg, and add to it:: pre-hook.numpy-extension-hook = stsci.distutils.hooks.numpy_extension_hook This hook must be used to build extension modules that use Numpy. The primary side-effect of this hook is to add the correct numpy include directories to `include_dirs`. To use it, add 'numpy' to the 'include-dirs' option of each extension module that requires numpy to build. The value 'numpy' will be replaced with the actual path to the numpy includes. stsci.distutils.hooks.is_display_option ''''''''''''''''''''''''''''''''''''''' This is not actually a hook, but is a useful utility function that can be used in writing other hooks. Basically, it returns ``True`` if setup.py was run with a "display option" such as --version or --help. This can be used to prevent your hook from running in such cases. stsci.distutils.hooks.glob_data_files ''''''''''''''''''''''''''''''''''''' A pre-command hook for the install_data command. Allows filename wildcards as understood by ``glob.glob()`` to be used in the data_files option. This hook must be used in order to have this functionality since it does not normally exist in distutils. This hook also ensures that data files are installed relative to the package path. data_files shouldn't normally be installed this way, but the functionality is required for a few special cases. Commands -------- build_optional_ext '''''''''''''''''' This serves as an optional replacement for the default built_ext command, which compiles C extension modules. Its purpose is to allow extension modules to be *optional*, so that if their build fails the rest of the package is still allowed to be built and installed. This can be used when an extension module is not definitely required to use the package. To use this custom command, add:: commands = stsci.distutils.command.build_optional_ext.build_optional_ext under the ``[global]`` section of your package's setup.cfg. Then, to mark an individual extension module as optional, under the setup.cfg section for that extension add:: optional = True Optionally, you may also add a custom failure message by adding:: fail_message = The foobar extension module failed to compile. This could be because you lack such and such headers. This package will still work, but such and such features will be disabled. .. _stsci_python: http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python .. _Astrolib: http://www.scipy.org/AstroLib/ .. _distutils2/packaging: http://distutils2.notmyidea.org/ .. _d2to1: http://pypi.python.org/pypi/d2to1 .. _distribute: http://pypi.python.org/pypi/distribute Changelog =========== 0.3.7 (2013-12-23) ------------------ - Avoid using ``Popen.stdout`` directly in the version.py SVN revision auto-update script to avoid possible ResourceWarnings on Python >= 3.2. See https://github.com/spacetelescope/PyFITS/issues/45 0.3.6 (2013-11-21) ------------------ - Fixed a syntax error in Python 3 that was introduced in 0.3.5. This could occur very early in the setup such that it bailed before even 2to3 could run on the rest of the package. 0.3.5 (2013-11-18) ------------------ - Fixed an obscure issue that could occur when trying to install with easy_install on Python 2 systems that have lib2to3 installed but have never used it. 0.3.4 (2013-07-31) ------------------ - Updated the check for ``__loader__`` added in v0.3.3 to only perform that check on Python >= 3.3, since the issue doesn't apply to older Python versions. 0.3.3 (2013-07-25) ------------------ - Updated the import-time SVN revision update mechanism in the ``version.py`` module generated by the ``version_setup_hook`` to avoid running when not in a dev version of the package. This saves time on importing released packages when installed on users' systems. - Added a workaround to a bug on Python 3.3 that could cause stsci.distutils to crash during installation. 0.3.2 (2013-03-27) ------------------ - Fixed a bug in the version hook that could occur if the svnversion command fails. - Updated the template for the version.py module generated by the version hook so that ``from .version import *`` will work for applications. - Added a ``__vdate__`` variable in version.py which may contain a release date string by specifying a ``vdate`` option in the ``[metadata]`` section of setup.cfg. - Added a ``stsci_distutils_version`` variable in version.py containing the version of stsci.distutils used to generate the file--useful primarily for debugging purposes. - Version 0.3.1 added a new zest.releaser hooks to ensure that source distributes are created as tar.gz files instead of zip files--this was left out of the changelog for 0.3.1. - The tar.gz zest.releaser hook is updated in 0.3.2 to only run on stsci packages. 0.3.1 (2012-06-28) ------------------ - Fixed a bug where console output from svn-related programs was assumed to be ascii, leading to possible crashes on non-English systems. 0.3 (2012-02-20) ---------------- - The ``glob_data_files`` hook became a pre-command hook for the install_data command instead of being a setup-hook. This is to support the additional functionality of requiring data_files with relative destination paths to be install relative to the package's install path (i.e. site-packages). - Dropped support for and deprecated the easier_install custom command. Although it should still work, it probably won't be used anymore for stsci_python packages. - Added support for the ``build_optional_ext`` command, which replaces/extends the default ``build_ext`` command. See the README for more details. - Added the ``tag_svn_revision`` setup_hook as a replacement for the setuptools-specific tag_svn_revision option to the egg_info command. This new hook is easier to use than the old tag_svn_revision option: It's automatically enabled by the presence of ``.dev`` in the version string, and disabled otherwise. - The ``svn_info_pre_hook`` and ``svn_info_post_hook`` have been replaced with ``version_pre_command_hook`` and ``version_post_command_hook`` respectively. However, a new ``version_setup_hook``, which has the same purpose, has been added. It is generally easier to use and will give more consistent results in that it will run every time setup.py is run, regardless of which command is used. ``stsci.distutils`` itself uses this hook--see the `setup.cfg` file and `stsci/distutils/__init__.py` for example usage. - Instead of creating an `svninfo.py` module, the new ``version_`` hooks create a file called `version.py`. In addition to the SVN info that was included in `svninfo.py`, it includes a ``__version__`` variable to be used by the package's `__init__.py`. This allows there to be a hard-coded ``__version__`` variable included in the source code, rather than using pkg_resources to get the version. - In `version.py`, the variables previously named ``__svn_version__`` and ``__full_svn_info__`` are now named ``__svn_revision__`` and ``__svn_full_info__``. - Fixed a bug when using stsci.distutils in the installation of other packages in the ``stsci.*`` namespace package. If stsci.distutils was not already installed, and was downloaded automatically by distribute through the setup_requires option, then ``stsci.distutils`` would fail to import. This is because the way the namespace package (nspkg) mechanism currently works, all packages belonging to the nspkg *must* be on the import path at initial import time. So when installing stsci.tools, for example, if ``stsci.tools`` is imported from within the source code at install time, but before ``stsci.distutils`` is downloaded and added to the path, the ``stsci`` package is already imported and can't be extended to include the path of ``stsci.distutils`` after the fact. The easiest way of dealing with this, it seems, is to delete ``stsci`` from ``sys.modules``, which forces it to be reimported, now the its ``__path__`` extended to include ``stsci.distutil``'s path. - Added zest.releaser hooks for tweaking the development version string template, and for uploading new releases to STScI's local package index. 0.2.2 (2011-11-09) ------------------ - Fixed check for the issue205 bug on actual setuptools installs; before it only worked on distribute. setuptools has the issue205 bug prior to version 0.6c10. - Improved the fix for the issue205 bug, especially on setuptools. setuptools, prior to 0.6c10, did not back of sys.modules either before sandboxing, which causes serious problems. In fact, it's so bad that it's not enough to add a sys.modules backup to the current sandbox: It's in fact necessary to monkeypatch setuptools.sandbox.run_setup so that any subsequent calls to it also back up sys.modules. 0.2.1 (2011-09-02) ------------------ - Fixed the dependencies so that setuptools is requirement but 'distribute' specifically. Previously installation could fail if users had plain setuptools installed and not distribute 0.2 (2011-08-23) ------------------ - Initial public release Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging stsci.distutils-0.3.7/stsci.distutils.egg-info/namespace_packages.txt0000644001134200020070000000000612256142702026767 0ustar embrayscience00000000000000stsci stsci.distutils-0.3.7/stsci.distutils.egg-info/requires.txt0000644001134200020070000000002712256142702025037 0ustar embrayscience00000000000000setuptools d2to1>=0.2.5stsci.distutils-0.3.7/stsci.distutils.egg-info/entry_points.txt0000644001134200020070000000047612256142702025745 0ustar embrayscience00000000000000[zest.releaser.postreleaser.before] fix_dev_version_template = stsci.distutils.release:fix_dev_version_template [zest.releaser.releaser.before] fix_sdist_format = stsci.distutils.release:fix_sdist_format [zest.releaser.releaser.after] add_to_stsci_package_index = stsci.distutils.release:add_to_stsci_package_index stsci.distutils-0.3.7/stsci.distutils.egg-info/top_level.txt0000644001134200020070000000000612256142702025166 0ustar embrayscience00000000000000stsci stsci.distutils-0.3.7/stsci.distutils.egg-info/not-zip-safe0000644001134200020070000000000112256142676024700 0ustar embrayscience00000000000000 stsci.distutils-0.3.7/MANIFEST.in0000644001134200020070000000004412256142676017344 0ustar embrayscience00000000000000include CHANGES.txt include tox.ini stsci.distutils-0.3.7/docs/0000755001134200020070000000000012256142707016533 5ustar embrayscience00000000000000stsci.distutils-0.3.7/docs/source/0000755001134200020070000000000012256142707020033 5ustar embrayscience00000000000000stsci.distutils-0.3.7/docs/source/index.rst0000644001134200020070000000073212256142676021703 0ustar embrayscience00000000000000.. stsci.distutils documentation master file, created by sphinx-quickstart on Wed Jan 16 15:48:41 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. :tocdepth: 3 ******************************************* Welcome to stsci.distutils's documentation! ******************************************* .. include:: ../../README.txt Appendix ======== .. toctree:: :maxdepth: 2 api changelog stsci.distutils-0.3.7/docs/source/changelog.rst0000644001134200020070000000003712256142676022521 0ustar embrayscience00000000000000.. include:: ../../CHANGES.txt stsci.distutils-0.3.7/docs/source/api.rst0000644001134200020070000000054212256142676021344 0ustar embrayscience00000000000000API documentation ================= stsci.distutils.hooks --------------------- .. automodule:: stsci.distutils.hooks :members: stsci.distutils.svnutils ------------------------ .. automodule:: stsci.distutils.svnutils :members: stsci.distutils.versionutils ---------------------------- .. automodule:: stsci.distutils.versionutils :members: stsci.distutils-0.3.7/docs/source/conf.py0000644001134200020070000001743312256142676021347 0ustar embrayscience00000000000000# -*- coding: utf-8 -*- # # stsci.distutils documentation build configuration file, created by # sphinx-quickstart on Wed Jan 16 15:48:41 2013. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os from stsci.sphinxext.conf import * # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions += [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'stsci.distutils' copyright = u'2013, Erik Bray, Mark Sienkiewicz, Christine Slocum' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.3.2' # The full version, including alpha/beta/rc tags. release = '0.3.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. #html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'stscidistutilsdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'stscidistutils.tex', u'stsci.distutils Documentation', u'Erik Bray, Mark Sienkiewicz, Christine Slocum', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'stscidistutils', u'stsci.distutils Documentation', [u'Erik Bray, Mark Sienkiewicz, Christine Slocum'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'stscidistutils', u'stsci.distutils Documentation', u'Erik Bray, Mark Sienkiewicz, Christine Slocum', 'stscidistutils', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' stsci.distutils-0.3.7/docs/Makefile0000644001134200020070000001274512256142676020211 0ustar embrayscience00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/stscidistutils.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/stscidistutils.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/stscidistutils" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/stscidistutils" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." stsci.distutils-0.3.7/stsci/0000755001134200020070000000000012256142707016730 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/0000755001134200020070000000000012256142707020754 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/astutils.py0000644001134200020070000000653712256142676023216 0ustar embrayscience00000000000000"""AST Visitors Currently only uses one for collecting a list of import statements. Unfortunately two versions of this have to be implemented: One for 2.6 and up and a different version for 2.5. """ import os import sys from distutils import log try: import ast # Python >= 2.6 def walk(filename, visitor): """Generate an AST for the given filename and walk over it using the given visitor instance. """ filename = os.path.abspath(filename) try: tree = ast.parse(open(filename, 'r').read()) except SyntaxError: if sys.version_info[0] < 3: e = sys.exc_info()[1] log.warn('SyntaxError while parsing file %s: %s' % (filename, str(e))) return # We're probably in Python 3 and looking at a file intended for # Python 2. Otherwise there's an unintended SyntaxError in the # file, so there are bigger problems anyways try: import lib2to3.refactor tool = StringRefactoringTool( lib2to3.refactor.get_fixers_from_package('lib2to3.fixes')) tool.refactor_file(filename, write=True) tree = ast.parse(tool.refactored[filename]) except ImportError: # Without 2to3 we can't do much more. # TODO: Issue a warning? return visitor.visit(tree) class ImportVisitor(ast.NodeVisitor): def __init__(self): self.imports = set() self.importfroms = set() def visit_Import(self, node): for name in node.names: self.imports.add((name.name, name.asname)) def visit_ImportFrom(self, node): for name in node.names: self.importfroms.add((node.module, name.name, name.asname)) except ImportError: import compiler def walk(filename, visitor): tree = compiler.parseFile(filename) compiler.walk(tree, visitor) class ImportVisitor(compiler.visitor.ASTVisitor): def __init__(self): self.imports = set() self.importfroms = set() def visitImport(self, node): for name in node.names: self.imports.add(name) def visitFrom(self, node): for name in node.names: self.importfroms.add((node.modname, name[0], name[1])) if sys.version_info[0] >= 3: try: import lib2to3.refactor class StringRefactoringTool(lib2to3.refactor.RefactoringTool): """A RefactoringTool that saves refactored files as strings in the self.refactored dict rather than outputting to actual files. This is used in case we're running in Python 3 and need to refactor a file before parsing its syntax tree. """ def __init__(self, fixer_names, options=None, explicit=None): super(StringRefactoringTool, self).__init__(fixer_names, options, explicit) self.refactored = {} def write_file(self, new_text, filename, old_text, encoding=None): self.refactored[filename] = new_text except ImportError: pass stsci.distutils-0.3.7/stsci/distutils/versionutils.py0000644001134200020070000001342112256142676024102 0ustar embrayscience00000000000000"""Utilities for dealing with package version info. See also stsci.distutils.svnutils which specifically deals with adding SVN info to version.py modules. """ from __future__ import with_statement import datetime import os import subprocess from .astutils import ImportVisitor, walk VERSION_PY_TEMPLATE = """ \"\"\"This is an automatically generated file created by %(hook_function)s. Do not modify this file by hand. \"\"\" __all__ = ['__version__', '__vdate__', '__svn_revision__', '__svn_full_info__', '__setup_datetime__'] import datetime __version__ = %(version)r __vdate__ = %(vdate)r __svn_revision__ = %(svn_revision)r __svn_full_info__ = %(svn_full_info)r __setup_datetime__ = %(setup_datetime)r # what version of stsci.distutils created this version.py stsci_distutils_version = %(stsci_distutils_version)r if '.dev' in __version__: def update_svn_info(): \"\"\"Update the SVN info if running out of an SVN working copy.\"\"\" import os import string import subprocess global __svn_revision__ global __svn_full_info__ path = os.path.abspath(os.path.dirname(__file__)) run_svnversion = True try: pipe = subprocess.Popen(['svn', 'info', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = pipe.communicate() if pipe.returncode == 0: lines = [] for line in stdout.splitlines(): line = line.decode('latin1').strip() if not line: continue lines.append(line) if not lines: __svn_full_info__ = ['unknown'] else: __svn_full_info__ = lines else: run_svnversion = False except OSError: run_svnversion = False if run_svnversion: # If updating the __svn_full_info__ succeeded then use its output # to find the base of the working copy and use svnversion to get # the svn revision. for line in __svn_full_info__: if line.startswith('Working Copy Root Path'): path = line.split(':', 1)[1].strip() break try: pipe = subprocess.Popen(['svnversion', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = pipe.communicate() if pipe.returncode == 0: stdout = stdout.decode('latin1').strip() if stdout and stdout[0] in string.digits: __svn_revision__ = stdout except OSError: pass # Convert __svn_full_info__ back to a string if isinstance(__svn_full_info__, list): __svn_full_info__ = '\\n'.join(__svn_full_info__) update_svn_info() del update_svn_info """[1:] def package_uses_version_py(package_root, package, module_name='version'): """Determines whether or not a version.py module should exist in the given package. Returns the full path to the version.py module, regardless of whether it already exists. Otherwise returns False. This works by checking whether or not there are any imports from the 'version' module in the package's ``__init__.py``. You should write this in your package's ``__init__.py``:: from .version import * """ pdir = os.path.join(package_root, *(package.split('.'))) init = os.path.join(pdir, '__init__.py') if not os.path.exists(init): raise Exception('Not a valid package - no __init__.py') try: visitor = ImportVisitor() walk(init, visitor) except: raise SyntaxError('Not able to parse %s' % init) found = False # Check the import statements parsed from the file for an import of or # from the svninfo module in this package for imp in visitor.imports: if imp[0] in (module_name, '.'.join((package, module_name))): found = True break for imp in visitor.importfroms: mod = imp[0] name = imp[1] if (mod in (module_name, '.'.join((package, module_name))) or (mod == package and name == module_name)): found = True break if not found: return False return os.path.join(pdir, module_name + '.py') def clean_version_py(package_dir, package): """Removes the generated version.py module from a package, but only if we're in an SVN working copy. """ pdir = os.path.join(package_root, *(package.split('.'))) version_py = os.path.join(pdir, 'version.py') if not os.path.exists(svninfo): return try: pipe = subprocess.Popen(['svn', 'status', svninfo], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: return if pipe.wait() != 0: return # TODO: Maybe don't assume ASCII here. Find out the best way to handle # this. if not pipe.stdout.read().decode('latin1').startswith('?'): return os.remove(version_py) def update_setup_datetime(filename='version.py'): """Update the version.py with the last time a setup command was run.""" if not os.path.exists(filename): return d = datetime.datetime.now() lines = [] with open(filename, 'r') as f: lines = f.readlines() with open(filename, 'w') as f: for line in lines: if not line.startswith('__setup_datetime__'): f.write(line) else: f.write('__setup_datetime__ = %r\n' % d) stsci.distutils-0.3.7/stsci/distutils/command/0000755001134200020070000000000012256142707022372 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/command/build_optional_ext.py0000644001134200020070000000632412256142676026642 0ustar embrayscience00000000000000from distutils import log from distutils.command.build_ext import build_ext from distutils.errors import DistutilsError, CCompilerError, CompileError from distutils.util import strtobool from ConfigParser import ConfigParser class build_optional_ext(build_ext): """This is a version of the build_ext command that allows specific extensions to be marked as 'optional'. If an optional extension fails to build, a warning message is displayed but the build does not cancel. It should be noted that this functionality already exists in the Python3 versions of distutils and packaging, but we must provide backwards compatibility for it. """ command_name = 'build_ext' def _find_optional_extensions(self, extensions): """Reads the setup.cfg to determine which extensions were set as 'optional'. Optionally, developers may also provide a warning message to display (otherwise a default message is used). This is one way in which this command improves on the existing functionality on Python 3. """ # TODO: However, support for the 'optional' extension attribute should # be included in d2to1, since it's a legitimate backwards compatibility # issue. But until I do another release it will have to be supported # here. cfg = ConfigParser() try: cfg.read('setup.cfg') except Exception, e: log.warn('Failed to read setup.cfg: %s; proceeding as though ' 'there are no optional extensions' % e) return # Map extension names to extension objects extensions = dict((ext.name, ext) for ext in extensions) for section in cfg.sections(): if not section.startswith('extension='): continue # The extension name can be specified with the 'name' option, but # if that's missing the name is taken from the section header for # now if cfg.has_option(section, 'name'): name = cfg.get(section, 'name') else: _, name = section.split('=', 1) if name not in extensions: # Could happen, for example, if a setup_hook disabled some # extensions continue ext = extensions[name] if cfg.has_option(section, 'optional'): ext._optional = strtobool(cfg.get(section, 'optional')) else: ext._optional = False if cfg.has_option(section, 'fail_message'): ext._fail_message = cfg.get(section, 'fail_message') def check_extensions_list(self, extensions): build_ext.check_extensions_list(self, extensions) self._find_optional_extensions(extensions) def build_extension(self, ext): try: build_ext.build_extension(self, ext) except (CCompilerError, DistutilsError, CompileError), e: if not hasattr(ext, '_optional') or not ext._optional: raise log.warn('building optional extension "%s" failed: %s' % (ext.name, e)) if hasattr(ext, '_fail_message'): log.warn(ext._fail_message) stsci.distutils-0.3.7/stsci/distutils/command/__init__.py0000644001134200020070000000000012256142676024476 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/command/easier_install.py0000644001134200020070000000746612256142676025764 0ustar embrayscience00000000000000import os try: from ConfigParser import ConfigParser except ImportError: # This is necessary for when stsci.distutils is being bootstrapped by other # setup.pys in stsci_python--otherwise the ConfigParser import would be # converted by d2to1 from configparser import ConfigParser from distutils import log import pkg_resources from setuptools.command.easy_install import easy_install from setuptools.package_index import PackageIndex def distro_from_setup_cfg(filename): """ Read a source checkout's distutils2 setup.cfg and create a Distribution for that checkout. filename can either be the path to the setup.cfg itself, or checkout directory containing the setup.cfg. """ if os.path.isdir(filename): path = filename filename = os.path.join(filename, 'setup.cfg') if not os.path.exists(filename): return None else: path, basename = os.path.split(filename) if basename != 'setup.cfg': return None cfg = ConfigParser() cfg.read(filename) if not cfg.has_option('metadata', 'name'): return None name = cfg.get('metadata', 'name') if cfg.has_option('metadata', 'version'): version = cfg.get('metadata', 'version') else: version = None return pkg_resources.Distribution( location=path, project_name=name, version=version, precedence=pkg_resources.CHECKOUT_DIST) class LocalSourcesPackageIndex(PackageIndex): """ Like PackageIndex, but can also install packages from local source checkouts, the locations of which are added via add_find_links(). Although PackageIndex supports installing for source distributions on the local filesystem, they must be in a tar/zip/etc. This allows installing from an existing source checkout on the local filesystem. """ def process_filename(self, fn, nested=False): PackageIndex.process_filename(self, fn, nested) dist = distro_from_setup_cfg(fn) if dist: self.add(dist) def fetch_distribution(self, requirement, tmpdir, force_scan=False, source=False, develop_ok=False, local_index=None): distribute_req = pkg_resources.Requirement.parse('distribute>=0.6.14') if pkg_resources.get_distribution('distribute') in distribute_req: # The local_index parameter is only in distribute>=0.6.14 dist = PackageIndex.fetch_distribution(self, requirement, tmpdir, force_scan, source, develop_ok, local_index) else: dist = PackageIndex.fetch_distribution(self, requirement, tmpdir, force_scan, source, develop_ok) if dist: log.info('Using %s from %s' % (dist, dist.location)) return dist class easier_install(easy_install): """ Extension to the easy_install command that uses LocalSourcesPackageIndex as its default PackageIndex implementation. """ command_name = 'easy_install' create_index = LocalSourcesPackageIndex def process_distribution(self, requirement, dist, deps=True, *info): """This version of process_distribution will force the package index to search for local distributions before going out to PyPI when processing a package's dependency. It will already do this for the first dependency, but not for subsequent dependencies--something I would consider a bug. """ if self.package_index.to_scan is None: self.package_index.to_scan = [] return easy_install.process_distribution(self, requirement, dist, deps, *info) stsci.distutils-0.3.7/stsci/distutils/version.py0000644001134200020070000000626212256142702023014 0ustar embrayscience00000000000000"""This is an automatically generated file created by stsci.distutils.hooks.version_setup_hook. Do not modify this file by hand. """ __all__ = ['__version__', '__vdate__', '__svn_revision__', '__svn_full_info__', '__setup_datetime__'] import datetime __version__ = '0.3.7' __vdate__ = 'unspecified' __svn_revision__ = '28700' __svn_full_info__ = 'Path: stsci.distutils-0.3.7-eLbs04\nWorking Copy Root Path: /tmp/stsci.distutils-0.3.7-eLbs04\nURL: https://svn.stsci.edu/svn/ssb/stsci_python/stsci.distutils/tags/0.3.7\nRepository Root: https://svn.stsci.edu/svn/ssb/stsci_python\nRepository UUID: fe389314-cf27-0410-b35b-8c050e845b92\nRevision: 28700\nNode Kind: directory\nSchedule: normal\nLast Changed Author: embray\nLast Changed Rev: 28700\nLast Changed Date: 2013-12-23 18:22:33 -0500 (Mon, 23 Dec 2013)' __setup_datetime__ = datetime.datetime(2013, 12, 23, 18, 22, 42, 121484) # what version of stsci.distutils created this version.py stsci_distutils_version = '0.3.7' if '.dev' in __version__: def update_svn_info(): """Update the SVN info if running out of an SVN working copy.""" import os import string import subprocess global __svn_revision__ global __svn_full_info__ path = os.path.abspath(os.path.dirname(__file__)) run_svnversion = True try: pipe = subprocess.Popen(['svn', 'info', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = pipe.communicate() if pipe.returncode == 0: lines = [] for line in stdout.splitlines(): line = line.decode('latin1').strip() if not line: continue lines.append(line) if not lines: __svn_full_info__ = ['unknown'] else: __svn_full_info__ = lines else: run_svnversion = False except OSError: run_svnversion = False if run_svnversion: # If updating the __svn_full_info__ succeeded then use its output # to find the base of the working copy and use svnversion to get # the svn revision. for line in __svn_full_info__: if line.startswith('Working Copy Root Path'): path = line.split(':', 1)[1].strip() break try: pipe = subprocess.Popen(['svnversion', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, _ = pipe.communicate() if pipe.returncode == 0: stdout = stdout.decode('latin1').strip() if stdout and stdout[0] in string.digits: __svn_revision__ = stdout except OSError: pass # Convert __svn_full_info__ back to a string if isinstance(__svn_full_info__, list): __svn_full_info__ = '\n'.join(__svn_full_info__) update_svn_info() del update_svn_info stsci.distutils-0.3.7/stsci/distutils/svnutils.py0000644001134200020070000000274112256142676023226 0ustar embrayscience00000000000000"""Functions for getting and saving SVN info for distribution.""" from __future__ import with_statement import os import subprocess from .astutils import ImportVisitor, walk def get_svn_version(path='.'): """Uses ``svnversion`` to get just the latest revision at the given path. """ try: pipe = subprocess.Popen(['svnversion', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: return None if pipe.wait() != 0: return None return pipe.stdout.read().decode('latin1').strip() def get_svn_info(path='.'): """Uses ``svn info`` to get the full information about the working copy at the given path. """ path = os.path.abspath(path) try: pipe = subprocess.Popen(['svn', 'info', path], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stderr is redirected in order to squelch it. Later Python versions # have subprocess.DEVNULL for this purpose, but it's not available in # 2.5 except OSError: return 'unknown' if pipe.wait() != 0: return 'unknown' lines = [] for line in pipe.stdout.readlines(): line = line.decode('latin1').strip() if not line: continue if line.startswith('Path:'): line = 'Path: %s' % os.path.basename(path) lines.append(line) if not lines: return 'unknown' return '\n'.join(lines) stsci.distutils-0.3.7/stsci/distutils/hooks.py0000644001134200020070000004107712256142676022467 0ustar embrayscience00000000000000from __future__ import with_statement import datetime import glob import os import string import sys from distutils import log try: from packaging.util import split_multiline except ImportError: try: from distutils2.util import split_multiline except ImportError: from d2to1.util import split_multiline try: # python 2 reload except NameError: # python 3 from imp import reload from .svnutils import get_svn_info, get_svn_version from .versionutils import (package_uses_version_py, clean_version_py, update_setup_datetime, VERSION_PY_TEMPLATE) # For each version.py that we create, we will note the version of # stsci.distutils (this package) that created it. The problem is # when the package being installed is stsci.distutils -- we don't # know the version yet. So, if we can't import the version (because # it does not exist yet), we declare it to be None and special case # it later. try : from . import version as my_version except ImportError : my_version = None def is_display_option(ignore=None): """A hack to test if one of the arguments passed to setup.py is a display argument that should just display a value and exit. If so, don't bother running this hook (this capability really ought to be included with distutils2). Optionally, ignore may contain a list of display options to ignore in this check. Each option in the ignore list must contain the correct number of dashes. """ from setuptools.dist import Distribution # If there were no arguments in argv (aside from the script name) then this # is an implied display opt if len(sys.argv) < 2: return True display_opts = ['--command-packages', '--help', '-h'] for opt in Distribution.display_options: display_opts.append('--' + opt[0]) for arg in sys.argv: if arg in display_opts and arg not in ignore: return True return False # TODO: With luck this can go away soon--packaging now supports adding the cwd # to sys.path for running setup_hooks. But it also needs to support adding # packages_root. Also, it currently does not support adding cwd/packages_root # to sys.path for pre/post-command hooks, so that needs to be fixed. def use_packages_root(config): """ Adds the path specified by the 'packages_root' option, or the current path if 'packages_root' is not specified, to sys.path. This is particularly useful, for example, to run setup_hooks or add custom commands that are in your package's source tree. Use this when the root of your package source tree is not in the same directory with the setup.py Config Usage:: [files] packages_root = lib # for installing pkgname from lib/pkgname/*.py [global] setup_hooks = stsci.distutils.hooks.use_packages_root """ if 'files' in config and 'packages_root' in config['files']: root = config['files']['packages_root'] else: root = '' if root not in sys.path: if root and sys.path[0] == '': sys.path.insert(1, root) else: sys.path.insert(0, root) # Reload the stsci namespace package in case any new paths can be added to # it from the new sys.path entry; depending on how the namespace packages # are installed this may fail--specifically if it's using the old # setuptools-based .pth approach there is not importable package called # 'stsci' that can be imported by itself. if 'stsci' in sys.modules: mod = sys.modules['stsci'] if sys.version_info[:2] >= (3, 3) and not hasattr(mod, '__loader__'): # Workaround for Python bug #17099 on Python 3.3, where reload() # crashes if a module doesn't have an __loader__ attribute del sys.modules['stsci'] try: import stsci except ImportError: pass else: try : reload(sys.modules['stsci']) except ImportError: # doesn't seem to bother anything when this reload() fails pass def tag_svn_revision(config): """ A setup_hook to add the SVN revision of the current working copy path to the package version string, but only if the version ends in .dev. For example, ``mypackage-1.0.dev`` becomes ``mypackage-1.0.dev1234``. This is in accordance with the version string format standardized by PEP 386. This should be used as a replacement for the ``tag_svn_revision`` option to the egg_info command. This hook is more compatible with packaging/distutils2, which does not include any VCS support. This hook is also more flexible in that it turns the revision number on/off depending on the presence of ``.dev`` in the version string, so that it's not automatically added to the version in final releases. This hook does require the ``svnversion`` command to be available in order to work. It does not examine the working copy metadata directly. Config Usage:: [global] setup_hooks = stsci.distutils.hooks.tag_svn_revision You should write exactly this in your package's ``__init__.py``:: from .version import * """ if 'metadata' in config and 'version' in config['metadata']: metadata = config['metadata'] version = metadata['version'] # Don't add an svn revision unless the version ends with .dev if not version.endswith('.dev'): return # First try to get the revision by checking for it in an existing # .version module package_dir = config.get('files', {}).get('packages_root', '') packages = config.get('files', {}).get('packages', '') packages = split_multiline(packages) rev = None for package in packages: version_py = package_uses_version_py(package_dir, package) if not version_py: continue try: mod = __import__(package + '.version', fromlist='__svn_revision__') except ImportError: mod = None if mod is not None and hasattr(mod, '__svn_revision__'): rev = mod.__svn_revision__ break # Cleanup names = set([package, package + '.']) for modname in list(sys.modules): if modname == package or modname.startswith(package + '.'): del sys.modules[modname] if rev is None: # A .version module didn't exist or was incomplete; try calling # svnversion directly rev = get_svn_version() if not rev: return if ':' in rev: rev, _ = rev.split(':', 1) while rev and rev[-1] not in string.digits: rev = rev[:-1] try: rev = int(rev) except (ValueError, TypeError): return metadata['version'] ='%s%d' % (version, rev) def _version_hook(function_name, package_dir, packages, name, version, vdate): """This command hook creates an version.py file in each package that requires it. This is by determining if the package's ``__init__.py`` tries to import or import from the version module. version.py will not be created in packages that don't use it. It should only be used by the top-level package of the project. Don't use this function directly--instead use :func:`version_setup_hook` or :func:`version_pre_command_hook` which know how to retrieve the required metadata depending on the context they are run in. Not called directly from the config file. See :func:`version_setup_hook`. """ # Strip any revision info from version; that will be handled separately if '-' in version: version = version.split('-', 1)[0] for package in packages: version_py = package_uses_version_py(package_dir, package) if not version_py: continue rev = get_svn_version() if ((not rev or not rev[0] in string.digits) and os.path.exists(version_py)): # If were unable to determine an SVN revision and the version.py # already exists, just update the __setup_datetime__ and leave the # rest of the file untouched update_setup_datetime(version_py) return elif rev is None: rev = 'Unable to determine SVN revision' svn_info = get_svn_info() # Wrap version, rev, and svn_info in str() to ensure that Python 2 # unicode literals aren't written, which will break things in Python 3 template_variables = { 'hook_function': function_name, 'name': name, 'version': str(version), 'vdate': str(vdate), 'svn_revision': str(rev), 'svn_full_info': str(svn_info), 'setup_datetime': datetime.datetime.now(), } # my_version is version.py for the stsci.distutils package. # It can be None if we are called during the install of # stsci.distutils; we are creating the version.py, so it was # not available to import yet. If this is what is happening, # we construct it specially. if my_version is None : if package == 'stsci.distutils' : template_variables['stsci_distutils_version'] = version else: # It should never happen that version.py does not # exist when we are installing any other package. raise RuntimeError('Internal consistency error') else : template_variables['stsci_distutils_version'] = \ my_version.__version__ with open(version_py, 'w') as f: f.write(VERSION_PY_TEMPLATE % template_variables) def version_setup_hook(config): """Creates a Python module called version.py which contains these variables: * ``__version__`` (the release version) * ``__svn_revision__`` (the SVN revision info as returned by the ``svnversion`` command) * ``__svn_full_info__`` (as returned by the ``svn info`` command) * ``__setup_datetime__`` (the date and time that setup.py was last run). * ``__vdate__`` (the release date) These variables can be imported in the package's ``__init__.py`` for degugging purposes. The version.py module will *only* be created in a package that imports from the version module in its ``__init__.py``. It should be noted that this is generally preferable to writing these variables directly into ``__init__.py``, since this provides more control and is less likely to unexpectedly break things in ``__init__.py``. Config Usage:: [global] setup-hooks = stsci.distutils.hooks.version_setup_hook You should write exactly this in your package's ``__init__.py``:: from .version import * """ if is_display_option(ignore=['--version']): return name = config['metadata'].get('name') version = config['metadata'].get('version', '0.0.0') vdate = config['metadata'].get('vdate', 'unspecified') package_dir = config.get('files', {}).get('packages_root', '') packages = config.get('files', {}).get('packages', '') packages = split_multiline(packages) _version_hook(__name__ + '.version_setup_hook', package_dir, packages, name, version, vdate) def version_pre_command_hook(command_obj): """ .. deprecated:: 0.3 Use :func:`version_setup_hook` instead; it's generally safer to check/update the version.py module on every setup.py run instead of on specific commands. This command hook creates an version.py file in each package that requires it. This is by determining if the package's ``__init__.py`` tries to import or import from the version module. version.py will not be created in packages that don't use it. It should only be used by the top-level package of the project. """ if is_display_option(): return package_dir = command_obj.distribution.package_dir.get('', '.') packages = command_obj.distribution.packages name = command_obj.distribution.metadata.name version = command_obj.distribution.metadata.version _version_hook(__name__ + '.version_pre_command_hook',package_dir, packages, name, version, vdate=None) def version_post_command_hook(command_obj): """ .. deprecated:: 0.3 This hook was meant to complement :func:`version_pre_command_hook`, also deprecated. Cleans up a previously generated version.py in order to avoid clutter. Only removes the file if we're in an SVN working copy and the file is not already under version control. """ package_dir = command_obj.distribution.package_dir.get('', '.') packages = command_obj.distribution.packages for package in packages: clean_version_py(package_dir, package) def numpy_extension_hook(command_obj): """A distutils2 pre-command hook for the build_ext command needed for building extension modules that use NumPy. To use this hook, add 'numpy' to the list of include_dirs in setup.cfg section for an extension module. This hook will replace 'numpy' with the necessary numpy header paths in the include_dirs option for that extension. Note: Although this function uses numpy, stsci.distutils does not depend on numpy. It is up to the distribution that uses this hook to require numpy as a dependency. Config Usage:: [extension=mypackage.extmod] sources = foo.c bar.c include_dirs = numpy [build_ext] pre-hook.numpy-extension = stsci.distutils.hooks.numpy_extension_hook """ command_name = command_obj.get_command_name() if command_name != 'build_ext': log.warn('%s is meant to be used with the build_ext command only; ' 'it is not for use with the %s command.' % (__name__, command_name)) try: import numpy except ImportError: # It's virtually impossible to automatically install numpy through # setuptools; I've tried. It's not pretty. # Besides, we don't want users complaining that our software doesn't # work just because numpy didn't build on their system. sys.stderr.write('\n\nNumpy is required to build this package.\n' 'Please install Numpy on your system first.\n\n') sys.exit(1) includes = [numpy.get_include()] #includes = [numpy.get_numarray_include(), numpy.get_include()] for extension in command_obj.extensions: if 'numpy' not in extension.include_dirs: continue idx = extension.include_dirs.index('numpy') for inc in includes: extension.include_dirs.insert(idx, inc) extension.include_dirs.remove('numpy') def glob_data_files(command_obj): """A pre-command hook for the install_data command allowing wildcard patterns to be used in the data_files option. Also ensures that data files with relative paths as their targets are installed relative install_lib. Config Usage:: [files] data_files = target_directory = source_directory/*.foo other_target_directory = other_source_directory/* [install_data] pre-hook.glob-data-files = stsci.distutils.hooks.glob_data_files """ command_name = command_obj.get_command_name() if command_name != 'install_data': log.warn('%s is meant to be used with the install_data command only; ' 'it is not for use with the %s command.' % (__name__, command_name)) data_files = command_obj.data_files for idx, val in enumerate(data_files[:]): if isinstance(val, basestring): # Support the rare, deprecated case where just a filename is given filenames = glob.glob(val) del data_files[idx] data_files.extend(filenames) continue dest, filenames = val filenames = sum((glob.glob(item) for item in filenames), []) data_files[idx] = (dest, filenames) # Ensure the correct install dir; this is the default behavior for # installing with distribute, but when using # --single-version-externally-managed we need to to tweak this install_cmd = command_obj.get_finalized_command('install') if command_obj.install_dir == install_cmd.install_data: install_lib_cmd = command_obj.get_finalized_command('install_lib') command_obj.install_dir = install_lib_cmd.install_dir stsci.distutils-0.3.7/stsci/distutils/release.py0000644001134200020070000001501212256142676022752 0ustar embrayscience00000000000000"""Hooks for zest.releaser specifically for STScI software""" import glob import os import shutil import sys from ConfigParser import ConfigParser from setuptools.dist import Distribution from zest.releaser.utils import ask DEFAULT_PACKAGE_INDEX_PATH = '/eng/ssb/web/download/packages' PACKAGE_INDEX_URL = 'http://stsdas.stsci.edu/download/packages/index' def is_stsci_project(workingdir): """ Returns True if the product being released is from STScI and is using the d2to1 + stsci.distutils build/install platform. This is determined via some basic introspection of the project layout; namely that it contains a setup.cfg, and that the author-email value contains '@stsci.edu'. It's ham-fisted but it should do for now. """ setup_cfg = os.path.join(workingdir, 'setup.cfg') if not os.path.exists(setup_cfg): return False cfg = ConfigParser() cfg.read(setup_cfg) if cfg.has_option('metadata', 'author-email'): author_email = cfg.get('metadata', 'author-email') elif cfg.has_option('metadata', 'author_email'): author_email = cfg.get('metadata', 'author_email') else: author_email = '' return '@stsci.edu' in author_email def fix_dev_version_template(data): """ A postreleaser.before hook to change the dev_version_template from the annoying default of 'x.y.z.dev0' to just 'x.y.z.dev' without the 0. """ if not is_stsci_project(data['workingdir']): return data['dev_version_template'] = '%(new_version)s.dev' def fix_sdist_format(data): """ Recent versions of zest.releaser have an annoyance that it creates .zip sdists instead of .tar.gz. This is supposedly to work around a bug in Python 2.4 with .tar.gz sdists, but none of our software supports Python 2.4 anyways. Unfortunately the only way to disable this behavior, for now, is with monkey-patching zest.releaser. """ if not is_stsci_project(data['workingdir']): return from zest.releaser.release import Releaser def _my_sdist_options(self): return '' Releaser._sdist_options = _my_sdist_options def add_to_stsci_package_index(data): """ A releaser.after hook to copy the source distribution to STScI's local package index and update the index using basketweaver. """ if not is_stsci_project(data['workingdir']): return if not data['tagdir'] or not os.path.exists(data['tagdir']): # Do nothing if a tag checkout was not performed return if not ask('Copy source package to STScI package index'): return package_path = DEFAULT_PACKAGE_INDEX_PATH if not os.path.exists(package_path): package_path = '' question = 'Path to package directory' if package_path: # A default exists; let the user know question += ' [%s]' % package_path question += ': ' answer = '' while not answer: try: answer = raw_input(question).strip() if not answer: if package_path: # The user simple pressed enter, so use the supplied # default answer = package_path else: continue if not os.path.exists(answer): print ('The supplied path %s does not exist. Please enter a ' 'different path or press Ctrl-C to cancel.' % answer) if not os.access(answer, os.W_OK): print ('The supplied path %s is not writeable. Either change ' 'the permissions of the directory or have someone ' 'grant you access and try again, enter a different ' 'directory, or press Ctrl-C to cancel.' % answer) package_path = answer break # The default was not supplied, so keep asking except KeyboardInterrupt: return # A tag checkout was made and an sdist created, this is where it would be # (the sdist is a .zip on Windows, a .tar.gz elsewhere--normally this # should be .tar.gz; don't make releases on Windows) sdist_file = '' while not sdist_file: try: sdist_file = glob.glob(os.path.join(data['tagdir'], 'dist', '*.tar.gz'))[0] except IndexError: try: sdist_file = glob.glob(os.path.join(data['tagdir'], 'dist', '*.zip'))[0] except IndexError: try: print ( "Could not find a source distribution in %s; did you " "do a source checkout for upload? If possible, try " "to cd to %s and manually create a source " "distribution by running `python setup.py sdist`. " "Then press enter to try again (or hit Ctrl-C to " "cancel). Go ahead, I'll wait..." % (data['tagdir'], data['tagdir'])) raw_input() except KeyboardInterrupt: return # Almost ready go to--now we just need to check if basketweaver is # available, and get it if not. try: import basketweaver.makeindex except ImportError: # Use setuptools' machinery to fetch a package and add it to the path; # we could do this without using setuptools directly, but it would # basically end up reimplementing much of the same code. dist = Distribution({'dependency_links': [PACKAGE_INDEX_URL]}) try: dist.fetch_build_eggs(['basketweaver']) except: # There are so many things that could possibly go wrong here... print ('Failed to get basketweaver, which is required to rebuild ' 'the package index. To manually complete the release, ' 'install basketweaver manually, then copy %s into %s, cd ' 'to %s, and then run `makeindex *`, where makeindex is the ' 'command installed by basketweaver.' % (sdist_file, package_path, package_path)) import basketweaver.makeindex # Now we should have everything we need... shutil.copy(sdist_file, package_path) old_cwd = os.getcwd() os.chdir(package_path) try: basketweaver.makeindex.main(glob.glob('*')) finally: os.chdir(old_cwd) print 'Finished adding package to %s.' % PACKAGE_INDEX_URL stsci.distutils-0.3.7/stsci/distutils/__init__.py0000644001134200020070000000071512256142676023075 0ustar embrayscience00000000000000try: from .version import (__version__, __svn_revision__, __svn_full_info__, __setup_datetime__) except ImportError: # If this happens, I hope this import is happening in the # stsci.distutils setup.py because we are about to use # stsci.distutils.hooks to install stsci.distutils __version__ = 'unspecified during initial install' __svn_revision__ = '' __svn_full_info__ = '' __setup_datetime__ = None stsci.distutils-0.3.7/stsci/distutils/tests/0000755001134200020070000000000012256142707022116 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/test_commands.py0000644001134200020070000000531612256142676025342 0ustar embrayscience00000000000000from __future__ import with_statement import os import sys try: import numpy except ImportError: numpy = None from nose import SkipTest from . import StsciDistutilsTestCase from .util import get_compiler_command, open_config class TestCommands(StsciDistutilsTestCase): def test_build_optional_ext(self): if numpy is None: raise SkipTest("numpy is required to run this test") # The test extension in the test package is already configured to be # "optional" by default--we'll do one test build to make sure that goes # smoothly compiler_cmd = get_compiler_command() _, _, exit_code = self.run_setup('build') # Make sure the build went successfully; a zero exit code should be # good enough for our purposes assert exit_code == 0 # Now let's try breaking the build with open(os.path.join('src', 'testext.c'), 'a') as f: f.write('1/0') # We leave off the exit status from the compiler--in most cases it will # say "exit status 1" but that can't be guaranteed for all compilers msg = ('building optional extension "stsci.testpackage.testext" ' 'failed: command \'%s\' failed with exit status' % compiler_cmd) # Prior to Python 2.7, distutils.log output everything to stdout; now # warnings and errors are output to stderr if sys.version_info[:2] < (2, 7): stderr, _, exit_code = self.run_setup('build', '--force') else: _, stderr, exit_code = self.run_setup('build', '--force') assert exit_code == 0 assert stderr.splitlines()[-1].startswith(msg) # Test a custom fail message with open_config('setup.cfg') as cfg: cfg.set('extension=stsci.testpackage.testext', 'fail_message', 'Custom fail message.') if sys.version_info[:2] < (2, 7): stderr, _, exit_code = self.run_setup('build', '--force') else: _, stderr, exit_code = self.run_setup('build', '--force') assert exit_code == 0 assert stderr.splitlines()[-1] == 'Custom fail message.' # Finally, make sure the extension is *not* treated as optional if not # marked as such in the config with open_config('setup.cfg') as cfg: cfg.remove_option('extension=stsci.testpackage.testext', 'optional') # This error message comes out on stderr for all Python versions AFAICT msg = "error: command '%s' failed with exit status" % compiler_cmd _, stderr, exit_code = self.run_setup('build', '--force') assert exit_code != 0 assert stderr.splitlines()[-1].startswith(msg) stsci.distutils-0.3.7/stsci/distutils/tests/test_hooks.py0000644001134200020070000002201512256142676024657 0ustar embrayscience00000000000000from __future__ import with_statement import glob import os import sys import tarfile import time import zipfile from datetime import datetime from setuptools import Distribution try: import numpy except ImportError: numpy = None from nose import SkipTest from . import StsciDistutilsTestCase, TESTPACKAGE_REV from .util import reload, get_compiler_command, open_config, rmtree VERSION = '0.1.dev' + TESTPACKAGE_REV class TestHooks(StsciDistutilsTestCase): def test_setup_py_version(self): """ Test that the `./setupy.py --version` command returns the correct value without balking. """ self.run_setup('egg_info') stdout, _, _ = self.run_setup('--version') assert stdout == VERSION def test_version_with_rev(self): """Test that the version string contains the correct SVN revision.""" # Build the package self.run_setup('build') self.run_setup('sdist') import stsci.testpackage assert hasattr(stsci.testpackage, '__version__') assert stsci.testpackage.__version__ == VERSION assert hasattr(stsci.testpackage, '__svn_revision__') assert stsci.testpackage.__svn_revision__ == TESTPACKAGE_REV filenames = [os.path.join('dist', 'stsci.testpackage-%s.%s' % (VERSION, ext)) for ext in ('tar.gz', 'zip')] assert os.path.exists(filenames[0]) or os.path.exists(filenames[1]) def test_release_version(self): """ Ensure that the SVN revision is not appended to release versions (i.e. not ending with '.dev'. """ with open_config('setup.cfg') as cfg: cfg.set('metadata', 'version', '0.1') self.run_setup('egg_info') stdout, _, _ = self.run_setup('--version') assert stdout == '0.1' def test_inline_svn_update(self): """Test version.py's capability of updating the SVN info at runtime.""" self.run_setup('build') import stsci.testpackage assert hasattr(stsci.testpackage, '__svn_revision__') assert stsci.testpackage.__svn_revision__ == TESTPACKAGE_REV with open('TEST', 'w') as f: # Create an empty file pass self.run_svn('add', 'TEST') # The working copy has been modified, so now svnversion (which is used # to generate __svn_revision__) should be the revision + 'M' reload(stsci.testpackage.version) reload(stsci.testpackage) assert stsci.testpackage.__svn_revision__ == TESTPACKAGE_REV + 'M' def test_setup_datetime(self): """ Test that the setup datetime is present, and is updated by subsequent setup.py runs. """ # Build the package self.run_setup('build') import stsci.testpackage assert hasattr(stsci.testpackage, '__setup_datetime__') prev = stsci.testpackage.__setup_datetime__ now = datetime.now() # Rebuild # So that there's less chance for ambiguity time.sleep(1) self.run_setup('build') reload(stsci.testpackage.version) reload(stsci.testpackage) import stsci.testpackage assert hasattr(stsci.testpackage, '__setup_datetime__') assert stsci.testpackage.__setup_datetime__ > now assert stsci.testpackage.__setup_datetime__ > prev def test_numpy_extension_hook(self): """Test basic functionality of the Numpy extension hook.""" if numpy is None: raise SkipTest("numpy is required to run this test") compiler_cmd = get_compiler_command() stdout, _, _ = self.run_setup('build') for line in stdout.splitlines(): # Previously this used shlex.split(), but that's broken for unicode # strings prior to Python 3.x, and it doesn't matter too much since # we only care about the first argument args = line.split() if not args: continue if args[0] != compiler_cmd: continue # The first output from the compiler should be an attempt to # compile a c file to an object, so that should include all the # include paths. This is of course not universally true, but it # should hold true for this test case for path in [numpy.get_include()]: #for path in [numpy.get_include(), numpy.get_numarray_include()]: assert '-I' + path in args break # And for the heck of it, let's ensure that this doesn't happen if # 'numpy' is not listed in include_dirs with open_config('setup.cfg') as cfg: cfg.remove_option('extension=stsci.testpackage.testext', 'include_dirs') rmtree('build') stdout, _, _ = self.run_setup('build') for line in stdout.splitlines(): args = line.split() if not args: continue if args[0] != compiler_cmd: continue for path in [numpy.get_include()]: #for path in [numpy.get_include(), numpy.get_numarray_include()]: assert '-I' + path not in args def test_glob_data_files(self): """ Test the glob_data_files hook by ensuring that all the correct data files are included in the source distribution, and that they are installed to the correct location in the package. """ data_files = os.path.join('stsci', 'testpackage', 'data_files') # First test the source distribution self.run_setup('sdist') # There can be only one try: tf = glob.glob(os.path.join('dist', '*.tar.gz'))[0] except IndexError: # No tar.gz files found? On Windows sdist creates a .zip file, so # let's look for that tf = glob.glob(os.path.join('dist', '*.zip'))[0] # If that failed then I don't know--I guess the test should fail if tf.endswith('.tar.gz'): tf = tarfile.open(tf) # Tarfiles created by sdist kindly place all contents in a # top-level directory with the same name as the file minus # extension, so as to kindly not bomb you when you extract it. But # we don't care about that top level directory names = ['/'.join(p.split('/')[1:]) for p in tf.getnames()] else: with zipfile.ZipFile(tf) as zf: names = ['/'.join(p.split('/')[1:]) for p in zf.namelist()] # Sdists should place the data_files at the root, just like in the # normal source layout; even files that aren't normally installed # should be included for filename in ['a.txt', 'b.txt', 'c.rst']: # Don't use os.path.join -- zipfile/tarfile always return paths # with / as path sep assert ('data_files/' + filename) in names # Now we test that data_files go to the right place in various install # schemes def get_install_lib(args): # This helper uses the distutils/setuptools machinery to determine # where a command will install files based on the arguments passed # to setup.py dist = Distribution({'script_args': args}) dist.parse_command_line() install_cmd = dist.get_command_obj('install') install_cmd.ensure_finalized() return install_cmd.install_lib def test_install_scheme(args): if numpy is None: raise SkipTest("numpy is required to run this test") # This general code should work to test the files in a variety of # install schemes depending on args if os.path.exists('temp'): rmtree('temp') install_lib = get_install_lib(args) os.makedirs(install_lib) old_pythonpath = os.environ.get('PYTHONPATH') # For a setuptools/easy_install-stype install to an alternate # prefix we have to have the new install dir on the PYTHONPATH or # easy_install will balk os.environ['PYTHONPATH'] = ( install_lib + os.pathsep + (old_pythonpath if old_pythonpath else '')) try: self.run_setup(*(args + ['--record=installed.txt'])) finally: if old_pythonpath is not None: os.environ['PYTHONPATH'] = old_pythonpath found_files = 0 with open('installed.txt') as f: # installed.txt, however, contains OS-specific paths for line in f: for name in ['a.txt', 'b.txt', 'c.rst']: if line.strip().endswith(os.sep + name): found_files += 1 assert found_files == 2 test_install_scheme(['install', '--prefix=temp']) test_install_scheme(['install', '--root=temp']) test_install_scheme(['install', '--install-lib=temp']) stsci.distutils-0.3.7/stsci/distutils/tests/util.py0000644001134200020070000000247312256142676023460 0ustar embrayscience00000000000000from __future__ import with_statement import contextlib import os import shutil import stat try: reload = reload except NameError: from imp import reload from ConfigParser import ConfigParser from distutils.ccompiler import new_compiler from distutils.msvccompiler import MSVCCompiler from distutils.sysconfig import customize_compiler @contextlib.contextmanager def open_config(filename): cfg = ConfigParser() cfg.read(filename) yield cfg with open(filename, 'w') as fp: cfg.write(fp) def get_compiler_command(): """ Returns the name of the executable used by the default compiler on the system used by distutils to build C extensions. """ compiler = new_compiler() customize_compiler(compiler) if isinstance(compiler, MSVCCompiler): compiler.initialize() # Normally the compiler path will be quoted as it contains spaces return '"%s"' % compiler.cc return compiler.compiler[0] def rmtree(path): """ shutil.rmtree() with error handler for 'access denied' from trying to delete read-only files. """ def onerror(func, path, exc_info): if not os.access(path, os.W_OK): os.chmod(path, stat.S_IWUSR) func(path) else: raise return shutil.rmtree(path, onerror=onerror) stsci.distutils-0.3.7/stsci/distutils/tests/__init__.py0000644001134200020070000000570212256142676024240 0ustar embrayscience00000000000000import os import shutil import subprocess import sys import tempfile import nose from .util import reload, rmtree TESTPACKAGE_URL = ('https://svn.stsci.edu/svn/ssb/stsci_python/' 'stsci.distutils/trunk/stsci/distutils/tests/testpackage') TESTPACKAGE_REV = '17597' # The last known 'good' revision of this package class StsciDistutilsTestCase(object): @classmethod def setup_class(cls): cls.wc_dir = tempfile.mkdtemp(prefix='stsci-distutils-test-') try: p = subprocess.Popen(['svn', '-r', TESTPACKAGE_REV, '--non-interactive', '--trust-server-cert', 'checkout', TESTPACKAGE_URL, cls.wc_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError, e: raise nose.SkipTest('svn unavailable to checkout out test ' 'package: %s' % e) if p.wait() != 0: raise nose.SkipTest('svn failed to check out the test package: ' '%s; tests will not be able to run' % p.stderr.read().decode('latin1')) @classmethod def teardown_class(cls): rmtree(cls.wc_dir) def setup(self): self.temp_dir = tempfile.mkdtemp(prefix='stsci-distutils-test-') self.package_dir = os.path.join(self.temp_dir, 'testpackage') shutil.copytree(self.wc_dir, self.package_dir) self.oldcwd = os.getcwd() os.chdir(self.package_dir) # We need to manually add the test package's path to the stsci # package's __path__ since it's already been imported. if 'stsci' in sys.modules: # Clean the existing __path__ up reload(sys.modules['stsci']) sys.modules['stsci'].__path__.insert( 0, os.path.join(self.package_dir, 'stsci')) def teardown(self): os.chdir(self.oldcwd) # Remove stsci.testpackage from sys.modules so that it can be freshly # re-imported by the next test for k in list(sys.modules): if k == 'stsci.testpackage' or k.startswith('stsci.testpackage.'): del sys.modules[k] rmtree(self.temp_dir) def run_setup(self, *args): return self._run_cmd(sys.executable, ('setup.py',) + args) def run_svn(self, *args): return self._run_cmd('svn', args) def _run_cmd(self, cmd, args): """ Runs a command, with the given argument list, in the root of the test working copy--returns the stdout and stderr streams and the exit code from the subprocess. """ os.chdir(self.package_dir) p = subprocess.Popen([cmd] + list(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE) streams = tuple(s.decode('latin1').strip() for s in p.communicate()) return (streams) + (p.returncode,) stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/0000755001134200020070000000000012256142707024411 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/data_files/0000755001134200020070000000000012256142707026504 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/data_files/c.rst0000644001134200020070000000000012256142676027453 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/data_files/b.txt0000644001134200020070000000000012256142676027461 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/data_files/a.txt0000644001134200020070000000000012256142676027460 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/setup.py0000755001134200020070000000066312256142676026140 0ustar embrayscience00000000000000#!/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>=0.2.5', 'stsci.distutils>=0.3.dev'], namespace_packages=['stsci'], packages=['stsci'], dependency_links=['http://stsdas.stsci.edu/download/packages'], d2to1=True, use_2to3=True, zip_safe=False, ) stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/distribute_setup.py0000644001134200020070000003661512256142676030401 0ustar embrayscience00000000000000#!python """Bootstrap distribute 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 distribute_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 sys import time import fnmatch import tempfile import tarfile from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None try: import subprocess def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 except ImportError: # will be used for python 2.3 def _python_cmd(*args): args = (sys.executable,) + args # quoting arguments if windows if sys.platform == 'win32': def quote(arg): if ' ' in arg: return '"%s"' % arg return arg args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 DEFAULT_VERSION = "0.6.19" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" SETUPTOOLS_PKG_INFO = """\ Metadata-Version: 1.0 Name: setuptools Version: %s Summary: xxxx Home-page: xxx Author: xxx Author-email: xxx License: xxx Description: xxx """ % SETUPTOOLS_FAKED_VERSION def _install(tarball): # 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 Distribute') if not _python_cmd('setup.py', 'install'): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') finally: os.chdir(old_wd) 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 Distribute egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) # 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, 'distribute-%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) import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15, no_fake=True): # 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: try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): if not no_fake: _fake_setuptools() raise ImportError except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("distribute>="+version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of distribute (>=%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 distribute'." "\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) finally: if not no_fake: _create_fake_setuptools_pkg_info(to_dir) def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename `version` should be a valid distribute 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. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen tgz_name = "distribute-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: log.warn("Downloading %s", url) 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(saveto, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def _no_sandbox(function): def __no_sandbox(*args, **kw): try: from setuptools.sandbox import DirectorySandbox if not hasattr(DirectorySandbox, '_old'): def violation(*args): pass DirectorySandbox._old = DirectorySandbox._violation DirectorySandbox._violation = violation patched = True else: patched = False except ImportError: patched = False try: return function(*args, **kw) finally: if patched: DirectorySandbox._violation = DirectorySandbox._old del DirectorySandbox._old return __no_sandbox def _patch_file(path, content): """Will backup the file then patch it""" existing_content = open(path).read() if existing_content == content: # already patched log.warn('Already patched.') return False log.warn('Patching...') _rename_path(path) f = open(path, 'w') try: f.write(content) finally: f.close() return True _patch_file = _no_sandbox(_patch_file) def _same_content(path, content): return open(path).read() == content def _rename_path(path): new_name = path + '.OLD.%s' % time.time() log.warn('Renaming %s into %s', path, new_name) os.rename(path, new_name) return new_name def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) return False found = False for file in os.listdir(placeholder): if fnmatch.fnmatch(file, 'setuptools*.egg-info'): found = True break if not found: log.warn('Could not locate setuptools*.egg-info') return log.warn('Removing elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) else: patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) if not patched: log.warn('%s already patched.', pkg_info) return False # now let's move the files out of the way for element in ('setuptools', 'pkg_resources.py', 'site.py'): element = os.path.join(placeholder, element) if os.path.exists(element): _rename_path(element) else: log.warn('Could not find the %s element of the ' 'Setuptools distribution', element) return True _remove_flat_installation = _no_sandbox(_remove_flat_installation) def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') return pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) setuptools_file = 'setuptools-%s-py%s.egg-info' % \ (SETUPTOOLS_FAKED_VERSION, pyver) pkg_info = os.path.join(placeholder, setuptools_file) if os.path.exists(pkg_info): log.warn('%s already exists', pkg_info) return log.warn('Creating %s', pkg_info) f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() pth_file = os.path.join(placeholder, 'setuptools.pth') log.warn('Creating %s', pth_file) f = open(pth_file, 'w') try: f.write(os.path.join(os.curdir, setuptools_file)) finally: f.close() _create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info) def _patch_egg_dir(path): # let's check if it's already patched pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') if os.path.exists(pkg_info): if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): log.warn('%s already patched.', pkg_info) return False _rename_path(path) os.mkdir(path) os.mkdir(os.path.join(path, 'EGG-INFO')) pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() return True _patch_egg_dir = _no_sandbox(_patch_egg_dir) def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() def _under_prefix(location): if 'install' not in sys.argv: return True args = sys.argv[sys.argv.index('install')+1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): top_dir = arg.split('root=')[-1] return location.startswith(top_dir) elif arg == option: if len(args) > index: top_dir = args[index+1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) return True def _fake_setuptools(): log.warn('Scanning installed packages') try: import pkg_resources except ImportError: # we're cool log.warn('Setuptools or Distribute does not seem to be installed.') return ws = pkg_resources.working_set try: setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools', replacement=False)) except TypeError: # old distribute API setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools')) if setuptools_dist is None: log.warn('No setuptools distribution found') return # detecting if it was already faked setuptools_location = setuptools_dist.location log.warn('Setuptools installation detected at %s', setuptools_location) # if --root or --preix was provided, and if # setuptools is not located in them, we don't patch it if not _under_prefix(setuptools_location): log.warn('Not patching, --root or --prefix is installing Distribute' ' in another location') return # let's see if its an egg if not setuptools_location.endswith('.egg'): log.warn('Non-egg installation') res = _remove_flat_installation(setuptools_location) if not res: return else: log.warn('Egg installation') pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') if (os.path.exists(pkg_info) and _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): log.warn('Already patched.') return log.warn('Patching...') # let's create a fake egg replacing setuptools one res = _patch_egg_dir(setuptools_location) if not res: return log.warn('Patched done.') _relaunch() def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) 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 main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" tarball = download_setuptools() _install(tarball) if __name__ == '__main__': main(sys.argv[1:]) stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/MANIFEST.in0000644001134200020070000000002512256142676026151 0ustar embrayscience00000000000000include data_files/* stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/0000755001134200020070000000000012256142707025536 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/__init__.py0000644001134200020070000000073412256142676027660 0ustar embrayscience00000000000000try: # As long as we're using setuptools/distribute, we need to do this the # setuptools way or else pkg_resources will throw up unncessary and # annoying warnings (even though the namespace mechanism will still # otherwise work without it). # Get rid of this as soon as setuptools/distribute is dead. __import__('pkg_resources').declare_namespace(__name__) except ImportError: pass __path__ = __import__('pkgutil').extend_path(__path__, __name__) stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/testpackage/0000755001134200020070000000000012256142707030031 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/testpackage/package_data/0000755001134200020070000000000012256142707032415 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/testpackage/package_data/2.txt0000644001134200020070000000000012256142676033312 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/testpackage/package_data/1.txt0000644001134200020070000000000012256142676033311 0ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/stsci/testpackage/__init__.py0000644001134200020070000000037312256142676032152 0ustar embrayscience00000000000000try: from .version import (__version__, __svn_revision__, __svn_full_info__, __setup_datetime__) except ImportError: __version__ = '' __svn_revision__ = '' __svn_full_info__ = '' __setup_datetime__ = None stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/LICENSE.txt0000644001134200020070000000267012256142676026246 0ustar embrayscience00000000000000Copyright (C) 2005 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. stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/src/0000755001134200020070000000000012256142707025200 5ustar embrayscience00000000000000stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/src/testext.c0000644001134200020070000000063212256142676027052 0ustar embrayscience00000000000000#include static PyMethodDef TestextMethods[] = { {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION >=3 static struct PyModuleDef testextmodule = { PyModuleDef_HEAD_INIT, "testext", -1, TestextMethods }; PyObject* PyInit_testext(void) { return PyModule_Create(&testextmodule); } #else PyMODINIT_FUNC inittestext(void) { Py_InitModule("testext", TestextMethods); } #endif stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/README.txt0000644001134200020070000001502412256142676026116 0ustar embrayscience00000000000000Introduction ============ This package contains utilities used to package some of STScI's Python projects; specifically those projects that comprise stsci_python_ and Astrolib_. It currently consists mostly of some setup_hook scripts meant for use with `distutils2/packaging`_ and/or d2to1_, and a customized easy_install command meant for use with distribute_. This package is not meant for general consumption, though it might be worth looking at for examples of how to do certain things with your own packages, but YMMV. Features ======== Hook Scripts ------------ Currently the main features of this package are a couple of setup_hook scripts. In distutils2, a setup_hook is a script that runs at the beginning of any pysetup command, and can modify the package configuration read from setup.cfg. There are also pre- and post-command hooks that only run before/after a specific setup command (eg. build_ext, install) is run. stsci.distutils.hooks.use_packages_root ''''''''''''''''''''''''''''''''''''''' If using the ``packages_root`` option under the ``[files]`` section of setup.cfg, this hook will add that path to ``sys.path`` so that modules in your package can be imported and used in setup. This can be used even if ``packages_root`` is not specified--in this case it adds ``''`` to ``sys.path``. stsci.distutils.hooks.version_setup_hook '''''''''''''''''''''''''''''''''''''''' Creates a Python module called version.py which currently contains four variables: * ``__version__`` (the release version) * ``__svn_revision__`` (the SVN revision info as returned by the ``svnversion`` command) * ``__svn_full_info__`` (as returned by the ``svn info`` command) * ``__setup_datetime__`` (the date and time that setup.py was last run). These variables can be imported in the package's `__init__.py` for degugging purposes. The version.py module will *only* be created in a package that imports from the version module in its `__init__.py`. It should be noted that this is generally preferable to writing these variables directly into `__init__.py`, since this provides more control and is less likely to unexpectedly break things in `__init__.py`. stsci.distutils.hooks.version_pre_command_hook '''''''''''''''''''''''''''''''''''''''''''''' Identical to version_setup_hook, but designed to be used as a pre-command hook. stsci.distutils.hooks.version_post_command_hook ''''''''''''''''''''''''''''''''''''''''''''''' The complement to version_pre_command_hook. This will delete any version.py files created during a build in order to prevent them from cluttering an SVN working copy (note, however, that version.py is *not* deleted from the build/ directory, so a copy of it is still preserved). It will also not be deleted if the current directory is not an SVN working copy. For example, if source code extracted from a source tarball it will be preserved. stsci.distutils.hooks.tag_svn_revision '''''''''''''''''''''''''''''''''''''' A setup_hook to add the SVN revision of the current working copy path to the package version string, but only if the version ends in .dev. For example, ``mypackage-1.0.dev`` becomes ``mypackage-1.0.dev1234``. This is in accordance with the version string format standardized by PEP 386. This should be used as a replacement for the ``tag_svn_revision`` option to the egg_info command. This hook is more compatible with packaging/distutils2, which does not include any VCS support. This hook is also more flexible in that it turns the revision number on/off depending on the presence of ``.dev`` in the version string, so that it's not automatically added to the version in final releases. This hook does require the ``svnversion`` command to be available in order to work. It does not examine the working copy metadata directly. stsci.distutils.hooks.numpy_extension_hook '''''''''''''''''''''''''''''''''''''''''' This is a pre-command hook for the build_ext command. To use it, add a ``[build_ext]`` section to your setup.cfg, and add to it:: pre-hook.numpy-extension-hook = stsci.distutils.hooks.numpy_extension_hook This hook must be used to build extension modules that use Numpy. The primary side-effect of this hook is to add the correct numpy include directories to `include_dirs`. To use it, add 'numpy' to the 'include-dirs' option of each extension module that requires numpy to build. The value 'numpy' will be replaced with the actual path to the numpy includes. stsci.distutils.hooks.is_display_option ''''''''''''''''''''''''''''''''''''''' This is not actually a hook, but is a useful utility function that can be used in writing other hooks. Basically, it returns ``True`` if setup.py was run with a "display option" such as --version or --help. This can be used to prevent your hook from running in such cases. stsci.distutils.hooks.glob_data_files ''''''''''''''''''''''''''''''''''''' A pre-command hook for the install_data command. Allows filename wildcards as understood by ``glob.glob()`` to be used in the data_files option. This hook must be used in order to have this functionality since it does not normally exist in distutils. This hook also ensures that data files are installed relative to the package path. data_files shouldn't normally be installed this way, but the functionality is required for a few special cases. Commands -------- build_optional_ext '''''''''''''''''' This serves as an optional replacement for the default built_ext command, which compiles C extension modules. Its purpose is to allow extension modules to be *optional*, so that if their build fails the rest of the package is still allowed to be built and installed. This can be used when an extension module is not definitely required to use the package. To use this custom command, add:: commands = stsci.distutils.command.build_optional_ext.build_optional_ext under the ``[global]`` section of your package's setup.cfg. Then, to mark an individual extension module as optional, under the setup.cfg section for that extension add:: optional = True Optionally, you may also add a custom failure message by adding:: fail_message = The foobar extension module failed to compile. This could be because you lack such and such headers. This package will still work, but such and such features will be disabled. .. _stsci_python: http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python .. _Astrolib: http://www.scipy.org/AstroLib/ .. _distutils2/packaging: http://distutils2.notmyidea.org/ .. _d2to1: http://pypi.python.org/pypi/d2to1 .. _distribute: http://pypi.python.org/pypi/distribute stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/setup.cfg0000644001134200020070000000247412256142676026246 0ustar embrayscience00000000000000[metadata] name = stsci.testpackage version = 0.1.dev author = Erik M. Bray author-email = embray@stsci.edu home-page = http://www.stsci.edu/resources/software_hardware/stsci_python summary = Test package for testing stsci.distutils description-file = README.txt CHANGES.txt requires-python = >=2.5 requires-dist = setuptools d2to1 (>=0.2.5) classifier = Development Status :: 3 - Alpha Intended Audience :: Developers License :: OSI Approved :: BSD License Programming Language :: Python Topic :: Scientific/Engineering Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = stsci stsci.testpackage package_data = stsci.testpackage = package_data/*.txt data_files = stsci/testpackage/data_files = data_files/*.txt [extension=stsci.testpackage.testext] sources = src/testext.c include_dirs = numpy optional = True [global] setup-hooks = stsci.distutils.hooks.tag_svn_revision stsci.distutils.hooks.version_setup_hook commands = stsci.distutils.command.build_optional_ext.build_optional_ext [build_ext] pre-hook.numpy-extension-hook = stsci.distutils.hooks.numpy_extension_hook [install_data] pre-hook.glob-data-files = stsci.distutils.hooks.glob_data_files stsci.distutils-0.3.7/stsci/distutils/tests/testpackage/CHANGES.txt0000644001134200020070000000766412256142676026244 0ustar embrayscience00000000000000Changelog =========== 0.3 (unreleased) ------------------ - The ``glob_data_files`` hook became a pre-command hook for the install_data command instead of being a setup-hook. This is to support the additional functionality of requiring data_files with relative destination paths to be install relative to the package's install path (i.e. site-packages). - Dropped support for and deprecated the easier_install custom command. Although it should still work, it probably won't be used anymore for stsci_python packages. - Added support for the ``build_optional_ext`` command, which replaces/extends the default ``build_ext`` command. See the README for more details. - Added the ``tag_svn_revision`` setup_hook as a replacement for the setuptools-specific tag_svn_revision option to the egg_info command. This new hook is easier to use than the old tag_svn_revision option: It's automatically enabled by the presence of ``.dev`` in the version string, and disabled otherwise. - The ``svn_info_pre_hook`` and ``svn_info_post_hook`` have been replaced with ``version_pre_command_hook`` and ``version_post_command_hook`` respectively. However, a new ``version_setup_hook``, which has the same purpose, has been added. It is generally easier to use and will give more consistent results in that it will run every time setup.py is run, regardless of which command is used. ``stsci.distutils`` itself uses this hook--see the `setup.cfg` file and `stsci/distutils/__init__.py` for example usage. - Instead of creating an `svninfo.py` module, the new ``version_`` hooks create a file called `version.py`. In addition to the SVN info that was included in `svninfo.py`, it includes a ``__version__`` variable to be used by the package's `__init__.py`. This allows there to be a hard-coded ``__version__`` variable included in the source code, rather than using pkg_resources to get the version. - In `version.py`, the variables previously named ``__svn_version__`` and ``__full_svn_info__`` are now named ``__svn_revision__`` and ``__svn_full_info__``. - Fixed a bug when using stsci.distutils in the installation of other packages in the ``stsci.*`` namespace package. If stsci.distutils was not already installed, and was downloaded automatically by distribute through the setup_requires option, then ``stsci.distutils`` would fail to import. This is because the way the namespace package (nspkg) mechanism currently works, all packages belonging to the nspkg *must* be on the import path at initial import time. So when installing stsci.tools, for example, if ``stsci.tools`` is imported from within the source code at install time, but before ``stsci.distutils`` is downloaded and added to the path, the ``stsci`` package is already imported and can't be extended to include the path of ``stsci.distutils`` after the fact. The easiest way of dealing with this, it seems, is to delete ``stsci`` from ``sys.modules``, which forces it to be reimported, now the its ``__path__`` extended to include ``stsci.distutil``'s path. 0.2.2 (2011-11-09) ------------------ - Fixed check for the issue205 bug on actual setuptools installs; before it only worked on distribute. setuptools has the issue205 bug prior to version 0.6c10. - Improved the fix for the issue205 bug, especially on setuptools. setuptools, prior to 0.6c10, did not back of sys.modules either before sandboxing, which causes serious problems. In fact, it's so bad that it's not enough to add a sys.modules backup to the current sandbox: It's in fact necessary to monkeypatch setuptools.sandbox.run_setup so that any subsequent calls to it also back up sys.modules. 0.2.1 (2011-09-02) ------------------ - Fixed the dependencies so that setuptools is requirement but 'distribute' specifically. Previously installation could fail if users had plain setuptools installed and not distribute 0.2 (2011-08-23) ------------------ - Initial public release stsci.distutils-0.3.7/stsci/__init__.py0000644001134200020070000000073412256142676021052 0ustar embrayscience00000000000000try: # As long as we're using setuptools/distribute, we need to do this the # setuptools way or else pkg_resources will throw up unncessary and # annoying warnings (even though the namespace mechanism will still # otherwise work without it). # Get rid of this as soon as setuptools/distribute is dead. __import__('pkg_resources').declare_namespace(__name__) except ImportError: pass __path__ = __import__('pkgutil').extend_path(__path__, __name__) stsci.distutils-0.3.7/LICENSE.txt0000644001134200020070000000267012256142676017440 0ustar embrayscience00000000000000Copyright (C) 2005 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. stsci.distutils-0.3.7/README.txt0000644001134200020070000001503412256142676017311 0ustar embrayscience00000000000000Introduction ============ This package contains utilities used to package some of STScI's Python projects; specifically those projects that comprise stsci_python_ and Astrolib_. It currently consists mostly of some setup_hook scripts meant for use with `distutils2/packaging`_ and/or d2to1_, and a customized easy_install command meant for use with distribute_. This package is not meant for general consumption, though it might be worth looking at for examples of how to do certain things with your own packages, but YMMV. Features ======== Hook Scripts ------------ Currently the main features of this package are a couple of setup_hook scripts. In distutils2, a setup_hook is a script that runs at the beginning of any pysetup command, and can modify the package configuration read from setup.cfg. There are also pre- and post-command hooks that only run before/after a specific setup command (eg. build_ext, install) is run. stsci.distutils.hooks.use_packages_root ''''''''''''''''''''''''''''''''''''''' If using the ``packages_root`` option under the ``[files]`` section of setup.cfg, this hook will add that path to ``sys.path`` so that modules in your package can be imported and used in setup. This can be used even if ``packages_root`` is not specified--in this case it adds ``''`` to ``sys.path``. stsci.distutils.hooks.version_setup_hook '''''''''''''''''''''''''''''''''''''''' Creates a Python module called version.py which currently contains four variables: * ``__version__`` (the release version) * ``__svn_revision__`` (the SVN revision info as returned by the ``svnversion`` command) * ``__svn_full_info__`` (as returned by the ``svn info`` command) * ``__setup_datetime__`` (the date and time that setup.py was last run). These variables can be imported in the package's ``__init__.py`` for degugging purposes. The version.py module will *only* be created in a package that imports from the version module in its ``__init__.py``. It should be noted that this is generally preferable to writing these variables directly into ``__init__.py``, since this provides more control and is less likely to unexpectedly break things in ``__init__.py``. stsci.distutils.hooks.version_pre_command_hook '''''''''''''''''''''''''''''''''''''''''''''' Identical to version_setup_hook, but designed to be used as a pre-command hook. stsci.distutils.hooks.version_post_command_hook ''''''''''''''''''''''''''''''''''''''''''''''' The complement to version_pre_command_hook. This will delete any version.py files created during a build in order to prevent them from cluttering an SVN working copy (note, however, that version.py is *not* deleted from the build/ directory, so a copy of it is still preserved). It will also not be deleted if the current directory is not an SVN working copy. For example, if source code extracted from a source tarball it will be preserved. stsci.distutils.hooks.tag_svn_revision '''''''''''''''''''''''''''''''''''''' A setup_hook to add the SVN revision of the current working copy path to the package version string, but only if the version ends in .dev. For example, ``mypackage-1.0.dev`` becomes ``mypackage-1.0.dev1234``. This is in accordance with the version string format standardized by PEP 386. This should be used as a replacement for the ``tag_svn_revision`` option to the egg_info command. This hook is more compatible with packaging/distutils2, which does not include any VCS support. This hook is also more flexible in that it turns the revision number on/off depending on the presence of ``.dev`` in the version string, so that it's not automatically added to the version in final releases. This hook does require the ``svnversion`` command to be available in order to work. It does not examine the working copy metadata directly. stsci.distutils.hooks.numpy_extension_hook '''''''''''''''''''''''''''''''''''''''''' This is a pre-command hook for the build_ext command. To use it, add a ``[build_ext]`` section to your setup.cfg, and add to it:: pre-hook.numpy-extension-hook = stsci.distutils.hooks.numpy_extension_hook This hook must be used to build extension modules that use Numpy. The primary side-effect of this hook is to add the correct numpy include directories to `include_dirs`. To use it, add 'numpy' to the 'include-dirs' option of each extension module that requires numpy to build. The value 'numpy' will be replaced with the actual path to the numpy includes. stsci.distutils.hooks.is_display_option ''''''''''''''''''''''''''''''''''''''' This is not actually a hook, but is a useful utility function that can be used in writing other hooks. Basically, it returns ``True`` if setup.py was run with a "display option" such as --version or --help. This can be used to prevent your hook from running in such cases. stsci.distutils.hooks.glob_data_files ''''''''''''''''''''''''''''''''''''' A pre-command hook for the install_data command. Allows filename wildcards as understood by ``glob.glob()`` to be used in the data_files option. This hook must be used in order to have this functionality since it does not normally exist in distutils. This hook also ensures that data files are installed relative to the package path. data_files shouldn't normally be installed this way, but the functionality is required for a few special cases. Commands -------- build_optional_ext '''''''''''''''''' This serves as an optional replacement for the default built_ext command, which compiles C extension modules. Its purpose is to allow extension modules to be *optional*, so that if their build fails the rest of the package is still allowed to be built and installed. This can be used when an extension module is not definitely required to use the package. To use this custom command, add:: commands = stsci.distutils.command.build_optional_ext.build_optional_ext under the ``[global]`` section of your package's setup.cfg. Then, to mark an individual extension module as optional, under the setup.cfg section for that extension add:: optional = True Optionally, you may also add a custom failure message by adding:: fail_message = The foobar extension module failed to compile. This could be because you lack such and such headers. This package will still work, but such and such features will be disabled. .. _stsci_python: http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python .. _Astrolib: http://www.scipy.org/AstroLib/ .. _distutils2/packaging: http://distutils2.notmyidea.org/ .. _d2to1: http://pypi.python.org/pypi/d2to1 .. _distribute: http://pypi.python.org/pypi/distribute stsci.distutils-0.3.7/tox.ini0000644001134200020070000000033412256142676017123 0ustar embrayscience00000000000000[tox] envlist = py25,py26,py27,py32,py33 [testenv] deps = nose numpy setuptools-subversion commands = python setup.py clean -a python setup.py build python setup.py nosetests sitepackages = True stsci.distutils-0.3.7/setup.cfg0000644001134200020070000000252012256142707017423 0ustar embrayscience00000000000000[metadata] name = stsci.distutils version = 0.3.7 author = Erik M. Bray author-email = embray@stsci.edu home-page = http://www.stsci.edu/resources/software_hardware/stsci_python summary = distutils/packaging-related utilities used by some of STScI's packages description-file = README.txt CHANGES.txt requires-python = >=2.5 requires-dist = setuptools d2to1 (>=0.2.5) classifier = Development Status :: 3 - Alpha Intended Audience :: Developers License :: OSI Approved :: BSD License Programming Language :: Python Topic :: Scientific/Engineering Topic :: Software Development :: Build Tools Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging [files] packages = stsci stsci.distutils stsci.distutils.command stsci.distutils.tests [global] setup-hooks = stsci.distutils.hooks.tag_svn_revision stsci.distutils.hooks.version_setup_hook [backwards_compat] use-2to3 = True zip-safe = False [entry_points] zest.releaser.releaser.before = fix_sdist_format = stsci.distutils.release:fix_sdist_format zest.releaser.releaser.after = add_to_stsci_package_index = stsci.distutils.release:add_to_stsci_package_index zest.releaser.postreleaser.before = fix_dev_version_template = stsci.distutils.release:fix_dev_version_template [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 stsci.distutils-0.3.7/CHANGES.txt0000644001134200020070000001457712256142676017437 0ustar embrayscience00000000000000Changelog =========== 0.3.7 (2013-12-23) ------------------ - Avoid using ``Popen.stdout`` directly in the version.py SVN revision auto-update script to avoid possible ResourceWarnings on Python >= 3.2. See https://github.com/spacetelescope/PyFITS/issues/45 0.3.6 (2013-11-21) ------------------ - Fixed a syntax error in Python 3 that was introduced in 0.3.5. This could occur very early in the setup such that it bailed before even 2to3 could run on the rest of the package. 0.3.5 (2013-11-18) ------------------ - Fixed an obscure issue that could occur when trying to install with easy_install on Python 2 systems that have lib2to3 installed but have never used it. 0.3.4 (2013-07-31) ------------------ - Updated the check for ``__loader__`` added in v0.3.3 to only perform that check on Python >= 3.3, since the issue doesn't apply to older Python versions. 0.3.3 (2013-07-25) ------------------ - Updated the import-time SVN revision update mechanism in the ``version.py`` module generated by the ``version_setup_hook`` to avoid running when not in a dev version of the package. This saves time on importing released packages when installed on users' systems. - Added a workaround to a bug on Python 3.3 that could cause stsci.distutils to crash during installation. 0.3.2 (2013-03-27) ------------------ - Fixed a bug in the version hook that could occur if the svnversion command fails. - Updated the template for the version.py module generated by the version hook so that ``from .version import *`` will work for applications. - Added a ``__vdate__`` variable in version.py which may contain a release date string by specifying a ``vdate`` option in the ``[metadata]`` section of setup.cfg. - Added a ``stsci_distutils_version`` variable in version.py containing the version of stsci.distutils used to generate the file--useful primarily for debugging purposes. - Version 0.3.1 added a new zest.releaser hooks to ensure that source distributes are created as tar.gz files instead of zip files--this was left out of the changelog for 0.3.1. - The tar.gz zest.releaser hook is updated in 0.3.2 to only run on stsci packages. 0.3.1 (2012-06-28) ------------------ - Fixed a bug where console output from svn-related programs was assumed to be ascii, leading to possible crashes on non-English systems. 0.3 (2012-02-20) ---------------- - The ``glob_data_files`` hook became a pre-command hook for the install_data command instead of being a setup-hook. This is to support the additional functionality of requiring data_files with relative destination paths to be install relative to the package's install path (i.e. site-packages). - Dropped support for and deprecated the easier_install custom command. Although it should still work, it probably won't be used anymore for stsci_python packages. - Added support for the ``build_optional_ext`` command, which replaces/extends the default ``build_ext`` command. See the README for more details. - Added the ``tag_svn_revision`` setup_hook as a replacement for the setuptools-specific tag_svn_revision option to the egg_info command. This new hook is easier to use than the old tag_svn_revision option: It's automatically enabled by the presence of ``.dev`` in the version string, and disabled otherwise. - The ``svn_info_pre_hook`` and ``svn_info_post_hook`` have been replaced with ``version_pre_command_hook`` and ``version_post_command_hook`` respectively. However, a new ``version_setup_hook``, which has the same purpose, has been added. It is generally easier to use and will give more consistent results in that it will run every time setup.py is run, regardless of which command is used. ``stsci.distutils`` itself uses this hook--see the `setup.cfg` file and `stsci/distutils/__init__.py` for example usage. - Instead of creating an `svninfo.py` module, the new ``version_`` hooks create a file called `version.py`. In addition to the SVN info that was included in `svninfo.py`, it includes a ``__version__`` variable to be used by the package's `__init__.py`. This allows there to be a hard-coded ``__version__`` variable included in the source code, rather than using pkg_resources to get the version. - In `version.py`, the variables previously named ``__svn_version__`` and ``__full_svn_info__`` are now named ``__svn_revision__`` and ``__svn_full_info__``. - Fixed a bug when using stsci.distutils in the installation of other packages in the ``stsci.*`` namespace package. If stsci.distutils was not already installed, and was downloaded automatically by distribute through the setup_requires option, then ``stsci.distutils`` would fail to import. This is because the way the namespace package (nspkg) mechanism currently works, all packages belonging to the nspkg *must* be on the import path at initial import time. So when installing stsci.tools, for example, if ``stsci.tools`` is imported from within the source code at install time, but before ``stsci.distutils`` is downloaded and added to the path, the ``stsci`` package is already imported and can't be extended to include the path of ``stsci.distutils`` after the fact. The easiest way of dealing with this, it seems, is to delete ``stsci`` from ``sys.modules``, which forces it to be reimported, now the its ``__path__`` extended to include ``stsci.distutil``'s path. - Added zest.releaser hooks for tweaking the development version string template, and for uploading new releases to STScI's local package index. 0.2.2 (2011-11-09) ------------------ - Fixed check for the issue205 bug on actual setuptools installs; before it only worked on distribute. setuptools has the issue205 bug prior to version 0.6c10. - Improved the fix for the issue205 bug, especially on setuptools. setuptools, prior to 0.6c10, did not back of sys.modules either before sandboxing, which causes serious problems. In fact, it's so bad that it's not enough to add a sys.modules backup to the current sandbox: It's in fact necessary to monkeypatch setuptools.sandbox.run_setup so that any subsequent calls to it also back up sys.modules. 0.2.1 (2011-09-02) ------------------ - Fixed the dependencies so that setuptools is requirement but 'distribute' specifically. Previously installation could fail if users had plain setuptools installed and not distribute 0.2 (2011-08-23) ------------------ - Initial public release