diff --git a/.travis.yml b/.travis.yml index 61064188..a6c8cd7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,10 +49,10 @@ matrix: - python: 3.6 env: SETUP_CMD='test' ASTROPY_VERSION=development - # Try older numpy versions - - python: 3.4 + # Try minimum supported versions + - python: 3.5 env: SETUP_CMD='test' NUMPY_VERSION=1.12 - - python: 3.4 + - python: 3.5 env: SETUP_CMD='test' NUMPY_VERSION=1.11 # Try released POPPY @@ -99,7 +99,6 @@ script: after_success: # coveralls.io integration - # - if [[ $SETUP_CMD == 'test --coverage' && TRAVIS_REPO_SLUG == "mperrin/webbpsf" ]]; then coveralls --rcfile='webbpsf/tests/coveragerc'; fi - if [[ $SETUP_CMD == 'test --coverage' ]]; then coveralls --rcfile='webbpsf/tests/coveragerc'; fi notifications: diff --git a/setup.py b/setup.py index b319ef5d..8f0a718d 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python +# Based on astropy affiliated package template's setup.py # Licensed under a 3-clause BSD style license - see LICENSE.rst -# --based on setup.py from astropy-- from __future__ import print_function import glob @@ -9,6 +9,15 @@ import imp import ast +__packagename__ = 'webbpsf' +__minimum_python_version__ = "3.5" + +# 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 __minimum_python_version__.split('.'))): + sys.stderr.write("ERROR: {} requires Python {} or later\n".format(__packagename__, __minimum_python_version__)) + sys.exit(1) + try: import numpy except ImportError: @@ -109,16 +118,15 @@ version=VERSION, description=DESCRIPTION, scripts=scripts, + python_requires='>=' + __minimum_python_version__, install_requires=[ 'numpy>=1.10.0', 'matplotlib>=1.5.0', 'scipy>=0.16.0', 'poppy>=0.7.0', - 'astropy>=1.2.0', + 'astropy>=1.3.0', 'jwxml>=0.3.0', 'pysiaf>=0.1.8', 'six', - 'pytest' # unlisted requirement for pysiaf - see https://github.com/spacetelescope/pysiaf/issues/16 - # Remove this requirement once that issue is addressed. ], provides=[PACKAGENAME], author=AUTHOR, diff --git a/webbpsf/__init__.py b/webbpsf/__init__.py index 89303f7c..1848fd00 100644 --- a/webbpsf/__init__.py +++ b/webbpsf/__init__.py @@ -1,5 +1,4 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -from __future__ import division, print_function, absolute_import, unicode_literals """ WebbPSF: Simulated Point Spread Functions for the James Webb Space Telescope ---------------------------------------------------------------------------- @@ -9,15 +8,32 @@ four science instruments plus the fine guidance sensor, including both direct imaging and coronagraphic modes. -Developed by Marshall Perrin and contributors at STScI, 2010-2015. +Developed by Marshall Perrin and collaborators at STScI, 2010-2018. + +Documentation can be found online at https://webbpsf.readthedocs.io/ """ # Affiliated packages may add whatever they like to this file, but # should keep this content at the top. # ---------------------------------------------------------------------------- +# make use of astropy affiliate framework to set __version__, __githash__, and +# add the test() helper function from ._astropy_init import * # ---------------------------------------------------------------------------- +# Enforce Python version check during package import. +# This is the same check as the one at the top of setup.py +import sys + +__minimum_python_version__ = "3.5" + +class UnsupportedPythonError(Exception): + pass + +if sys.version_info < tuple((int(val) for val in __minimum_python_version__.split('.'))): + raise UnsupportedPythonError("webbpsf does not support Python < {}".format(__minimum_python_version__)) + + # This tuple gives the *minimum* version of the WebbPSF data package # required. If changes to the code and data mean WebbPSF won't work # properly with an old data package, increment this version number. @@ -27,11 +43,11 @@ import astropy from astropy import config as _config + class Conf(_config.ConfigNamespace): """ Configuration parameters for `webbpsf`. """ -# Should probably be science state in astropy>=0.4 schema: default_oversampling = _config.ConfigItem(4, 'Default '+ 'oversampling factor: number of times more finely sampled than '+ diff --git a/webbpsf/constants.py b/webbpsf/constants.py index 7ae0f90a..9be74041 100644 --- a/webbpsf/constants.py +++ b/webbpsf/constants.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals # This file contains constants and data that do not fit in the data # package for one reason or another. It could be that they are in a # data structure that doesn't serialize well or they're too small to diff --git a/webbpsf/distortion.py b/webbpsf/distortion.py index 6785a700..f5b75a26 100644 --- a/webbpsf/distortion.py +++ b/webbpsf/distortion.py @@ -1,12 +1,9 @@ -from __future__ import division, print_function, absolute_import, unicode_literals - import copy import astropy.convolution import astropy.io.fits as fits import numpy as np import pysiaf -import six from scipy.interpolate import griddata from scipy.ndimage.interpolation import rotate @@ -48,7 +45,7 @@ def apply_distortion(hdulist_or_filename=None, fill_value=0): """ # Read in input PSF - if isinstance(hdulist_or_filename, six.string_types): + if isinstance(hdulist_or_filename, str): hdu_list = fits.open(hdulist_or_filename) elif isinstance(hdulist_or_filename, fits.HDUList): hdu_list = hdulist_or_filename @@ -166,7 +163,7 @@ def apply_rotation(hdulist_or_filename=None, rotate_value=None, crop=True): """ # Read in input PSF - if isinstance(hdulist_or_filename, six.string_types): + if isinstance(hdulist_or_filename, str): hdu_list = fits.open(hdulist_or_filename) elif isinstance(hdulist_or_filename, fits.HDUList): hdu_list = hdulist_or_filename @@ -270,7 +267,7 @@ def apply_miri_scattering(hdulist_or_filename=None, kernel_amp=None): """ # Read in input PSF - if isinstance(hdulist_or_filename, six.string_types): + if isinstance(hdulist_or_filename, str): hdu_list = fits.open(hdulist_or_filename) elif isinstance(hdulist_or_filename, fits.HDUList): hdu_list = hdulist_or_filename diff --git a/webbpsf/jupyter_gui.py b/webbpsf/jupyter_gui.py index 4fa5d5f7..ffa985a6 100644 --- a/webbpsf/jupyter_gui.py +++ b/webbpsf/jupyter_gui.py @@ -1,8 +1,6 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import logging import matplotlib import astropy.io.fits as fits -import six import poppy from . import webbpsf_core @@ -235,7 +233,7 @@ def show_notebook_interface_jwst(instrument): from matplotlib import pyplot as plt - if isinstance(instrument, six.string_types): + if isinstance(instrument, str): instrument = Instrument(instrument) try: diff --git a/webbpsf/obssim.py b/webbpsf/obssim.py index 5b711c06..505c11c6 100755 --- a/webbpsf/obssim.py +++ b/webbpsf/obssim.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -from __future__ import division, print_function, absolute_import, unicode_literals """ obssim.py diff --git a/webbpsf/opds.py b/webbpsf/opds.py index d34a07ce..aacd87ef 100644 --- a/webbpsf/opds.py +++ b/webbpsf/opds.py @@ -27,8 +27,6 @@ # ############################################################################### -from __future__ import division - import os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/optics.py b/webbpsf/optics.py index 8855081b..19c4d6f4 100644 --- a/webbpsf/optics.py +++ b/webbpsf/optics.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import os import poppy import poppy.utils diff --git a/webbpsf/tests/__init__.py b/webbpsf/tests/__init__.py index 5e6606e1..ef2abc96 100644 --- a/webbpsf/tests/__init__.py +++ b/webbpsf/tests/__init__.py @@ -1,5 +1,4 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -from __future__ import division, print_function, absolute_import, unicode_literals """ This package contains automated software tests for WebbPSF. """ diff --git a/webbpsf/tests/test_errorhandling.py b/webbpsf/tests/test_errorhandling.py index bc9aeeea..bfeb1a38 100644 --- a/webbpsf/tests/test_errorhandling.py +++ b/webbpsf/tests/test_errorhandling.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals # This file contains code for testing various error handlers and user interface edge cases, # as opposed to testing the main body of functionality of the code. diff --git a/webbpsf/tests/test_fgs.py b/webbpsf/tests/test_fgs.py index c3ffbeab..10d8f914 100644 --- a/webbpsf/tests/test_fgs.py +++ b/webbpsf/tests/test_fgs.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_miri.py b/webbpsf/tests/test_miri.py index 8d7f5a76..16684df9 100644 --- a/webbpsf/tests/test_miri.py +++ b/webbpsf/tests/test_miri.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_nircam.py b/webbpsf/tests/test_nircam.py index dcaec7b5..ec6a3a62 100644 --- a/webbpsf/tests/test_nircam.py +++ b/webbpsf/tests/test_nircam.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_niriss.py b/webbpsf/tests/test_niriss.py index 5ab63dac..661b4e79 100644 --- a/webbpsf/tests/test_niriss.py +++ b/webbpsf/tests/test_niriss.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_nirspec.py b/webbpsf/tests/test_nirspec.py index c899ba71..f52dbf8d 100644 --- a/webbpsf/tests/test_nirspec.py +++ b/webbpsf/tests/test_nirspec.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_utils.py b/webbpsf/tests/test_utils.py index 4b48a263..78af15c8 100644 --- a/webbpsf/tests/test_utils.py +++ b/webbpsf/tests/test_utils.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_webbpsf.py b/webbpsf/tests/test_webbpsf.py index b884269b..b178d531 100644 --- a/webbpsf/tests/test_webbpsf.py +++ b/webbpsf/tests/test_webbpsf.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import sys, os import numpy as np import matplotlib.pyplot as plt diff --git a/webbpsf/tests/test_wfirst.py b/webbpsf/tests/test_wfirst.py index 7c9526c7..979a4e92 100644 --- a/webbpsf/tests/test_wfirst.py +++ b/webbpsf/tests/test_wfirst.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import pytest from webbpsf import wfirst diff --git a/webbpsf/tests/validate_webbpsf.py b/webbpsf/tests/validate_webbpsf.py index 05ba72aa..c041977e 100644 --- a/webbpsf/tests/validate_webbpsf.py +++ b/webbpsf/tests/validate_webbpsf.py @@ -1,4 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import os from astropy.io import fits import numpy as N diff --git a/webbpsf/tkgui.py b/webbpsf/tkgui.py index 9cb7613d..f6972c74 100755 --- a/webbpsf/tkgui.py +++ b/webbpsf/tkgui.py @@ -1,22 +1,21 @@ #!/usr/bin/env python -from __future__ import division, print_function, absolute_import, unicode_literals import os import numpy as np import matplotlib.pyplot as plt import matplotlib import astropy.io.fits as fits -from six.moves import tkinter as tk -from six.moves import tkinter_tkfiledialog as tkFileDialog -from six.moves import tkinter_messagebox as tkMessageBox +import tkinter as tk +import tkinter.filedialog as tkFileDialog +import tkinter.messagebox as tkMessageBox import logging import logging _log = logging.getLogger('webbpsf') try: - from six.moves import tkinter_ttk as ttk + import tkinter.ttk as ttk except ImportError: - raise RuntimeError("Python 2.7.0 (or newer) with ttk widget support is required") + raise RuntimeError("Python with ttk widget support is required") diff --git a/webbpsf/utils.py b/webbpsf/utils.py index 8635f65f..441d60de 100644 --- a/webbpsf/utils.py +++ b/webbpsf/utils.py @@ -1,6 +1,4 @@ -from __future__ import division, print_function, absolute_import, unicode_literals import os, sys -import six import astropy.io.fits as fits import numpy as np import matplotlib.pyplot as plt @@ -439,7 +437,7 @@ def measure_strehl(HDUlist_or_filename=None, ext=0, slice=0, center=None, displa from .webbpsf_core import Instrument from poppy import display_psf - if isinstance(HDUlist_or_filename, six.string_types): + if isinstance(HDUlist_or_filename, str): HDUlist = fits.open(HDUlist_or_filename) elif isinstance(HDUlist_or_filename, fits.HDUList): HDUlist = HDUlist_or_filename diff --git a/webbpsf/webbpsf_core.py b/webbpsf/webbpsf_core.py index 2146ab85..ec15d0bd 100644 --- a/webbpsf/webbpsf_core.py +++ b/webbpsf/webbpsf_core.py @@ -1,5 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals - """ ============ WebbPSF Core @@ -24,7 +22,6 @@ import os import glob import time -import six import copy from collections import namedtuple, OrderedDict import numpy as np @@ -403,10 +400,10 @@ def _get_optical_system(self, fft_oversample=2, detector_oversample=None, optsys.source_offset_theta = options['source_offset_theta'] # ---- set pupil OPD - if isinstance(self.pupilopd, six.string_types): # simple filename + if isinstance(self.pupilopd, str): # simple filename opd_map = self.pupilopd if os.path.exists(self.pupilopd) else \ os.path.join(self._datapath, "OPD", self.pupilopd) - elif hasattr(self.pupilopd, '__getitem__') and isinstance(self.pupilopd[0], six.string_types): + elif hasattr(self.pupilopd, '__getitem__') and isinstance(self.pupilopd[0], str): # tuple with filename and slice opd_map = (self.pupilopd[0] if os.path.exists(self.pupilopd[0]) else os.path.join(self._datapath, "OPD", self.pupilopd[0]), @@ -427,7 +424,7 @@ def _get_optical_system(self, fft_oversample=2, detector_oversample=None, pupil_optic = optsys.add_pupil(self.pupil) else: # wrap in an optic and supply to POPPY - if isinstance(self.pupil, six.string_types): # simple filename + if isinstance(self.pupil, str): # simple filename if os.path.exists(self.pupil): pupil_transmission = self.pupil else: diff --git a/webbpsf/wfirst.py b/webbpsf/wfirst.py index 6bc8e67c..3dbc2bdd 100644 --- a/webbpsf/wfirst.py +++ b/webbpsf/wfirst.py @@ -1,5 +1,3 @@ -from __future__ import division, print_function, absolute_import, unicode_literals - """ ============================== WFIRST Instruments (pre-alpha) diff --git a/webbpsf/wxgui.py b/webbpsf/wxgui.py index 9f5f9e7c..e4fa4011 100755 --- a/webbpsf/wxgui.py +++ b/webbpsf/wxgui.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -from __future__ import division, print_function, absolute_import, unicode_literals import astropy.io.fits as fits import matplotlib