diff --git a/.travis.yml b/.travis.yml index 5104ebe3..c5f38982 100644 --- a/.travis.yml +++ b/.travis.yml @@ -97,9 +97,7 @@ matrix: # time. - os: linux - env: PYTHON_VERSION=2.7 NUMPY_VERSION=1.9 - - os: linux - env: PYTHON_VERSION=3.4 NUMPY_VERSION=1.10 + env: PYTHON_VERSION=3.5 NUMPY_VERSION=1.10 - os: linux env: PYTHON_VERSION=3.5 NUMPY_VERSION=1.11 - os: linux diff --git a/MANIFEST.in b/MANIFEST.in index c87d8971..0b677077 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,6 +4,7 @@ include README.rst include ez_setup.py include ah_bootstrap.py include setup.cfg +include pydl/tests/coveragerc recursive-include pydl *.pyx *.c *.pxd recursive-include docs * @@ -28,7 +29,7 @@ recursive-include astropy_helpers/licenses * include astropy_helpers/ez_setup.py include astropy_helpers/ah_bootstrap.py -recursive-include astropy_helpers/astropy_helpers *.py *.pyx *.c *.h +recursive-include astropy_helpers/astropy_helpers *.py *.pyx *.c *.h *.rst recursive-include astropy_helpers/astropy_helpers.egg-info * # include the sphinx stuff with "*" because there are css/html/rst/etc. recursive-include astropy_helpers/astropy_helpers/sphinx * diff --git a/ah_bootstrap.py b/ah_bootstrap.py index 786b8b14..e55254ee 100644 --- a/ah_bootstrap.py +++ b/ah_bootstrap.py @@ -19,9 +19,14 @@ contains an option called ``auto_use`` with a value of ``True``, it will automatically call the main function of this module called `use_astropy_helpers` (see that function's docstring for full details). -Otherwise no further action is taken (however, -``ah_bootstrap.use_astropy_helpers`` may be called manually from within the -setup.py script). +Otherwise no further action is taken and by default the system-installed version +of astropy-helpers will be used (however, ``ah_bootstrap.use_astropy_helpers`` +may be called manually from within the setup.py script). + +This behavior can also be controlled using the ``--auto-use`` and +``--no-auto-use`` command-line flags. For clarity, an alias for +``--no-auto-use`` is ``--use-system-astropy-helpers``, and we recommend using +the latter if needed. Additional options in the ``[ah_boostrap]`` section of setup.cfg have the same names as the arguments to `use_astropy_helpers`, and can be used to configure @@ -137,7 +142,6 @@ from setuptools import Distribution from setuptools.package_index import PackageIndex -from setuptools.sandbox import run_setup from distutils import log from distutils.debug import DEBUG @@ -147,6 +151,11 @@ DIST_NAME = 'astropy-helpers' PACKAGE_NAME = 'astropy_helpers' +if PY3: + UPPER_VERSION_EXCLUSIVE = None +else: + UPPER_VERSION_EXCLUSIVE = '3' + # Defaults for other options DOWNLOAD_IF_NEEDED = True INDEX_URL = 'https://pypi.python.org/simple' @@ -287,6 +296,18 @@ def parse_command_line(cls, argv=None): config['offline'] = True argv.remove('--offline') + if '--auto-use' in argv: + config['auto_use'] = True + argv.remove('--auto-use') + + if '--no-auto-use' in argv: + config['auto_use'] = False + argv.remove('--no-auto-use') + + if '--use-system-astropy-helpers' in argv: + config['auto_use'] = False + argv.remove('--use-system-astropy-helpers') + return config def run(self): @@ -464,9 +485,10 @@ def _directory_import(self): # setup.py exists we can generate it setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): - with _silence(): - run_setup(os.path.join(path, 'setup.py'), - ['egg_info']) + # We use subprocess instead of run_setup from setuptools to + # avoid segmentation faults - see the following for more details: + # https://github.com/cython/cython/issues/2104 + sp.check_output([sys.executable, 'setup.py', 'egg_info'], cwd=path) for dist in pkg_resources.find_distributions(path, True): # There should be only one... @@ -501,16 +523,32 @@ def get_option_dict(self, command_name): if version: req = '{0}=={1}'.format(DIST_NAME, version) else: - req = DIST_NAME + if UPPER_VERSION_EXCLUSIVE is None: + req = DIST_NAME + else: + req = '{0}<{1}'.format(DIST_NAME, UPPER_VERSION_EXCLUSIVE) attrs = {'setup_requires': [req]} + # NOTE: we need to parse the config file (e.g. setup.cfg) to make sure + # it honours the options set in the [easy_install] section, and we need + # to explicitly fetch the requirement eggs as setup_requires does not + # get honored in recent versions of setuptools: + # https://github.com/pypa/setuptools/issues/1273 + try: - if DEBUG: - _Distribution(attrs=attrs) - else: - with _silence(): - _Distribution(attrs=attrs) + + context = _verbose if DEBUG else _silence + with context(): + dist = _Distribution(attrs=attrs) + try: + dist.parse_config_files(ignore_option_errors=True) + dist.fetch_build_eggs(req) + except TypeError: + # On older versions of setuptools, ignore_option_errors + # doesn't exist, and the above two lines are not needed + # so we can just continue + pass # If the setup_requires succeeded it will have added the new dist to # the main working_set @@ -846,6 +884,10 @@ def flush(self): pass +@contextlib.contextmanager +def _verbose(): + yield + @contextlib.contextmanager def _silence(): """A context manager that silences sys.stdout and sys.stderr.""" diff --git a/astropy_helpers b/astropy_helpers index d23a53f4..5e30a46d 160000 --- a/astropy_helpers +++ b/astropy_helpers @@ -1 +1 @@ -Subproject commit d23a53f46dd1c3703e5eee63dca3f53bd18a4e8b +Subproject commit 5e30a46dd0146a241f5c7ca8de0cc0144455b2e1 diff --git a/docs/conf.py b/docs/conf.py index 7893e015..79fb3c48 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,7 +9,7 @@ # # All configuration values have a default. Some values are defined in # the global Astropy configuration which is loaded here before anything else. -# See astropy_helpers.sphinx.conf for which values are set there. +# See astropy.sphinx.conf for which values are set there. # 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 @@ -18,7 +18,7 @@ # IMPORTANT: the above commented section was generated by sphinx-quickstart, but # is *NOT* appropriate for astropy or Astropy affiliated packages. It is left # commented out with this explanation to make it clear why this should not be -# done. If the sys.path entry above is added, when the astropy_helpers.sphinx.conf +# done. If the sys.path entry above is added, when the astropy.sphinx.conf # import occurs, it will import the *source* version of astropy instead of the # version installed (if invoked as "make html" or directly with sphinx), or the # version in the build directory (if "python setup.py build_sphinx" is used). @@ -103,13 +103,6 @@ # global configuration are listed below, commented out. -# Please update these texts to match the name of your package. -html_theme_options = { - 'logotext1': '', # white, semi-bold - 'logotext2': 'PyDL', # orange, light - 'logotext3': ':docs' # white, light - } - # Add any paths that contain custom themes here, relative to this directory. # To use a different custom theme, add the directory containing the theme. #html_theme_path = [] @@ -119,6 +112,15 @@ # name of a builtin theme or the name of a custom theme in html_theme_path. #html_theme = None + +# Please update these texts to match the name of your package. +html_theme_options = { + 'logotext1': '', # white, semi-bold + 'logotext2': 'PyDL', # orange, light + 'logotext3': ':docs' # white, light + } + + # Custom sidebar templates, maps document names to template names. #html_sidebars = {} @@ -176,3 +178,29 @@ # -- Resolving issue number to links in changelog ----------------------------- github_issues_url = 'https://github.com/{0}/issues/'.format(setup_cfg['github_project']) + +# -- Turn on nitpicky mode for sphinx (to warn about references not found) ---- +# +# nitpicky = True +# nitpick_ignore = [] +# +# Some warnings are impossible to suppress, and you can list specific references +# that should be ignored in a nitpick-exceptions file which should be inside +# the docs/ directory. The format of the file should be: +# +# +# +# for example: +# +# py:class astropy.io.votable.tree.Element +# py:class astropy.io.votable.tree.SimpleElement +# py:class astropy.io.votable.tree.SimpleElementWithContent +# +# Uncomment the following lines to enable the exceptions: +# +# for line in open('nitpick-exceptions'): +# if line.strip() == "" or line.startswith("#"): +# continue +# dtype, target = line.split(None, 1) +# target = target.strip() +# nitpick_ignore.append((dtype, six.u(target))) diff --git a/docs/pydl/changes.rst b/docs/pydl/changes.rst index 300d6d59..f9922926 100644 --- a/docs/pydl/changes.rst +++ b/docs/pydl/changes.rst @@ -7,7 +7,7 @@ PyDL Changelog * Support the ``firstField`` bit in ObjIDs from DR7 and earlier (Issue `#37`_). * Change tests of Astropy development version from Python 2 to Python 3. -* Update to `astropy_helpers`_/v2.0.2. +* Update to `astropy_helpers`_/v2.0.6. .. _`#37`: https://github.com/weaverba137/pydl/issues/37. diff --git a/pydl/__init__.py b/pydl/__init__.py index c806d1df..49573eb6 100644 --- a/pydl/__init__.py +++ b/pydl/__init__.py @@ -13,14 +13,24 @@ .. _IDL: http://www.exelisvis.com/language/en-us/productsservices/idl.aspx """ -# Affiliated packages may add whatever they like to this file, but +# Packages may add whatever they like to this file, but # should keep this content at the top. # ---------------------------------------------------------------------------- from ._astropy_init import * # ---------------------------------------------------------------------------- -# For egg_info test builds to pass, put package imports here. +# Enforce Python version check during package import. +# This is the same check as the one at the top of setup.py +import sys + +class UnsupportedPythonError(Exception): + pass + +if sys.version_info < tuple((int(val) for val in "2.7".split('.'))): + raise UnsupportedPythonError("PyDL does not support Python < {}".format(2.7)) + if not _ASTROPY_SETUP_: + # For egg_info test builds to pass, put package imports here. from .file_lines import file_lines from .median import median from .pcomp import pcomp diff --git a/pydl/conftest.py b/pydl/conftest.py index 82e97ade..f7490bf8 100644 --- a/pydl/conftest.py +++ b/pydl/conftest.py @@ -1,16 +1,36 @@ -# this contains imports plugins that configure py.test for astropy tests. -# by importing them here in conftest.py they are discoverable by py.test -# no matter how it is invoked within the source tree. +# This file is used to configure the behavior of pytest when using the Astropy +# test infrastructure. -from astropy.tests.pytest_plugins import * +from astropy.version import version as astropy_version +if astropy_version < '3.0': + # With older versions of Astropy, we actually need to import the pytest + # plugins themselves in order to make them discoverable by pytest. + from astropy.tests.pytest_plugins import * +else: + # As of Astropy 3.0, the pytest plugins provided by Astropy are + # automatically made available when Astropy is installed. This means it's + # not necessary to import them here, but we still need to import global + # variables that are used for configuration. + from astropy.tests.plugins.display import PYTEST_HEADER_MODULES, TESTED_VERSIONS -# Uncomment the following line to treat all DeprecationWarnings as -# exceptions +from astropy.tests.helper import enable_deprecations_as_exceptions + +## Uncomment the following line to treat all DeprecationWarnings as +## exceptions. For Astropy v2.0 or later, there are 2 additional keywords, +## as follow (although default should work for most cases). +## To ignore some packages that produce deprecation warnings on import +## (in addition to 'compiler', 'scipy', 'pygments', 'ipykernel', and +## 'setuptools'), add: +## modules_to_ignore_on_import=['module_1', 'module_2'] +## To ignore some specific deprecation warning messages for Python version +## MAJOR.MINOR or later, add: +## warnings_to_ignore_by_pyver={(MAJOR, MINOR): ['Message to ignore']} # enable_deprecations_as_exceptions() -# Uncomment and customize the following lines to add/remove entries -# from the list of packages for which version numbers are displayed -# when running the tests +## Uncomment and customize the following lines to add/remove entries from +## the list of packages for which version numbers are displayed when running +## the tests. Making it pass for KeyError is essential in some cases when +## the package uses other astropy affiliated packages. try: PYTEST_HEADER_MODULES['Astropy'] = 'astropy' PYTEST_HEADER_MODULES['PyDL'] = 'pydl' @@ -22,16 +42,16 @@ del PYTEST_HEADER_MODULES['Pandas'] except KeyError: pass -except NameError: # needed to support Astropy < 1.0 +except (NameError, KeyError): # NameError is needed to support Astropy < 1.0 pass -# Uncomment the following lines to display the version number of the -# package rather than the version number of Astropy in the top line when -# running the tests. +## Uncomment the following lines to display the version number of the +## package rather than the version number of Astropy in the top line when +## running the tests. import os -# This is to figure out the affiliated package version, rather than -# using Astropy's +## This is to figure out the package version, rather than +## using Astropy's try: from .version import version except ImportError: diff --git a/setup.cfg b/setup.cfg index 072ef911..b40f3d49 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,7 +16,7 @@ show-response = 1 minversion = 3.0 norecursedirs = build docs/_build doctest_plus = enabled -addopts: -p no:warnings +addopts = -p no:warnings [ah_bootstrap] auto_use = True @@ -48,7 +48,7 @@ license = BSD url = http://github.com/weaverba137/pydl edit_on_github = False github_project = weaverba137/pydl -install_requires = astropy scipy matplotlib +install_requires = astropy, scipy, matplotlib # version should be PEP440 compatible (http://www.python.org/dev/peps/pep-0440) version = 0.6.1.dev diff --git a/setup.py b/setup.py index 2b7f7cd1..c0a2e635 100755 --- a/setup.py +++ b/setup.py @@ -5,6 +5,12 @@ import os import sys +# Enforce Python version check - this is the same check as in __init__.py but +# this one has to happen before importing ah_bootstrap. +if sys.version_info < tuple((int(val) for val in "2.7".split('.'))): + sys.stderr.write("ERROR: packagename requires Python {} or later\n".format(2.7)) + sys.exit(1) + import ah_bootstrap from setuptools import setup @@ -31,8 +37,8 @@ metadata = dict(conf.items('metadata')) PACKAGENAME = metadata.get('package_name', 'packagename') -DESCRIPTION = metadata.get('description', 'Astropy affiliated package') -AUTHOR = metadata.get('author', '') +DESCRIPTION = metadata.get('description', 'Astropy Package Template') +AUTHOR = metadata.get('author', 'Astropy Developers') AUTHOR_EMAIL = metadata.get('author_email', '') LICENSE = metadata.get('license', 'unknown') URL = metadata.get('url', 'http://astropy.org') @@ -42,7 +48,7 @@ # (2) load LONG_DESCRIPTION.rst, # (3) load README.rst, # (4) package docstring -readme_glob = 'NOSUCHFILE*' +readme_glob = 'README*' _cfg_long_description = metadata.get('long_description', '') if _cfg_long_description: LONG_DESCRIPTION = _cfg_long_description @@ -66,7 +72,7 @@ builtins._ASTROPY_PACKAGE_NAME_ = PACKAGENAME # VERSION should be PEP440 compatible (http://www.python.org/dev/peps/pep-0440) -VERSION = metadata.get('version', '0.0.dev') +VERSION = metadata.get('version', '0.0.dev0') # Indicates if this version is a release version RELEASE = 'dev' not in VERSION @@ -100,10 +106,11 @@ # Define entry points for command-line scripts entry_points = {'console_scripts': []} -entry_point_list = conf.items('entry_points') -for entry_point in entry_point_list: - entry_points['console_scripts'].append('{0} = {1}'.format(entry_point[0], - entry_point[1])) +if conf.has_section('entry_points'): + entry_point_list = conf.items('entry_points') + for entry_point in entry_point_list: + entry_points['console_scripts'].append('{0} = {1}'.format( + entry_point[0], entry_point[1])) # Include all .c files, recursively, including those generated by # Cython, since we can not do this in MANIFEST.in with a "dynamic" @@ -125,7 +132,7 @@ version=VERSION, description=DESCRIPTION, scripts=scripts, - install_requires=metadata.get('install_requires', 'astropy').strip().split(), + install_requires=[s.strip() for s in metadata.get('install_requires', 'astropy').split(',')], author=AUTHOR, author_email=AUTHOR_EMAIL, license=LICENSE, @@ -145,5 +152,6 @@ 'Topic :: Scientific/Engineering :: Physics', 'Topic :: Scientific/Engineering :: Astronomy', ], + python_requires='>={}'.format("2.7"), **package_info )