From 78b33ce51a03bea9f9b591821bc2907cc73bd332 Mon Sep 17 00:00:00 2001 From: Michele Costa Date: Sun, 1 Mar 2020 17:09:29 +0000 Subject: [PATCH 1/6] Fix data initalisation Signed-off-by: Michele Costa --- saba/main.py | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/saba/main.py b/saba/main.py index ee59d68..6487131 100644 --- a/saba/main.py +++ b/saba/main.py @@ -2,7 +2,7 @@ from collections import OrderedDict from sherpa.fit import Fit from sherpa.data import Data1D, Data1DInt, Data2D, Data2DInt, DataSimulFit -from sherpa.data import BaseData +from sherpa.data import Data from sherpa.models import UserModel, Parameter, SimulFitModel from sherpa.stats import Chi2, Chi2ConstVar, Chi2DataVar, Chi2Gehrels from sherpa.stats import Chi2ModVar, Chi2XspecVar, LeastSq @@ -759,12 +759,7 @@ def __init__(self, name, xlo, xhi, y, bkg, staterror=None, bkg_scale=1, src_scal self.subtracted = False self._backgrounds = [BkgDataset(bkg, bkg_scale)] - BaseData.__init__(self) - - self.xlo = xlo - self.xhi = xhi - self.y = y - self.staterror = staterror + Data.__init__(self, (xlo, xhi), y, staterror) class Data1DBkg(Data1D): @@ -814,11 +809,8 @@ def __init__(self, name, x, y, bkg, staterror=None, bkg_scale=1, src_scale=1): self.subtracted = False self._backgrounds = [BkgDataset(bkg, bkg_scale)] - BaseData.__init__(self) + Data.__init__(self, name, (x, ), y, staterror) - self.x = x - self.y = y - self.staterror = staterror class Data2DIntBkg(Data2DInt): @@ -875,14 +867,7 @@ def __init__(self, name, xlo, xhi, ylo, yhi, z, bkg, staterror=None, bkg_scale=1 self.subtracted = False self._backgrounds = [BkgDataset(bkg, bkg_scale)] - BaseData.__init__(self) - - self.xlo = xlo - self.xhi = xhi - self.ylo = ylo - self.yhi = yhi - self.z = z - self.staterror = staterror + Data.__init__(self, (xlo, xhi, ylo, yhi), z, staterror) class Data2DBkg(Data2D): @@ -935,13 +920,8 @@ def __init__(self, name, x, y, z, bkg, staterror=None, bkg_scale=1, src_scale=1) self.subtracted = False self._backgrounds = [BkgDataset(bkg, bkg_scale)] - BaseData.__init__(self) - - self.x = x - self.y = y - self.z = z - self.staterror = staterror - + Data.__init__(self, name, (x, y), z, staterror) + class BkgDataset(object): """ From 1d544264e5adde8e9eeda5251d1bdd3765ec3549 Mon Sep 17 00:00:00 2001 From: hamogu Date: Mon, 2 Mar 2020 11:10:35 -0500 Subject: [PATCH 2/6] Remove astropy-helpers submodule --- .gitmodules | 3 - ah_bootstrap.py | 1010 ----------------------------------------------- astropy_helpers | 1 - 3 files changed, 1014 deletions(-) delete mode 100644 .gitmodules delete mode 100644 ah_bootstrap.py delete mode 160000 astropy_helpers diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6a20fa6..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "astropy_helpers"] - path = astropy_helpers - url = https://github.com/astropy/astropy-helpers.git diff --git a/ah_bootstrap.py b/ah_bootstrap.py deleted file mode 100644 index 512a05a..0000000 --- a/ah_bootstrap.py +++ /dev/null @@ -1,1010 +0,0 @@ -""" -This bootstrap module contains code for ensuring that the astropy_helpers -package will be importable by the time the setup.py script runs. It also -includes some workarounds to ensure that a recent-enough version of setuptools -is being used for the installation. - -This module should be the first thing imported in the setup.py of distributions -that make use of the utilities in astropy_helpers. If the distribution ships -with its own copy of astropy_helpers, this module will first attempt to import -from the shipped copy. However, it will also check PyPI to see if there are -any bug-fix releases on top of the current version that may be useful to get -past platform-specific bugs that have been fixed. When running setup.py, use -the ``--offline`` command-line option to disable the auto-upgrade checks. - -When this module is imported or otherwise executed it automatically calls a -main function that attempts to read the project's setup.cfg file, which it -checks for a configuration section called ``[ah_bootstrap]`` the presences of -that section, and options therein, determine the next step taken: If it -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 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 -the bootstrap script when ``auto_use = True``. - -See https://github.com/astropy/astropy-helpers for more details, and for the -latest version of this module. -""" - -import contextlib -import errno -import io -import locale -import os -import re -import subprocess as sp -import sys - -from distutils import log -from distutils.debug import DEBUG - -from configparser import ConfigParser, RawConfigParser - -import pkg_resources - -from setuptools import Distribution -from setuptools.package_index import PackageIndex - -# This is the minimum Python version required for astropy-helpers -__minimum_python_version__ = (3, 5) - -# TODO: Maybe enable checking for a specific version of astropy_helpers? -DIST_NAME = 'astropy-helpers' -PACKAGE_NAME = 'astropy_helpers' -UPPER_VERSION_EXCLUSIVE = None - -# Defaults for other options -DOWNLOAD_IF_NEEDED = True -INDEX_URL = 'https://pypi.python.org/simple' -USE_GIT = True -OFFLINE = False -AUTO_UPGRADE = True - -# A list of all the configuration options and their required types -CFG_OPTIONS = [ - ('auto_use', bool), ('path', str), ('download_if_needed', bool), - ('index_url', str), ('use_git', bool), ('offline', bool), - ('auto_upgrade', bool) -] - -# Start off by parsing the setup.cfg file - -SETUP_CFG = ConfigParser() - -if os.path.exists('setup.cfg'): - - try: - SETUP_CFG.read('setup.cfg') - except Exception as e: - if DEBUG: - raise - - log.error( - "Error reading setup.cfg: {0!r}\n{1} will not be " - "automatically bootstrapped and package installation may fail." - "\n{2}".format(e, PACKAGE_NAME, _err_help_msg)) - -# We used package_name in the package template for a while instead of name -if SETUP_CFG.has_option('metadata', 'name'): - parent_package = SETUP_CFG.get('metadata', 'name') -elif SETUP_CFG.has_option('metadata', 'package_name'): - parent_package = SETUP_CFG.get('metadata', 'package_name') -else: - parent_package = None - -if SETUP_CFG.has_option('options', 'python_requires'): - - python_requires = SETUP_CFG.get('options', 'python_requires') - - # The python_requires key has a syntax that can be parsed by SpecifierSet - # in the packaging package. However, we don't want to have to depend on that - # package, so instead we can use setuptools (which bundles packaging). We - # have to add 'python' to parse it with Requirement. - - from pkg_resources import Requirement - req = Requirement.parse('python' + python_requires) - - # We want the Python version as a string, which we can get from the platform module - import platform - # strip off trailing '+' incase this is a dev install of python - python_version = platform.python_version().strip('+') - # allow pre-releases to count as 'new enough' - if not req.specifier.contains(python_version, True): - if parent_package is None: - message = "ERROR: Python {} is required by this package\n".format(req.specifier) - else: - message = "ERROR: Python {} is required by {}\n".format(req.specifier, parent_package) - sys.stderr.write(message) - sys.exit(1) - -if sys.version_info < __minimum_python_version__: - - if parent_package is None: - message = "ERROR: Python {} or later is required by astropy-helpers\n".format( - __minimum_python_version__) - else: - message = "ERROR: Python {} or later is required by astropy-helpers for {}\n".format( - __minimum_python_version__, parent_package) - - sys.stderr.write(message) - sys.exit(1) - -_str_types = (str, bytes) - - -# What follows are several import statements meant to deal with install-time -# issues with either missing or misbehaving pacakges (including making sure -# setuptools itself is installed): - -# Check that setuptools 30.3 or later is present -from distutils.version import LooseVersion - -try: - import setuptools - assert LooseVersion(setuptools.__version__) >= LooseVersion('30.3') -except (ImportError, AssertionError): - sys.stderr.write("ERROR: setuptools 30.3 or later is required by astropy-helpers\n") - sys.exit(1) - -# typing as a dependency for 1.6.1+ Sphinx causes issues when imported after -# initializing submodule with ah_boostrap.py -# See discussion and references in -# https://github.com/astropy/astropy-helpers/issues/302 - -try: - import typing # noqa -except ImportError: - pass - - -# Note: The following import is required as a workaround to -# https://github.com/astropy/astropy-helpers/issues/89; if we don't import this -# module now, it will get cleaned up after `run_setup` is called, but that will -# later cause the TemporaryDirectory class defined in it to stop working when -# used later on by setuptools -try: - import setuptools.py31compat # noqa -except ImportError: - pass - - -# matplotlib can cause problems if it is imported from within a call of -# run_setup(), because in some circumstances it will try to write to the user's -# home directory, resulting in a SandboxViolation. See -# https://github.com/matplotlib/matplotlib/pull/4165 -# Making sure matplotlib, if it is available, is imported early in the setup -# process can mitigate this (note importing matplotlib.pyplot has the same -# issue) -try: - import matplotlib - matplotlib.use('Agg') - import matplotlib.pyplot -except: - # Ignore if this fails for *any* reason* - pass - - -# End compatibility imports... - - -class _Bootstrapper(object): - """ - Bootstrapper implementation. See ``use_astropy_helpers`` for parameter - documentation. - """ - - def __init__(self, path=None, index_url=None, use_git=None, offline=None, - download_if_needed=None, auto_upgrade=None): - - if path is None: - path = PACKAGE_NAME - - if not (isinstance(path, _str_types) or path is False): - raise TypeError('path must be a string or False') - - if not isinstance(path, str): - fs_encoding = sys.getfilesystemencoding() - path = path.decode(fs_encoding) # path to unicode - - self.path = path - - # Set other option attributes, using defaults where necessary - self.index_url = index_url if index_url is not None else INDEX_URL - self.offline = offline if offline is not None else OFFLINE - - # If offline=True, override download and auto-upgrade - if self.offline: - download_if_needed = False - auto_upgrade = False - - self.download = (download_if_needed - if download_if_needed is not None - else DOWNLOAD_IF_NEEDED) - self.auto_upgrade = (auto_upgrade - if auto_upgrade is not None else AUTO_UPGRADE) - - # If this is a release then the .git directory will not exist so we - # should not use git. - git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git')) - if use_git is None and not git_dir_exists: - use_git = False - - self.use_git = use_git if use_git is not None else USE_GIT - # Declared as False by default--later we check if astropy-helpers can be - # upgraded from PyPI, but only if not using a source distribution (as in - # the case of import from a git submodule) - self.is_submodule = False - - @classmethod - def main(cls, argv=None): - if argv is None: - argv = sys.argv - - config = cls.parse_config() - config.update(cls.parse_command_line(argv)) - - auto_use = config.pop('auto_use', False) - bootstrapper = cls(**config) - - if auto_use: - # Run the bootstrapper, otherwise the setup.py is using the old - # use_astropy_helpers() interface, in which case it will run the - # bootstrapper manually after reconfiguring it. - bootstrapper.run() - - return bootstrapper - - @classmethod - def parse_config(cls): - - if not SETUP_CFG.has_section('ah_bootstrap'): - return {} - - config = {} - - for option, type_ in CFG_OPTIONS: - if not SETUP_CFG.has_option('ah_bootstrap', option): - continue - - if type_ is bool: - value = SETUP_CFG.getboolean('ah_bootstrap', option) - else: - value = SETUP_CFG.get('ah_bootstrap', option) - - config[option] = value - - return config - - @classmethod - def parse_command_line(cls, argv=None): - if argv is None: - argv = sys.argv - - config = {} - - # For now we just pop recognized ah_bootstrap options out of the - # arg list. This is imperfect; in the unlikely case that a setup.py - # custom command or even custom Distribution class defines an argument - # of the same name then we will break that. However there's a catch22 - # here that we can't just do full argument parsing right here, because - # we don't yet know *how* to parse all possible command-line arguments. - if '--no-git' in argv: - config['use_git'] = False - argv.remove('--no-git') - - if '--offline' in argv: - 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): - strategies = ['local_directory', 'local_file', 'index'] - dist = None - - # First, remove any previously imported versions of astropy_helpers; - # this is necessary for nested installs where one package's installer - # is installing another package via setuptools.sandbox.run_setup, as in - # the case of setup_requires - for key in list(sys.modules): - try: - if key == PACKAGE_NAME or key.startswith(PACKAGE_NAME + '.'): - del sys.modules[key] - except AttributeError: - # Sometimes mysterious non-string things can turn up in - # sys.modules - continue - - # Check to see if the path is a submodule - self.is_submodule = self._check_submodule() - - for strategy in strategies: - method = getattr(self, 'get_{0}_dist'.format(strategy)) - dist = method() - if dist is not None: - break - else: - raise _AHBootstrapSystemExit( - "No source found for the {0!r} package; {0} must be " - "available and importable as a prerequisite to building " - "or installing this package.".format(PACKAGE_NAME)) - - # This is a bit hacky, but if astropy_helpers was loaded from a - # directory/submodule its Distribution object gets a "precedence" of - # "DEVELOP_DIST". However, in other cases it gets a precedence of - # "EGG_DIST". However, when activing the distribution it will only be - # placed early on sys.path if it is treated as an EGG_DIST, so always - # do that - dist = dist.clone(precedence=pkg_resources.EGG_DIST) - - # Otherwise we found a version of astropy-helpers, so we're done - # Just active the found distribution on sys.path--if we did a - # download this usually happens automatically but it doesn't hurt to - # do it again - # Note: Adding the dist to the global working set also activates it - # (makes it importable on sys.path) by default. - - try: - pkg_resources.working_set.add(dist, replace=True) - except TypeError: - # Some (much) older versions of setuptools do not have the - # replace=True option here. These versions are old enough that all - # bets may be off anyways, but it's easy enough to work around just - # in case... - if dist.key in pkg_resources.working_set.by_key: - del pkg_resources.working_set.by_key[dist.key] - pkg_resources.working_set.add(dist) - - @property - def config(self): - """ - A `dict` containing the options this `_Bootstrapper` was configured - with. - """ - - return dict((optname, getattr(self, optname)) - for optname, _ in CFG_OPTIONS if hasattr(self, optname)) - - def get_local_directory_dist(self): - """ - Handle importing a vendored package from a subdirectory of the source - distribution. - """ - - if not os.path.isdir(self.path): - return - - log.info('Attempting to import astropy_helpers from {0} {1!r}'.format( - 'submodule' if self.is_submodule else 'directory', - self.path)) - - dist = self._directory_import() - - if dist is None: - log.warn( - 'The requested path {0!r} for importing {1} does not ' - 'exist, or does not contain a copy of the {1} ' - 'package.'.format(self.path, PACKAGE_NAME)) - elif self.auto_upgrade and not self.is_submodule: - # A version of astropy-helpers was found on the available path, but - # check to see if a bugfix release is available on PyPI - upgrade = self._do_upgrade(dist) - if upgrade is not None: - dist = upgrade - - return dist - - def get_local_file_dist(self): - """ - Handle importing from a source archive; this also uses setup_requires - but points easy_install directly to the source archive. - """ - - if not os.path.isfile(self.path): - return - - log.info('Attempting to unpack and import astropy_helpers from ' - '{0!r}'.format(self.path)) - - try: - dist = self._do_download(find_links=[self.path]) - except Exception as e: - if DEBUG: - raise - - log.warn( - 'Failed to import {0} from the specified archive {1!r}: ' - '{2}'.format(PACKAGE_NAME, self.path, str(e))) - dist = None - - if dist is not None and self.auto_upgrade: - # A version of astropy-helpers was found on the available path, but - # check to see if a bugfix release is available on PyPI - upgrade = self._do_upgrade(dist) - if upgrade is not None: - dist = upgrade - - return dist - - def get_index_dist(self): - if not self.download: - log.warn('Downloading {0!r} disabled.'.format(DIST_NAME)) - return None - - log.warn( - "Downloading {0!r}; run setup.py with the --offline option to " - "force offline installation.".format(DIST_NAME)) - - try: - dist = self._do_download() - except Exception as e: - if DEBUG: - raise - log.warn( - 'Failed to download and/or install {0!r} from {1!r}:\n' - '{2}'.format(DIST_NAME, self.index_url, str(e))) - dist = None - - # No need to run auto-upgrade here since we've already presumably - # gotten the most up-to-date version from the package index - return dist - - def _directory_import(self): - """ - Import astropy_helpers from the given path, which will be added to - sys.path. - - Must return True if the import succeeded, and False otherwise. - """ - - # Return True on success, False on failure but download is allowed, and - # otherwise raise SystemExit - path = os.path.abspath(self.path) - - # Use an empty WorkingSet rather than the man - # pkg_resources.working_set, since on older versions of setuptools this - # will invoke a VersionConflict when trying to install an upgrade - ws = pkg_resources.WorkingSet([]) - ws.add_entry(path) - dist = ws.by_key.get(DIST_NAME) - - if dist is None: - # We didn't find an egg-info/dist-info in the given path, but if a - # setup.py exists we can generate it - setup_py = os.path.join(path, 'setup.py') - if os.path.isfile(setup_py): - # 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... - return dist - - return dist - - def _do_download(self, version='', find_links=None): - if find_links: - allow_hosts = '' - index_url = None - else: - allow_hosts = None - index_url = self.index_url - - # Annoyingly, setuptools will not handle other arguments to - # Distribution (such as options) before handling setup_requires, so it - # is not straightforward to programmatically augment the arguments which - # are passed to easy_install - class _Distribution(Distribution): - def get_option_dict(self, command_name): - opts = Distribution.get_option_dict(self, command_name) - if command_name == 'easy_install': - if find_links is not None: - opts['find_links'] = ('setup script', find_links) - if index_url is not None: - opts['index_url'] = ('setup script', index_url) - if allow_hosts is not None: - opts['allow_hosts'] = ('setup script', allow_hosts) - return opts - - if version: - req = '{0}=={1}'.format(DIST_NAME, version) - else: - 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: - - 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 - return pkg_resources.working_set.by_key.get(DIST_NAME) - except Exception as e: - if DEBUG: - raise - - msg = 'Error retrieving {0} from {1}:\n{2}' - if find_links: - source = find_links[0] - elif index_url != INDEX_URL: - source = index_url - else: - source = 'PyPI' - - raise Exception(msg.format(DIST_NAME, source, repr(e))) - - def _do_upgrade(self, dist): - # Build up a requirement for a higher bugfix release but a lower minor - # release (so API compatibility is guaranteed) - next_version = _next_version(dist.parsed_version) - - req = pkg_resources.Requirement.parse( - '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_version)) - - package_index = PackageIndex(index_url=self.index_url) - - upgrade = package_index.obtain(req) - - if upgrade is not None: - return self._do_download(version=upgrade.version) - - def _check_submodule(self): - """ - Check if the given path is a git submodule. - - See the docstrings for ``_check_submodule_using_git`` and - ``_check_submodule_no_git`` for further details. - """ - - if (self.path is None or - (os.path.exists(self.path) and not os.path.isdir(self.path))): - return False - - if self.use_git: - return self._check_submodule_using_git() - else: - return self._check_submodule_no_git() - - def _check_submodule_using_git(self): - """ - Check if the given path is a git submodule. If so, attempt to initialize - and/or update the submodule if needed. - - This function makes calls to the ``git`` command in subprocesses. The - ``_check_submodule_no_git`` option uses pure Python to check if the given - path looks like a git submodule, but it cannot perform updates. - """ - - cmd = ['git', 'submodule', 'status', '--', self.path] - - try: - log.info('Running `{0}`; use the --no-git option to disable git ' - 'commands'.format(' '.join(cmd))) - returncode, stdout, stderr = run_cmd(cmd) - except _CommandNotFound: - # The git command simply wasn't found; this is most likely the - # case on user systems that don't have git and are simply - # trying to install the package from PyPI or a source - # distribution. Silently ignore this case and simply don't try - # to use submodules - return False - - stderr = stderr.strip() - - if returncode != 0 and stderr: - # Unfortunately the return code alone cannot be relied on, as - # earlier versions of git returned 0 even if the requested submodule - # does not exist - - # This is a warning that occurs in perl (from running git submodule) - # which only occurs with a malformatted locale setting which can - # happen sometimes on OSX. See again - # https://github.com/astropy/astropy/issues/2749 - perl_warning = ('perl: warning: Falling back to the standard locale ' - '("C").') - if not stderr.strip().endswith(perl_warning): - # Some other unknown error condition occurred - log.warn('git submodule command failed ' - 'unexpectedly:\n{0}'.format(stderr)) - return False - - # Output of `git submodule status` is as follows: - # - # 1: Status indicator: '-' for submodule is uninitialized, '+' if - # submodule is initialized but is not at the commit currently indicated - # in .gitmodules (and thus needs to be updated), or 'U' if the - # submodule is in an unstable state (i.e. has merge conflicts) - # - # 2. SHA-1 hash of the current commit of the submodule (we don't really - # need this information but it's useful for checking that the output is - # correct) - # - # 3. The output of `git describe` for the submodule's current commit - # hash (this includes for example what branches the commit is on) but - # only if the submodule is initialized. We ignore this information for - # now - _git_submodule_status_re = re.compile( - r'^(?P[+-U ])(?P[0-9a-f]{40}) ' - r'(?P\S+)( .*)?$') - - # The stdout should only contain one line--the status of the - # requested submodule - m = _git_submodule_status_re.match(stdout) - if m: - # Yes, the path *is* a git submodule - self._update_submodule(m.group('submodule'), m.group('status')) - return True - else: - log.warn( - 'Unexpected output from `git submodule status`:\n{0}\n' - 'Will attempt import from {1!r} regardless.'.format( - stdout, self.path)) - return False - - def _check_submodule_no_git(self): - """ - Like ``_check_submodule_using_git``, but simply parses the .gitmodules file - to determine if the supplied path is a git submodule, and does not exec any - subprocesses. - - This can only determine if a path is a submodule--it does not perform - updates, etc. This function may need to be updated if the format of the - .gitmodules file is changed between git versions. - """ - - gitmodules_path = os.path.abspath('.gitmodules') - - if not os.path.isfile(gitmodules_path): - return False - - # This is a minimal reader for gitconfig-style files. It handles a few of - # the quirks that make gitconfig files incompatible with ConfigParser-style - # files, but does not support the full gitconfig syntax (just enough - # needed to read a .gitmodules file). - gitmodules_fileobj = io.StringIO() - - # Must use io.open for cross-Python-compatible behavior wrt unicode - with io.open(gitmodules_path) as f: - for line in f: - # gitconfig files are more flexible with leading whitespace; just - # go ahead and remove it - line = line.lstrip() - - # comments can start with either # or ; - if line and line[0] in (':', ';'): - continue - - gitmodules_fileobj.write(line) - - gitmodules_fileobj.seek(0) - - cfg = RawConfigParser() - - try: - cfg.readfp(gitmodules_fileobj) - except Exception as exc: - log.warn('Malformatted .gitmodules file: {0}\n' - '{1} cannot be assumed to be a git submodule.'.format( - exc, self.path)) - return False - - for section in cfg.sections(): - if not cfg.has_option(section, 'path'): - continue - - submodule_path = cfg.get(section, 'path').rstrip(os.sep) - - if submodule_path == self.path.rstrip(os.sep): - return True - - return False - - def _update_submodule(self, submodule, status): - if status == ' ': - # The submodule is up to date; no action necessary - return - elif status == '-': - if self.offline: - raise _AHBootstrapSystemExit( - "Cannot initialize the {0} submodule in --offline mode; " - "this requires being able to clone the submodule from an " - "online repository.".format(submodule)) - cmd = ['update', '--init'] - action = 'Initializing' - elif status == '+': - cmd = ['update'] - action = 'Updating' - if self.offline: - cmd.append('--no-fetch') - elif status == 'U': - raise _AHBootstrapSystemExit( - 'Error: Submodule {0} contains unresolved merge conflicts. ' - 'Please complete or abandon any changes in the submodule so that ' - 'it is in a usable state, then try again.'.format(submodule)) - else: - log.warn('Unknown status {0!r} for git submodule {1!r}. Will ' - 'attempt to use the submodule as-is, but try to ensure ' - 'that the submodule is in a clean state and contains no ' - 'conflicts or errors.\n{2}'.format(status, submodule, - _err_help_msg)) - return - - err_msg = None - cmd = ['git', 'submodule'] + cmd + ['--', submodule] - log.warn('{0} {1} submodule with: `{2}`'.format( - action, submodule, ' '.join(cmd))) - - try: - log.info('Running `{0}`; use the --no-git option to disable git ' - 'commands'.format(' '.join(cmd))) - returncode, stdout, stderr = run_cmd(cmd) - except OSError as e: - err_msg = str(e) - else: - if returncode != 0: - err_msg = stderr - - if err_msg is not None: - log.warn('An unexpected error occurred updating the git submodule ' - '{0!r}:\n{1}\n{2}'.format(submodule, err_msg, - _err_help_msg)) - -class _CommandNotFound(OSError): - """ - An exception raised when a command run with run_cmd is not found on the - system. - """ - - -def run_cmd(cmd): - """ - Run a command in a subprocess, given as a list of command-line - arguments. - - Returns a ``(returncode, stdout, stderr)`` tuple. - """ - - try: - p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) - # XXX: May block if either stdout or stderr fill their buffers; - # however for the commands this is currently used for that is - # unlikely (they should have very brief output) - stdout, stderr = p.communicate() - except OSError as e: - if DEBUG: - raise - - if e.errno == errno.ENOENT: - msg = 'Command not found: `{0}`'.format(' '.join(cmd)) - raise _CommandNotFound(msg, cmd) - else: - raise _AHBootstrapSystemExit( - 'An unexpected error occurred when running the ' - '`{0}` command:\n{1}'.format(' '.join(cmd), str(e))) - - - # Can fail of the default locale is not configured properly. See - # https://github.com/astropy/astropy/issues/2749. For the purposes under - # consideration 'latin1' is an acceptable fallback. - try: - stdio_encoding = locale.getdefaultlocale()[1] or 'latin1' - except ValueError: - # Due to an OSX oddity locale.getdefaultlocale() can also crash - # depending on the user's locale/language settings. See: - # http://bugs.python.org/issue18378 - stdio_encoding = 'latin1' - - # Unlikely to fail at this point but even then let's be flexible - if not isinstance(stdout, str): - stdout = stdout.decode(stdio_encoding, 'replace') - if not isinstance(stderr, str): - stderr = stderr.decode(stdio_encoding, 'replace') - - return (p.returncode, stdout, stderr) - - -def _next_version(version): - """ - Given a parsed version from pkg_resources.parse_version, returns a new - version string with the next minor version. - - Examples - ======== - >>> _next_version(pkg_resources.parse_version('1.2.3')) - '1.3.0' - """ - - if hasattr(version, 'base_version'): - # New version parsing from setuptools >= 8.0 - if version.base_version: - parts = version.base_version.split('.') - else: - parts = [] - else: - parts = [] - for part in version: - if part.startswith('*'): - break - parts.append(part) - - parts = [int(p) for p in parts] - - if len(parts) < 3: - parts += [0] * (3 - len(parts)) - - major, minor, micro = parts[:3] - - return '{0}.{1}.{2}'.format(major, minor + 1, 0) - - -class _DummyFile(object): - """A noop writeable object.""" - - errors = '' # Required for Python 3.x - encoding = 'utf-8' - - def write(self, s): - pass - - def flush(self): - pass - - -@contextlib.contextmanager -def _verbose(): - yield - -@contextlib.contextmanager -def _silence(): - """A context manager that silences sys.stdout and sys.stderr.""" - - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = _DummyFile() - sys.stderr = _DummyFile() - exception_occurred = False - try: - yield - except: - exception_occurred = True - # Go ahead and clean up so that exception handling can work normally - sys.stdout = old_stdout - sys.stderr = old_stderr - raise - - if not exception_occurred: - sys.stdout = old_stdout - sys.stderr = old_stderr - - -_err_help_msg = """ -If the problem persists consider installing astropy_helpers manually using pip -(`pip install astropy_helpers`) or by manually downloading the source archive, -extracting it, and installing by running `python setup.py install` from the -root of the extracted source code. -""" - - -class _AHBootstrapSystemExit(SystemExit): - def __init__(self, *args): - if not args: - msg = 'An unknown problem occurred bootstrapping astropy_helpers.' - else: - msg = args[0] - - msg += '\n' + _err_help_msg - - super(_AHBootstrapSystemExit, self).__init__(msg, *args[1:]) - - -BOOTSTRAPPER = _Bootstrapper.main() - - -def use_astropy_helpers(**kwargs): - """ - Ensure that the `astropy_helpers` module is available and is importable. - This supports automatic submodule initialization if astropy_helpers is - included in a project as a git submodule, or will download it from PyPI if - necessary. - - Parameters - ---------- - - path : str or None, optional - A filesystem path relative to the root of the project's source code - that should be added to `sys.path` so that `astropy_helpers` can be - imported from that path. - - If the path is a git submodule it will automatically be initialized - and/or updated. - - The path may also be to a ``.tar.gz`` archive of the astropy_helpers - source distribution. In this case the archive is automatically - unpacked and made temporarily available on `sys.path` as a ``.egg`` - archive. - - If `None` skip straight to downloading. - - download_if_needed : bool, optional - If the provided filesystem path is not found an attempt will be made to - download astropy_helpers from PyPI. It will then be made temporarily - available on `sys.path` as a ``.egg`` archive (using the - ``setup_requires`` feature of setuptools. If the ``--offline`` option - is given at the command line the value of this argument is overridden - to `False`. - - index_url : str, optional - If provided, use a different URL for the Python package index than the - main PyPI server. - - use_git : bool, optional - If `False` no git commands will be used--this effectively disables - support for git submodules. If the ``--no-git`` option is given at the - command line the value of this argument is overridden to `False`. - - auto_upgrade : bool, optional - By default, when installing a package from a non-development source - distribution ah_boostrap will try to automatically check for patch - releases to astropy-helpers on PyPI and use the patched version over - any bundled versions. Setting this to `False` will disable that - functionality. If the ``--offline`` option is given at the command line - the value of this argument is overridden to `False`. - - offline : bool, optional - If `False` disable all actions that require an internet connection, - including downloading packages from the package index and fetching - updates to any git submodule. Defaults to `True`. - """ - - global BOOTSTRAPPER - - config = BOOTSTRAPPER.config - config.update(**kwargs) - - # Create a new bootstrapper with the updated configuration and run it - BOOTSTRAPPER = _Bootstrapper(**config) - BOOTSTRAPPER.run() diff --git a/astropy_helpers b/astropy_helpers deleted file mode 160000 index ba37342..0000000 --- a/astropy_helpers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ba3734222a40f4c2864c375c6639f32cd9df06cd From 425c128c7e7f1f1f2674b2d505a7a4d96fd636eb Mon Sep 17 00:00:00 2001 From: hamogu Date: Mon, 2 Mar 2020 13:45:57 -0500 Subject: [PATCH 3/6] Update to post astropy 4.0, with tox and without helpers --- .gitignore | 3 + .travis.yml | 211 +++++----- MANIFEST.in | 32 +- README.rst | 5 + docs/conf.py | 450 +++++++-------------- licenses/LICENSE.rst | 708 ++++++++++++++++++++++++++++++++++ licenses/README.rst | 9 + licenses/TEMPLATE_LICENCE.rst | 31 ++ pyproject.toml | 7 + saba/__init__.py | 19 +- saba/_astropy_init.py | 12 +- saba/conftest.py | 100 +++-- saba/tests/coveragerc | 31 -- setup.cfg | 106 ++--- setup.py | 202 +++------- tox.ini | 88 +++++ 16 files changed, 1268 insertions(+), 746 deletions(-) create mode 100644 README.rst create mode 100644 licenses/LICENSE.rst create mode 100644 licenses/README.rst create mode 100644 licenses/TEMPLATE_LICENCE.rst create mode 100644 pyproject.toml delete mode 100644 saba/tests/coveragerc create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index b1e15ac..e085608 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ distribute-*.tar.gz # Mac OSX .DS_Store + +saba/version.py +pip-wheel-metadata/ diff --git a/.travis.yml b/.travis.yml index cbbbdd3..03f62ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,12 @@ -# We set the language to c because python isn't supported on the MacOS X nodes -# on Travis. However, the language ends up being irrelevant anyway, since we -# install Python ourselves using conda. -language: c +language: python + +# We need a full clone to make sure setuptools_scm works properly +git: + depth: false os: - linux -# Setting sudo to false opts in to Travis-CI container-based builds. -sudo: false - # The apt packages below are needed for sphinx builds. A full list of packages # that can be included can be found here: # @@ -18,9 +16,17 @@ addons: apt: packages: - graphviz - - texlive-latex-extra - - dvipng - - gfortran + + +stages: + # Do the style check and a single test job, don't proceed if it fails + - name: Initial tests + # Test docs, astropy dev, and without optional dependencies + - name: Comprehensive tests + # These will only run when cron is opted in + - name: Cron tests + if: type = cron + env: global: @@ -28,45 +34,19 @@ env: # The following versions are the 'default' for tests, unless # overridden underneath. They are defined here in order to save having # to repeat them for all configurations. - - PYTHON_VERSION=3.7 - - NUMPY_VERSION=stable - - ASTROPY_VERSION=stable - - MAIN_CMD='python setup.py' - - SETUP_CMD='test' - - EVENT_TYPE='pull_request push' - - - # For this package-template, we include examples of Cython modules, - # so Cython is required for testing. If your package does not include - # Cython code, you can set CONDA_DEPENDENCIES='' - - CONDA_DEPENDENCIES='Cython sherpa' - - CONDA_DEPENDENCIES_DOC='Cython sphinx-astropy sherpa' - - # List other runtime dependencies for the package that are available as - # pip packages here. - - PIP_DEPENDENCIES='' - - # Conda packages for affiliated packages are hosted in channel - # "astropy" while builds for astropy LTS with recent numpy versions - # are in astropy-ci-extras. If your package uses either of these, - # add the channels to CONDA_CHANNELS along with any other channels - # you want to use. - - CONDA_CHANNELS='astropy-ci-extras astropy sherpa' - - # If there are matplotlib or other GUI tests, uncomment the following - # line to use the X virtual framebuffer. - # - SETUP_XVFB=True - - # If you want to ignore certain flake8 errors, you can list them - # in FLAKE8_OPT, for example: - # - FLAKE8_OPT='--ignore=E501' - - FLAKE8_OPT='' - - matrix: - # Make sure that egg_info works without dependencies - - PYTHON_VERSION=3.7 SETUP_CMD='egg_info' - - gfortran + # The following three variables are for tox. TOXENV is a standard + # variable that tox uses to determine the environment to run, + # TOXARGS are arguments passed to tox, and TOXPOSARGS are arguments + # that tox passes through to the {posargs} indicator in tox.ini. + # The latter can be used for example to pass arguments to pytest. + - TOXENV='test' + - TOXARGS='-v' + - TOXPOSARGS='' + + # The following is needed to avoid issues if e.g. Matplotlib tries + # to open a GUI window. + - SETUP_XVFB=True matrix: @@ -74,84 +54,109 @@ matrix: fast_finish: true include: - # Try MacOS X + + # Try MacOS X, usually enough only to run from cron as hardly there are + # issues that are not picked up by a linux worker. We set language to + # 'c' since 'python' doesn't work on non-Linux platforms. - os: osx - env: SETUP_CMD='test' + language: c + name: Python 3.7 with required dependencies + stage: Cron tests + env: PYTHON_VERSION=3.7 TOXENV=py37-test - # Do a coverage test. + # Do a regular build on Linux with Python 3.8, with cov + # For Linux we use language: python to avoid using conda. - os: linux - env: SETUP_CMD='test --coverage' + python: 3.8 + name: Python 3.8 with required dependencies and measure coverage + stage: Initial tests + env: TOXENV=py38-test-cov - # Check for sphinx doc build warnings - we do this first because it - # may run for a long time + # Check for sphinx doc build warnings - os: linux - env: SETUP_CMD='build_docs -w' - CONDA_DEPENDENCIES=$CONDA_DEPENDENCIES_DOC + python: 3.8 + name: Documentation build + stage: Comprehensive tests + env: TOXENV=build_docs - # Now try Astropy dev with the latest Python and LTS with Python 2.7 and 3.x. + # Now try Astropy dev with the latest Python - os: linux - env: ASTROPY_VERSION=development - EVENT_TYPE='pull_request push cron' - - os: linux - env: ASTROPY_VERSION=lts + python: 3.8 + name: Python 3.8 with developer version of astropy + stage: Comprehensive tests + env: TOXENV=py38-test-devdeps - # Try all python versions and Numpy versions. Since we can assume that + # And with an older Python, Astropy LTS, and the oldest supported Numpy + - os: linux + python: 3.6 + name: Python 3.6 astropy LTS and Numpy 1.16 + stage: Comprehensive tests + env: TOXENV=py36-test-astropylts-numpy116 + + # Add a job that runs from cron only and tests against astropy dev and + # numpy dev to give a change for early discovery of issues and feedback + # for both developer teams. + - os: linux + python: 3.8 + name: Python 3.8 latest developer version of key dependencies + stage: Cron tests + env: TOXENV=py38-test-devdeps + + # Try on Windows. + # Sherpa does not support windows, so we don't test on windows + # - os: windows + # language: c + # name: Python 3.8 with required dependencies + # stage: Comprehensive tests + # env: PYTHON_VERSION=3.8 TOXENV=py38-test + + # Try other python versions and Numpy versions. Since we can assume that # the Numpy developers have taken care of testing Numpy with different # versions of Python, we can vary Python and Numpy versions at the same # time. - os: linux - env: PYTHON_VERSION=3.5 NUMPY_VERSION=1.12 - - os: linux - env: PYTHON_VERSION=3.6 NUMPY_VERSION=1.13 - - os: linux - env: NUMPY_VERSION=1.14 - - # Try numpy dev - - os: linux - env: NUMPY_VERSION=dev - EVENT_TYPE='pull_request push cron' + python: 3.7 + name: Python 3.7 with astropy 3.0 and Numpy 1.17 + stage: Comprehensive tests + env: TOXENV=py37-test-astropy30-numpy117 - # Do a PEP8 test with flake8 + # Do a code style check - os: linux - env: MAIN_CMD='flake8 packagename --count --show-source --statistics $FLAKE8_OPT' SETUP_CMD='' + python: 3.8 + name: Code style checks + stage: Initial tests + env: TOXENV=codestyle allow_failures: # Do a PEP8 test with flake8 - # (allow to fail unless your code completely compliant) + # (do allow to fail unless your code completely compliant) - os: linux - env: MAIN_CMD='flake8 packagename --count --show-source --statistics $FLAKE8_OPT' SETUP_CMD='' + python: 3.8 + name: Code style checks + stage: Initial tests + env: TOXENV=codestyle install: - # We now use the ci-helpers package to set up our testing environment. - # This is done by using Miniconda and then using conda and pip to install - # dependencies. Which dependencies are installed using conda and pip is - # determined by the CONDA_DEPENDENCIES and PIP_DEPENDENCIES variables, - # which should be space-delimited lists of package names. See the README - # in https://github.com/astropy/ci-helpers for information about the full - # list of environment variables that can be used to customize your - # environment. In some cases, ci-helpers may not offer enough flexibility - # in how to install a package, in which case you can have additional - # commands in the install: section below. - - - git clone --depth 1 git://github.com/astropy/ci-helpers.git - - source ci-helpers/travis/setup_conda.sh - - # As described above, using ci-helpers, you should be able to set up an - # environment with dependencies installed using conda and pip, but in some - # cases this may not provide enough flexibility in how to install a - # specific dependency (and it will not be able to install non-Python - # dependencies). Therefore, you can also include commands below (as - # well as at the start of the install section or in the before_install - # section if they are needed before setting up conda) to install any - # other dependencies. + # We now use the ci-helpers package to set up our Python environment + # on Windows and MacOS X but we don't set up any other dependencies, + # instead using tox to do this. See https://github.com/astropy/ci-helpers + # for more information about ci-helpers. + + - if [[ $TRAVIS_OS_NAME != linux ]]; then + git clone --depth 1 git://github.com/astropy/ci-helpers.git; + source ci-helpers/travis/setup_conda.sh; + fi script: - - $MAIN_CMD $SETUP_CMD + - pip install tox + - tox $TOXARGS -- $TOXPOSARGS after_success: - - if [[ $SETUP_CMD == *coverage* ]]; then coveralls --rcfile='saba/tests/coveragerc'; fi - -notifications: - email: false + # If coveralls.io is set up for this package, uncomment the two lines below. + pip install coveralls + coveralls + # If codecov is set up for this package, uncomment the two lines below + # pip install codecov + # codecov diff --git a/MANIFEST.in b/MANIFEST.in index ab22bf5..b334771 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,42 +1,16 @@ include README.rst include CHANGES.rst - -include ez_setup.py -include ah_bootstrap.py include setup.cfg +include LICENSE.rst +include pyproject.toml -recursive-include *.pyx *.c *.pxd +recursive-include saba *.pyx *.c *.pxd recursive-include docs * recursive-include licenses * -recursive-include cextern * recursive-include scripts * prune build prune docs/_build prune docs/api - -# the next few stanzas are for astropy_helpers. It's derived from the -# astropy_helpers/MANIFEST.in, but requires additional includes for the actual -# package directory and egg-info. - -include astropy_helpers/README.rst -include astropy_helpers/CHANGES.rst -include astropy_helpers/LICENSE.rst -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.egg-info * -# include the sphinx stuff with "*" because there are css/html/rst/etc. -recursive-include astropy_helpers/astropy_helpers/sphinx * - -prune astropy_helpers/build -prune astropy_helpers/astropy_helpers/tests - - global-exclude *.pyc *.o - -include saba/tests/coveragerc diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..fbe8419 --- /dev/null +++ b/README.rst @@ -0,0 +1,5 @@ +SABA is a code to brigde astropy and and Sherpa modelling and fitting. Both +packages provide a a modelling and fitting framework that is in principle +compatible, but uses different APIs. SABA translates between the two packages, +so that e.g. sherpa models and fitters cna be used inside the astropy modelling +framework. diff --git a/docs/conf.py b/docs/conf.py index d5210df..2270281 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,227 +1,125 @@ # -*- coding: utf-8 -*- +# Licensed under a 3-clause BSD style license - see LICENSE.rst # -# saba documentation build configuration file, created by -# sphinx-quickstart on Wed Aug 19 16:30:00 2015. +# Astropy documentation build configuration file. # -# This file is execfile()d with the current directory set to its -# containing dir. +# 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. +# Note that not all possible configuration values are present in this file. # -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -# import shlex - -# AstroPy Helpers (at present a hard-coded dependency that must be -# pre-installed, rather than something that cna be bootstrap-installed -# during the documentation-build process). -# -from sphinx_astropy.conf import * +# All configuration values have a default. Some values are defined in +# the global Astropy configuration which is loaded here before anything else. +# 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 # documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) - -import saba - -# For now include the '+...' part of the version string -# and that I can drop the '+...' part. -# -saba_release = saba.__version__.split(".dev")[0] -saba_version = saba.__version__ - -# For sabaext -sys.path.insert(0, os.path.abspath('.')) - -# For run-time code used in the documentation -# TODO: is there a better way to do this? -sys.path.insert(0, os.path.join(os.path.abspath('.'), 'code')) - -# -- 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. - -# automodapi_writereprocessed = True - -# With my test setup, whey using 'python setup.py build_sphinx', -# the api docs get written to the top-level - i.e. *not* within -# docs/ - so see if I can avoid this. Unfortunately, changing -# this adjusts both the location of where the files are added -# *and* the reference used by the toctree directive - e.g. -# if automodapi_toctreedirnm is chaned from 'api' to 'docs/api' -# then the files get written to 'docs/api/', but then the -# toctree directive is (depending on where the file is) -# :toctree: docs/api/ -# :toctree: ../docs/api/ -# so it appears there's no way to change it sensibly. -# -# It's also not clear that adding these files to docs/ is a good -# idea (without at least telling something somewhere to exclude -# this directory). -# -# automodapi_toctreedirnm = 'docs/api' - -""" -extensions = [ - 'sphinx.ext.autodoc', - # currently do not look at coverage - # 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', - 'sphinx.ext.viewcode', - 'matplotlib.sphinxext.plot_directive' - 'sphinx.ext.intersphinx', - 'numpydoc.numpydoc' - -] -""" - -# override math generation -# - name depends on what version of astropy_helpers is installed -for n in ['pngmath', 'imgmath']: - try: - extensions.remove('sphinx.ext.' + n) - except ValueError: - pass - -extensions.append('sphinx.ext.mathjax') - -# Add any paths that contain templates here, relative to this directory. -# -templates_path = ['_templates'] +# sys.path.insert(0, os.path.abspath('..')) +# 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.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). +# Thus, any C-extensions that are needed to build the documentation will *not* +# be accessible, and the documentation will not build correctly. +import os +import sys +import datetime +from importlib import import_module -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +try: + from sphinx_astropy.conf.v1 import * # noqa +except ImportError: + print('ERROR: the documentation requires the sphinx-astropy package to be installed') + sys.exit(1) -# The encoding of source files. -#source_encoding = 'utf-8-sig' +# Get configuration information from setup.cfg +from configparser import ConfigParser +conf = ConfigParser() -# The master toctree document. -master_doc = 'index' +conf.read([os.path.join(os.path.dirname(__file__), '..', 'setup.cfg')]) +setup_cfg = dict(conf.items('metadata')) -# General information about the project. -project = u'saba' -author = u'NocturnalAstro' +# -- General configuration ---------------------------------------------------- -# 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 = saba_version -# The full version, including alpha/beta/rc tags. -release = saba_release +# By default, highlight as Python 3. +highlight_language = 'python3' -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.2' -# 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' +# To perform a Sphinx version check that needs to be more specific than +# major.minor, call `check_sphinx_version("x.y.z")` here. +# check_sphinx_version("1.2.1") # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -#exclude_patterns = ['_build'] - -# the astropy_helpers sets up exclude_patterns to include _build, -# and I am going to assume that that is unlikely to change exclude_patterns.append('_templates') -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None +# This is added to the end of RST files - a good place to put substitutions to +# be used globally. +rst_epilog += """ +.. _astropy: http://www.astropy.org/ +.. _matplotlib: http://matplotlib.org/ +.. _Sherpa: http://cxc.cfa.harvard.edu/contrib/sherpa/ +""" -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +modindex_common_prefix = ['saba.'] -# 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 +# -- Project information ------------------------------------------------------ -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +# This does not *have* to match the package name, but typically does +project = setup_cfg['name'] +author = setup_cfg['author'] +copyright = '{0}, {1}'.format( + datetime.datetime.now().year, setup_cfg['author']) -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# 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. -modindex_common_prefix = ['saba.'] +import_module(setup_cfg['name']) +package = sys.modules[setup_cfg['name']] -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# The short X.Y version. +version = package.__version__.split('-', 1)[0] +# The full version, including alpha/beta/rc tags. +release = package.__version__ -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False +# -- Options for HTML output -------------------------------------------------- -# Define standard header/footers. +# A NOTE ON HTML THEMES +# The global astropy configuration uses a custom theme, 'bootstrap-astropy', +# which is installed along with astropy. A different theme can be used or +# the options for this theme can be modified by overriding some of the +# variables set in the global configuration. The variables set in the +# global configuration are listed below, commented out. -rst_prolog = "" -rst_epilog = """ -.. _astropy: http://www.astropy.org/ -.. _matplotlib: http://matplotlib.org/ -.. _Sherpa: http://cxc.cfa.harvard.edu/contrib/sherpa/ -""" -# -- Options for HTML output ---------------------------------------------- +# 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 = [] # The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -#html_theme = 'alabaster' +# a list of builtin themes. To override the custom theme, set this to the +# name of a builtin theme or the name of a custom theme in html_theme_path. +#html_theme = None + -# For when/if we use ReadTheDocs, based on -# http://docs.readthedocs.org/en/latest/theme.html -# -''' -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -if not on_rtd: - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -else: - 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 = { 'logotext1': 'saba', # white, semi-bold - 'logotext2': ':docs', # orange, light - 'logotext3': '', # white, light - -} + 'logotext2': '', # orange, light + 'logotext3': ':docs' # white, light + } -# 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 +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -232,161 +130,77 @@ # pixels large. html_favicon = os.path.join('_static', 'favicon.ico') -# 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'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - # 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 = {} +#html_last_updated_fmt = '' -# 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 - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +html_title = '{0} v{1}'.format(project, release) # Output file base name for HTML help builder. -htmlhelp_basename = 'sabadoc' +htmlhelp_basename = project + 'doc' -# -- 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': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', +# Add logo in left bar - this differs from astropy template +html_context = { + 'css_files': ['_static/saba.css'], } -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'astrosherpabridge.tex', u'AstroSherpaBridge Documentation', - u'', 'manual'), -] +intersphinx_mapping['sherpa'] = ('http://sherpa.readthedocs.io/en/stable/', None) -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None +# -- Options for LaTeX output ------------------------------------------------- -# 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 +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', project + '.tex', project + u' Documentation', + author, 'manual')] -# -- Options for manual page output --------------------------------------- +# -- Options for manual page output ------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'astrosherpabridge', u'AstroSherpaBridge Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False +man_pages = [('index', project.lower(), project + u' Documentation', + [author], 1)] -# -- Options for Texinfo output ------------------------------------------- +# -- Options for the edit_on_github extension --------------------------------- -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'astrosherpabridge', u'AstroSherpaBridge Documentation', - author, 'AstroSherpaBridge', 'One line description of project.', - 'Miscellaneous'), -] +if setup_cfg.get('edit_on_github').lower() == 'true': -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] + extensions += ['sphinx_astropy.ext.edit_on_github'] -# If false, no module index is generated. -#texinfo_domain_indices = True + edit_on_github_project = setup_cfg['github_project'] + edit_on_github_branch = "master" -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' + edit_on_github_source_root = "" + edit_on_github_doc_root = "docs" -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# -- Resolving issue number to links in changelog ----------------------------- +github_issues_url = 'https://github.com/{0}/issues/'.format(setup_cfg['github_project']) - -intersphinx_mapping = { - 'astropy': ('http://docs.astropy.org/en/stable/', None), - 'sherpa': ('http://hea-www.harvard.edu/~dburke/playground/sherpa/', None) - } - -html_context = { - 'css_files': ['_static/saba.css'], -} +# -- 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/licenses/LICENSE.rst b/licenses/LICENSE.rst new file mode 100644 index 0000000..12f76e0 --- /dev/null +++ b/licenses/LICENSE.rst @@ -0,0 +1,708 @@ +Copyright (C) 2020, Michele Costa, Hans Moritz Guenther + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +--- + +****************************************************************************** +GNU General Public License +****************************************************************************** + +Version 3, 29 June 2007 + +Copyright (c) 2007 Free Software Foundation, Inc. <`http://fsf.org/`_> + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +.. contents:: + +Preamble +============================================================================== + +The GNU General Public License is a free, copyleft license for software and +other kinds of works. + +The licenses for most software and other practical works are designed to take +away your freedom to share and change the works. By contrast, the GNU General +Public License is intended to guarantee your freedom to share and change all +versions of a program--to make sure it remains free software for all its +users. We, the Free Software Foundation, use the GNU General Public License +for most of our software; it applies also to any other work released this way +by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for them if you wish), that +you receive source code or can get it if you want it, that you can change the +software or use pieces of it in new free programs, and that you know you can +do these things. + +To protect your rights, we need to prevent others from denying you these +rights or asking you to surrender the rights. Therefore, you have certain +responsibilities if you distribute copies of the software, or if you modify +it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must pass on to the recipients the same freedoms that you +received. You must make sure that they, too, receive or can get the source +code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) +assert copyright on the software, and (2) offer you this License giving you +legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that +there is no warranty for this free software. For both users' and authors' +sake, the GPL requires that modified versions be marked as changed, so that +their problems will not be attributed erroneously to authors of previous +versions. + +Some devices are designed to deny users access to install or run modified +versions of the software inside them, although the manufacturer can do so. +This is fundamentally incompatible with the aim of protecting users' freedom +to change the software. The systematic pattern of such abuse occurs in the +area of products for individuals to use, which is precisely where it is most +unacceptable. Therefore, we have designed this version of the GPL to prohibit +the practice for those products. If such problems arise substantially in +other domains, we stand ready to extend this provision to those domains in +future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States +should not allow patents to restrict development and use of software on +general-purpose computers, but in those that do, we wish to avoid the special +danger that patents applied to a free program could make it effectively +proprietary. To prevent this, the GPL assures that patents cannot be used to +render the program non-free. + +The precise terms and conditions for copying, distribution and modification +follow. + + +Terms and conditions +============================================================================== + + +0. Definitions. +------------------------------------------------------------------------------ + +?This License? refers to version 3 of the GNU General Public License. + +?Copyright? also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +?The Program? refers to any copyrightable work licensed under this License. +Each licensee is addressed as ?you?. ?Licensees? and ?recipients? may be +individuals or organizations. + +To ?modify? a work means to copy from or adapt all or part of the work in a +fashion requiring copyright permission, other than the making of an exact +copy. The resulting work is called a ?modified version? of the earlier work +or a work ?based on? the earlier work. + +A ?covered work? means either the unmodified Program or a work based on the +Program. + +To ?propagate? a work means to do anything with it that, without permission, +would make you directly or secondarily liable for infringement under +applicable copyright law, except executing it on a computer or modifying a +private copy. Propagation includes copying, distribution (with or without +modification), making available to the public, and in some countries other +activities as well. + +To ?convey? a work means any kind of propagation that enables other parties +to make or receive copies. Mere interaction with a user through a computer +network, with no transfer of a copy, is not conveying. + +An interactive user interface displays ?Appropriate Legal Notices? to the +extent that it includes a convenient and prominently visible feature that (1) +displays an appropriate copyright notice, and (2) tells the user that there +is no warranty for the work (except to the extent that warranties are +provided), that licensees may convey the work under this License, and how to +view a copy of this License. If the interface presents a list of user +commands or options, such as a menu, a prominent item in the list meets this +criterion. + + +1. Source Code. +------------------------------------------------------------------------------ + +The ?source code? for a work means the preferred form of the work for making +modifications to it. ?Object code? means any non-source form of a work. + +A ?Standard Interface? means an interface that either is an official standard +defined by a recognized standards body, or, in the case of interfaces +specified for a particular programming language, one that is widely used +among developers working in that language. + +The ?System Libraries? of an executable work include anything, other than the +work as a whole, that (a) is included in the normal form of packaging a Major +Component, but which is not part of that Major Component, and (b) serves only +to enable use of the work with that Major Component, or to implement a +Standard Interface for which an implementation is available to the public in +source code form. A ?Major Component?, in this context, means a major +essential component (kernel, window system, and so on) of the specific +operating system (if any) on which the executable work runs, or a compiler +used to produce the work, or an object code interpreter used to run it. + +The ?Corresponding Source? for a work in object code form means all the +source code needed to generate, install, and (for an executable work) run the +object code and to modify the work, including scripts to control those +activities. However, it does not include the work's System Libraries, or +general-purpose tools or generally available free programs which are used +unmodified in performing those activities but which are not part of the work. +For example, Corresponding Source includes interface definition files +associated with source files for the work, and the source code for shared +libraries and dynamically linked subprograms that the work is specifically +designed to require, such as by intimate data communication or control flow +between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate +automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + + +2. Basic Permissions. +------------------------------------------------------------------------------ + +All rights granted under this License are granted for the term of copyright +on the Program, and are irrevocable provided the stated conditions are met. +This License explicitly affirms your unlimited permission to run the +unmodified Program. The output from running a covered work is covered by this +License only if the output, given its content, constitutes a covered work. +This License acknowledges your rights of fair use or other equivalent, as +provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without +conditions so long as your license otherwise remains in force. You may convey +covered works to others for the sole purpose of having them make +modifications exclusively for you, or provide you with facilities for running +those works, provided that you comply with the terms of this License in +conveying all material for which you do not control copyright. Those thus +making or running the covered works for you must do so exclusively on your +behalf, under your direction and control, on terms that prohibit them from +making any copies of your copyrighted material outside their relationship +with you. + +Conveying under any other circumstances is permitted solely under the +conditions stated below. Sublicensing is not allowed; section 10 makes it +unnecessary. + + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +------------------------------------------------------------------------------ + +No covered work shall be deemed part of an effective technological measure +under any applicable law fulfilling obligations under article 11 of the WIPO +copyright treaty adopted on 20 December 1996, or similar laws prohibiting or +restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention is +effected by exercising rights under this License with respect to the covered +work, and you disclaim any intention to limit operation or modification of +the work as a means of enforcing, against the work's users, your or third +parties' legal rights to forbid circumvention of technological measures. + + +4. Conveying Verbatim Copies. +------------------------------------------------------------------------------ + +You may convey verbatim copies of the Program's source code as you receive +it, in any medium, provided that you conspicuously and appropriately publish +on each copy an appropriate copyright notice; keep intact all notices stating +that this License and any non-permissive terms added in accord with section 7 +apply to the code; keep intact all notices of the absence of any warranty; +and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you +may offer support or warranty protection for a fee. + + +5. Conveying Modified Source Versions. +------------------------------------------------------------------------------ + +You may convey a work based on the Program, or the modifications to produce +it from the Program, in the form of source code under the terms of section 4, +provided that you also meet all of these conditions: + +- a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. +- b) The work must carry prominent notices stating that it is released + under this License and any conditions added under section 7. This + requirement modifies the requirement in section 4 to ?keep intact all + notices?. +- c) You must license the entire work, as a whole, under this License + to anyone who comes into possession of a copy. This License will + therefore apply, along with any applicable section 7 additional terms, to + the whole of the work, and all its parts, regardless of how they are + packaged. This License gives no permission to license the work in any + other way, but it does not invalidate such permission if you have + separately received it. +- d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your work need + not make them do so. + +A compilation of a covered work with other separate and independent works, +which are not by their nature extensions of the covered work, and which are +not combined with it such as to form a larger program, in or on a volume of a +storage or distribution medium, is called an ?aggregate? if the compilation +and its resulting copyright are not used to limit the access or legal rights +of the compilation's users beyond what the individual works permit. Inclusion +of a covered work in an aggregate does not cause this License to apply to the +other parts of the aggregate. + + +6. Conveying Non-Source Forms. +------------------------------------------------------------------------------ + +You may convey a covered work in object code form under the terms of sections +4 and 5, provided that you also convey the machine-readable Corresponding +Source under the terms of this License, in one of these ways: + +- a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium customarily used + for software interchange. +- b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a written + offer, valid for at least three years and valid for as long as you offer + spare parts or customer support for that product model, to give anyone + who possesses the object code either (1) a copy of the Corresponding + Source for all the software in the product that is covered by this + License, on a durable physical medium customarily used for software + interchange, for a price no more than your reasonable cost of physically + performing this conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. +- c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This alternative is + allowed only occasionally and noncommercially, and only if you received + the object code with such an offer, in accord with subsection 6b. +- d) Convey the object code by offering access from a designated place + (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no further + charge. You need not require recipients to copy the Corresponding Source + along with the object code. If the place to copy the object code is a + network server, the Corresponding Source may be on a different server + (operated by you or a third party) that supports equivalent copying + facilities, provided you maintain clear directions next to the object + code saying where to find the Corresponding Source. Regardless of what + server hosts the Corresponding Source, you remain obligated to ensure + that it is available for as long as needed to satisfy these requirements. +- e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding Source of + the work are being offered to the general public at no charge under + subsection 6d. + +A separable portion of the object code, whose source code is excluded from +the Corresponding Source as a System Library, need not be included in +conveying the object code work. + +A ?User Product? is either (1) a ?consumer product?, which means any tangible +personal property which is normally used for personal, family, or household +purposes, or (2) anything designed or sold for incorporation into a dwelling. +In determining whether a product is a consumer product, doubtful cases shall +be resolved in favor of coverage. For a particular product received by a +particular user, ?normally used? refers to a typical or common use of that +class of product, regardless of the status of the particular user or of the +way in which the particular user actually uses, or expects or is expected to +use, the product. A product is a consumer product regardless of whether the +product has substantial commercial, industrial or non-consumer uses, unless +such uses represent the only significant mode of use of the product. + +?Installation Information? for a User Product means any methods, procedures, +authorization keys, or other information required to install and execute +modified versions of a covered work in that User Product from a modified +version of its Corresponding Source. The information must suffice to ensure +that the continued functioning of the modified object code is in no case +prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as part of +a transaction in which the right of possession and use of the User Product is +transferred to the recipient in perpetuity or for a fixed term (regardless of +how the transaction is characterized), the Corresponding Source conveyed +under this section must be accompanied by the Installation Information. But +this requirement does not apply if neither you nor any third party retains +the ability to install modified object code on the User Product (for example, +the work has been installed in ROM). + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates for +a work that has been modified or installed by the recipient, or for the User +Product in which it has been modified or installed. Access to a network may +be denied when the modification itself materially and adversely affects the +operation of the network or violates the rules and protocols for +communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in +accord with this section must be in a format that is publicly documented (and +with an implementation available to the public in source code form), and must +require no special password or key for unpacking, reading or copying. + + +7. Additional Terms. +------------------------------------------------------------------------------ + +?Additional permissions? are terms that supplement the terms of this License +by making exceptions from one or more of its conditions. Additional +permissions that are applicable to the entire Program shall be treated as +though they were included in this License, to the extent that they are valid +under applicable law. If additional permissions apply only to part of the +Program, that part may be used separately under those permissions, but the +entire Program remains governed by this License without regard to the +additional permissions. + +When you convey a copy of a covered work, you may at your option remove any +additional permissions from that copy, or from any part of it. (Additional +permissions may be written to require their own removal in certain cases when +you modify the work.) You may place additional permissions on material, added +by you to a covered work, for which you have or can give appropriate +copyright permission. + +Notwithstanding any other provision of this License, for material you add to +a covered work, you may (if authorized by the copyright holders of that +material) supplement the terms of this License with terms: + +- a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or +- b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal Notices + displayed by works containing it; or +- c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in reasonable + ways as different from the original version; or +- d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or +- e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or +- f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of it) + with contractual assumptions of liability to the recipient, for any + liability that these contractual assumptions directly impose on those + licensors and authors. + +All other non-permissive additional terms are considered ?further +restrictions? within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is governed +by this License along with a term that is a further restriction, you may +remove that term. If a license document contains a further restriction but +permits relicensing or conveying under this License, you may add to a covered +work material governed by the terms of that license document, provided that +the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must +place, in the relevant source files, a statement of the additional terms that +apply to those files, or a notice indicating where to find the applicable +terms. + +Additional terms, permissive or non-permissive, may be stated in the form of +a separately written license, or stated as exceptions; the above requirements +apply either way. + + +8. Termination. +------------------------------------------------------------------------------ + +You may not propagate or modify a covered work except as expressly provided +under this License. Any attempt otherwise to propagate or modify it is void, +and will automatically terminate your rights under this License (including +any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a +particular copyright holder is reinstated (a) provisionally, unless and until +the copyright holder explicitly and finally terminates your license, and (b) +permanently, if the copyright holder fails to notify you of the violation by +some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated +permanently if the copyright holder notifies you of the violation by some +reasonable means, this is the first time you have received notice of +violation of this License (for any work) from that copyright holder, and you +cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses +of parties who have received copies or rights from you under this License. If +your rights have been terminated and not permanently reinstated, you do not +qualify to receive new licenses for the same material under section 10. + + +9. Acceptance Not Required for Having Copies. +------------------------------------------------------------------------------ + +You are not required to accept this License in order to receive or run a copy +of the Program. Ancillary propagation of a covered work occurring solely as a +consequence of using peer-to-peer transmission to receive a copy likewise +does not require acceptance. However, nothing other than this License grants +you permission to propagate or modify any covered work. These actions +infringe copyright if you do not accept this License. Therefore, by modifying +or propagating a covered work, you indicate your acceptance of this License +to do so. + + +10. Automatic Licensing of Downstream Recipients. +------------------------------------------------------------------------------ + +Each time you convey a covered work, the recipient automatically receives a +license from the original licensors, to run, modify and propagate that work, +subject to this License. You are not responsible for enforcing compliance by +third parties with this License. + +An ?entity transaction? is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered work +results from an entity transaction, each party to that transaction who +receives a copy of the work also receives whatever licenses to the work the +party's predecessor in interest had or could give under the previous +paragraph, plus a right to possession of the Corresponding Source of the work +from the predecessor in interest, if the predecessor has it or can get it +with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights +granted or affirmed under this License. For example, you may not impose a +license fee, royalty, or other charge for exercise of rights granted under +this License, and you may not initiate litigation (including a cross-claim or +counterclaim in a lawsuit) alleging that any patent claim is infringed by +making, using, selling, offering for sale, or importing the Program or any +portion of it. + + +11. Patents. +------------------------------------------------------------------------------ + +A ?contributor? is a copyright holder who authorizes use under this License +of the Program or a work on which the Program is based. The work thus +licensed is called the contributor's ?contributor version?. + +A contributor's ?essential patent claims? are all patent claims owned or +controlled by the contributor, whether already acquired or hereafter +acquired, that would be infringed by some manner, permitted by this License, +of making, using, or selling its contributor version, but do not include +claims that would be infringed only as a consequence of further modification +of the contributor version. For purposes of this definition, ?control? +includes the right to grant patent sublicenses in a manner consistent with +the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent +license under the contributor's essential patent claims, to make, use, sell, +offer for sale, import and otherwise run, modify and propagate the contents +of its contributor version. + +In the following three paragraphs, a ?patent license? is any express +agreement or commitment, however denominated, not to enforce a patent (such +as an express permission to practice a patent or covenant not to sue for +patent infringement). To ?grant? such a patent license to a party means to +make such an agreement or commitment not to enforce a patent against the +party. + +If you convey a covered work, knowingly relying on a patent license, and the +Corresponding Source of the work is not available for anyone to copy, free of +charge and under the terms of this License, through a publicly available +network server or other readily accessible means, then you must either (1) +cause the Corresponding Source to be so available, or (2) arrange to deprive +yourself of the benefit of the patent license for this particular work, or +(3) arrange, in a manner consistent with the requirements of this License, to +extend the patent license to downstream recipients. ?Knowingly relying? means +you have actual knowledge that, but for the patent license, your conveying +the covered work in a country, or your recipient's use of the covered work in +a country, would infringe one or more identifiable patents in that country +that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, +you convey, or propagate by procuring conveyance of, a covered work, and +grant a patent license to some of the parties receiving the covered work +authorizing them to use, propagate, modify or convey a specific copy of the +covered work, then the patent license you grant is automatically extended to +all recipients of the covered work and works based on it. + +A patent license is ?discriminatory? if it does not include within the scope +of its coverage, prohibits the exercise of, or is conditioned on the non- +exercise of one or more of the rights that are specifically granted under +this License. You may not convey a covered work if you are a party to an +arrangement with a third party that is in the business of distributing +software, under which you make payment to the third party based on the extent +of your activity of conveying the work, and under which the third party +grants, to any of the parties who would receive the covered work from you, a +discriminatory patent license (a) in connection with copies of the covered +work conveyed by you (or copies made from those copies), or (b) primarily for +and in connection with specific products or compilations that contain the +covered work, unless you entered into that arrangement, or that patent +license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any +implied license or other defenses to infringement that may otherwise be +available to you under applicable patent law. + + +12. No Surrender of Others' Freedom. +------------------------------------------------------------------------------ + +If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not excuse +you from the conditions of this License. If you cannot convey a covered work +so as to satisfy simultaneously your obligations under this License and any +other pertinent obligations, then as a consequence you may not convey it at +all. For example, if you agree to terms that obligate you to collect a +royalty for further conveying from those to whom you convey the Program, the +only way you could satisfy both those terms and this License would be to +refrain entirely from conveying the Program. + + +13. Use with the GNU Affero General Public License. +------------------------------------------------------------------------------ + +Notwithstanding any other provision of this License, you have permission to +link or combine any covered work with a work licensed under version 3 of the +GNU Affero General Public License into a single combined work, and to convey +the resulting work. The terms of this License will continue to apply to the +part which is the covered work, but the special requirements of the GNU +Affero General Public License, section 13, concerning interaction through a +network will apply to the combination as such. + + +14. Revised Versions of this License. +------------------------------------------------------------------------------ + +The Free Software Foundation may publish revised and/or new versions of the +GNU General Public License from time to time. Such new versions will be +similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies that a certain numbered version of the GNU General Public License +?or any later version? applies to it, you have the option of following the +terms and conditions either of that numbered version or of any later version +published by the Free Software Foundation. If the Program does not specify a +version number of the GNU General Public License, you may choose any version +ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the +GNU General Public License can be used, that proxy's public statement of +acceptance of a version permanently authorizes you to choose that version for +the Program. + +Later license versions may give you additional or different permissions. +However, no additional obligations are imposed on any author or copyright +holder as a result of your choosing to follow a later version. + + +15. Disclaimer of Warranty. +------------------------------------------------------------------------------ + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE +LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM ?AS IS? WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. +SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY +SERVICING, REPAIR OR CORRECTION. + + +16. Limitation of Liability. +------------------------------------------------------------------------------ + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE +OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR +DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR +A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +17. Interpretation of Sections 15 and 16. +------------------------------------------------------------------------------ + +If the disclaimer of warranty and limitation of liability provided above +cannot be given local legal effect according to their terms, reviewing courts +shall apply local law that most closely approximates an absolute waiver of +all civil liability in connection with the Program, unless a warranty or +assumption of liability accompanies a copy of the Program in return for a +fee. + +END OF TERMS AND CONDITIONS + + +How to Apply These Terms to Your New Programs +============================================================================== + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively state the exclusion +of warranty; and each file should have at least the ?copyright? line and a +pointer to where the full notice is found. + +:: + Copyright (C) + + This program is free software: you can redistribute it and/or + modify + it under the terms of the GNU General Public License as + published by + the Free Software Foundation, either version 3 of the + License, or + (at your option) any later version. + + This program is distributed in the hope that it will be + useful, + but WITHOUT ANY WARRANTY; without even the implied warranty + of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License + along with this program. If not, see + . + + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like +this when it starts in an interactive mode: + +:: Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details + type ``show w``. + This is free software, and you are welcome to redistribute it + under certain conditions; type ``show c`` for details. + + +The hypothetical commands ``show w`` and ``show c`` should show the appropriate +parts of the General Public License. Of course, your program's commands might +be different; for a GUI interface, you would use an ?about box?. + +You should also get your employer (if you work as a programmer) or school, if +any, to sign a ?copyright disclaimer? for the program, if necessary. For more +information on this, and how to apply and follow the GNU GPL, see +<`http://www.gnu.org/licenses/`_>. + +The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General Public +License instead of this License. But first, please read +<`http://www.gnu.org/philosophy/why-not-lgpl.html`_>. + +.. _http://fsf.org/: http://fsf.org/ +.. _http://www.gnu.org/licenses/: http://www.gnu.org/licenses/ +.. _http://www.gnu.org/philosophy/why-not-lgpl.html: + http://www.gnu.org/philosophy/why-not-lgpl.html diff --git a/licenses/README.rst b/licenses/README.rst new file mode 100644 index 0000000..67b82f6 --- /dev/null +++ b/licenses/README.rst @@ -0,0 +1,9 @@ +Licenses +======== + +This directory holds license and credit information for the package, +works the package is derived from, and/or datasets. + +Ensure that you pick a package licence which is in this folder and it matches +the one mentioned in the top level README.rst file. If you are using the +pre-rendered version of this template check for the word 'Other' in the README. diff --git a/licenses/TEMPLATE_LICENCE.rst b/licenses/TEMPLATE_LICENCE.rst new file mode 100644 index 0000000..f29177b --- /dev/null +++ b/licenses/TEMPLATE_LICENCE.rst @@ -0,0 +1,31 @@ +This project is based upon the Astropy package template +(https://github.com/astropy/package-template/) which is licenced under the terms +of the following licence. + +--- + +Copyright (c) 2018, Astropy Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the Astropy Team nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..7e7daea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] + +requires = ["setuptools", + "setuptools_scm", + "wheel"] + +build-backend = 'setuptools.build_meta' diff --git a/saba/__init__.py b/saba/__init__.py index 266937d..37732df 100644 --- a/saba/__init__.py +++ b/saba/__init__.py @@ -7,20 +7,9 @@ # Affiliated packages may add whatever they like to this file, but # should keep this content at the top. # ---------------------------------------------------------------------------- -from ._astropy_init import * +from ._astropy_init import * # noqa # ---------------------------------------------------------------------------- -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("packagename does not support Python < {}".format(__minimum_python_version__)) - - -# For egg_info test builds to pass, put package imports here. -if not _ASTROPY_SETUP_: - from .main import SherpaFitter, SherpaMCMC, Stat, OptMethod, EstMethod, Dataset, ConvertedModel +from .main import (SherpaFitter, SherpaMCMC, + Stat, OptMethod, EstMethod, + Dataset, ConvertedModel) diff --git a/saba/_astropy_init.py b/saba/_astropy_init.py index 1e229e1..2dffe8f 100644 --- a/saba/_astropy_init.py +++ b/saba/_astropy_init.py @@ -1,26 +1,18 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -__all__ = ['__version__', '__githash__'] +__all__ = ['__version__'] # this indicates whether or not we are in the package's setup.py try: _ASTROPY_SETUP_ except NameError: - from sys import version_info - if version_info[0] >= 3: - import builtins - else: - import __builtin__ as builtins + import builtins builtins._ASTROPY_SETUP_ = False try: from .version import version as __version__ except ImportError: __version__ = '' -try: - from .version import githash as __githash__ -except ImportError: - __githash__ = '' if not _ASTROPY_SETUP_: # noqa diff --git a/saba/conftest.py b/saba/conftest.py index 8130402..48ed37a 100644 --- a/saba/conftest.py +++ b/saba/conftest.py @@ -1,63 +1,51 @@ # This file is used to configure the behavior of pytest when using the Astropy -# test infrastructure. +# test infrastructure. It needs to live inside the package in order for it to +# get picked up when running the tests inside an interpreter using +# packagename.test + +import os from astropy.version import version as astropy_version + +# For Astropy 3.0 and later, we can use the standalone pytest plugin 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 * + from astropy.tests.pytest_plugins import * # noqa + del pytest_report_header + ASTROPY_HEADER = True 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() + try: + from pytest_astropy_header.display import PYTEST_HEADER_MODULES, TESTED_VERSIONS + ASTROPY_HEADER = True + except ImportError: + ASTROPY_HEADER = False -# 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['sherpa'] = 'sherpa' - del PYTEST_HEADER_MODULES['h5py'] - del PYTEST_HEADER_MODULES['Pandas'] - del PYTEST_HEADER_MODULES['Scipy'] -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. -import os -# This is to figure out the affiliated package version, rather than -# using Astropy's -try: - from .version import version, astropy_helpers_version -except ImportError: - version = 'dev' - -try: - packagename = os.path.basename(os.path.dirname(__file__)) - TESTED_VERSIONS[packagename] = version - TESTED_VERSIONS['astropy_helpers'] = astropy_helpers_version -except NameError: # Needed to support Astropy <= 1.0.0 - pass +def pytest_configure(config): + + if ASTROPY_HEADER: + + config.option.astropy_header = True + + # Customize the following lines to add/remove entries from the list of + # packages for which version numbers are displayed when running the tests. + PYTEST_HEADER_MODULES.pop('Pandas', None) + PYTEST_HEADER_MODULES.pop('h5py', None) + + PYTEST_HEADER_MODULES['sherpa'] = 'sherpa' + + from . import __version__ + packagename = os.path.basename(os.path.dirname(__file__)) + TESTED_VERSIONS[packagename] = __version__ + +# Uncomment the last two lines in this block 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']} +# from astropy.tests.helper import enable_deprecations_as_exceptions # noqa +# enable_deprecations_as_exceptions() diff --git a/saba/tests/coveragerc b/saba/tests/coveragerc deleted file mode 100644 index 3a21984..0000000 --- a/saba/tests/coveragerc +++ /dev/null @@ -1,31 +0,0 @@ -[run] -source = saba -omit = - saba/_astropy_init* - saba/conftest* - saba/cython_version* - saba/setup_package* - saba/*/setup_package* - saba/*/*/setup_package* - saba/tests/* - saba/*/tests/* - saba/*/*/tests/* - saba/version* - -[report] -exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - - # Don't complain about packages we have installed - # except ImportError - - # Don't complain if tests don't hit assertions - raise AssertionError - raise NotImplementedError - - # Don't complain about script hooks - def main\(.*\): - - # Ignore branches that don't pertain to this version of Python - pragma: py{ignore_python_version} diff --git a/setup.cfg b/setup.cfg index 553d028..4abc4c6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,52 +1,68 @@ -[build_sphinx] -source-dir = docs -build-dir = docs/_build -all_files = 1 - -[build_docs] -source-dir = docs -build-dir = docs/_build -all_files = 1 - -[upload_docs] -upload-dir = docs/_build/html -show-response = 1 - -[tool:pytest] -minversion = 3.0 -norecursedirs = build docs/_build -doctest_plus = enabled -addopts = -p no:warnings - -[ah_bootstrap] -auto_use = True - -[flake8] -exclude = extern,sphinx,*parsetab.py - -[pycodestyle] -exclude = extern,sphinx,*parsetab.py - [metadata] -package_name = saba -description = SABA - A code to bridge and astropy and sherpa -long_description = SABA is a code to brigde astropy and and Sherpa modelling and fitting. Both packages provide a a modelling and fitting framework that is in principle compatible, but uses different APIs. SABA translates between the two packages, so that e.g. sherpa models and fitters cna be used inside the astropy modelling framework. -author = Michele Costa +name = saba +author = Michele Costa, Hans Moritz Guenther author_email = micky.t.costa@gmail.com -license = GPLv3+ +license = GNU GPL v3+ +license_file = licenses/LICENSE.rst url = https://github.com/astropy/saba -edit_on_github = False +description = SABA - A code to bridge and astropy and sherpa +long_description = file: README.rst +long_description_content_type = text/x-rst +edit_on_github = True github_project = astropy/saba -# install_requires should be formatted as a comma-separated list, e.g.: -# install_requires = astropy, scipy, matplotlib -install_requires = astropy -# version should be PEP440 compatible (https://www.python.org/dev/peps/pep-0440/) -version = 0.2.dev -# Note: you will also need to change this in your package's __init__.py -minimum_python_version = 3.5 +[options] +zip_safe = False +packages = find: +python_requires = >=3.6 +setup_requires = setuptools_scm +install_requires = + numpy + astropy + sherpa + +[options.extras_require] +test = + pytest-astropy +docs = + sphinx-astropy + +[tool:pytest] +testpaths = "saba" "docs" +astropy_header = true +doctest_plus = enabled +text_file_format = rst +addopts = --doctest-rst -[entry_points] +[coverage:run] +omit = + saba/_astropy_init* + saba/conftest.py + saba/*setup_package* + saba/tests/* + saba/*/tests/* + saba/extern/* + saba/version* + */saba/_astropy_init* + */saba/conftest.py + */saba/*setup_package* + */saba/tests/* + */saba/*/tests/* + */saba/extern/* + */saba/version* -[saba_entry_points] -SherpaFitter = saba:SherpaFitter +[coverage:report] +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + # Don't complain about packages we have installed + except ImportError + # Don't complain if tests don't hit assertions + raise AssertionError + raise NotImplementedError + # Don't complain about script hooks + def main\(.*\): + # Ignore branches that don't pertain to this version of Python + pragma: py{ignore_python_version} + # Don't complain about IPython completion helper + def _ipython_key_completions_ diff --git a/setup.py b/setup.py index fc21e8d..c7efed3 100755 --- a/setup.py +++ b/setup.py @@ -1,154 +1,78 @@ #!/usr/bin/env python # Licensed under a 3-clause BSD style license - see LICENSE.rst -import glob +# NOTE: The configuration for the package, including the name, version, and +# other information are set in the setup.cfg file. + import os import sys -try: - from configparser import ConfigParser -except ImportError: - from ConfigParser import ConfigParser +from setuptools import setup + + +# First provide helpful messages if contributors try and run legacy commands +# for tests or docs. -# Get some values from the setup.cfg -conf = ConfigParser() -conf.read(['setup.cfg']) -metadata = dict(conf.items('metadata')) +TEST_HELP = """ +Note: running tests is no longer done using 'python setup.py test'. Instead +you will need to run: -PACKAGENAME = metadata.get('package_name', 'packagename') -DESCRIPTION = metadata.get('description', 'Use astropy models with sherpa') -AUTHOR = metadata.get('author', '') -AUTHOR_EMAIL = metadata.get('author_email', '') -LICENSE = metadata.get('license', 'unknown') -URL = metadata.get('url', 'http://astropy.org') + tox -e test -__minimum_python_version__ = metadata.get("minimum_python_version", "3.6") +If you don't already have tox installed, you can install it with: + pip install tox -# 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: packagename requires Python {} or later\n".format(__minimum_python_version__)) +If you only want to run part of the test suite, you can also use pytest +directly with:: + + pip install -e .[test] + pytest + +For more information, see: + + http://docs.astropy.org/en/latest/development/testguide.html#running-tests +""" + +if 'test' in sys.argv: + print(TEST_HELP) sys.exit(1) -# Import ah_bootstrap after the python version validation +DOCS_HELP = """ +Note: building the documentation is no longer done using +'python setup.py build_docs'. Instead you will need to run: -import ah_bootstrap -from setuptools import setup + tox -e build_docs -import builtins -builtins._ASTROPY_SETUP_ = True - -from astropy_helpers.setup_helpers import (register_commands, get_debug_option, - get_package_info) -from astropy_helpers.git_helpers import get_git_devstr -from astropy_helpers.version_helpers import generate_version_py - - -# order of priority for long_description: -# (1) set in setup.cfg, -# (2) load LONG_DESCRIPTION.rst, -# (3) load README.rst, -# (4) package docstring -readme_glob = 'README*' -_cfg_long_description = metadata.get('long_description', '') -if _cfg_long_description: - LONG_DESCRIPTION = _cfg_long_description - -elif os.path.exists('LONG_DESCRIPTION.rst'): - with open('LONG_DESCRIPTION.rst') as f: - LONG_DESCRIPTION = f.read() - -elif len(glob.glob(readme_glob)) > 0: - with open(glob.glob(readme_glob)[0]) as f: - LONG_DESCRIPTION = f.read() - -else: - # Get the long description from the package's docstring - __import__(PACKAGENAME) - package = sys.modules[PACKAGENAME] - LONG_DESCRIPTION = package.__doc__ - -# Store the package name in a built-in variable so it's easy -# to get from other parts of the setup infrastructure -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') - -# Indicates if this version is a release version -RELEASE = 'dev' not in VERSION - -if not RELEASE: - VERSION += get_git_devstr(False) - -# Populate the dict of setup command overrides; this should be done before -# invoking any other functionality from distutils since it can potentially -# modify distutils' behavior. -cmdclassd = register_commands(PACKAGENAME, VERSION, RELEASE) - -# Freeze build information in version.py -generate_version_py() - -# Treat everything in scripts except README* as a script to be installed -scripts = [fname for fname in glob.glob(os.path.join('scripts', '*')) - if not os.path.basename(fname).startswith('README')] - - -# Get configuration information from all of the various subpackages. -# See the docstring for setup_helpers.update_package_files for more -# details. -package_info = get_package_info() - -# Add the project-global data -package_info['package_data'].setdefault(PACKAGENAME, []) -package_info['package_data'][PACKAGENAME].append('data/*') - -# Define entry points for saba -entry_points = {'console_scripts': [], 'astropy.modeling': []} - - -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])) - -saba_entry_point_list = conf.items('saba_entry_points') -for saba_entry_point in saba_entry_point_list: - entry_points['astropy.modeling'].append('{0} = {1}'.format( - saba_entry_point[0], - saba_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" -# directory name. -c_files = [] -for root, dirs, files in os.walk(PACKAGENAME): - for filename in files: - if filename.endswith('.c'): - c_files.append( - os.path.join( - os.path.relpath(root, PACKAGENAME), filename)) -package_info['package_data'][PACKAGENAME].extend(c_files) - -# Note that requires and provides should not be included in the call to -# ``setup``, since these are now deprecated. See this link for more details: -# https://groups.google.com/forum/#!topic/astropy-dev/urYO8ckB2uM - -setup(name=PACKAGENAME, - version=VERSION, - description=DESCRIPTION, - scripts=scripts, - install_requires=[s.strip() for s in metadata.get('install_requires', 'astropy').split(',')], - author=AUTHOR, - author_email=AUTHOR_EMAIL, - license=LICENSE, - url=URL, - long_description=LONG_DESCRIPTION, - cmdclass=cmdclassd, - zip_safe=False, - entry_points=entry_points, - python_requires='>={}'.format(__minimum_python_version__), - **package_info -) +If you don't already have tox installed, you can install it with: + + pip install tox + +You can also build the documentation with Sphinx directly using:: + + pip install -e .[docs] + cd docs + make html + +For more information, see: + + http://docs.astropy.org/en/latest/install.html#builddocs +""" + +if 'build_docs' in sys.argv or 'build_sphinx' in sys.argv: + print(DOCS_HELP) + sys.exit(1) + +VERSION_TEMPLATE = """ +# Note that we need to fall back to the hard-coded version if either +# setuptools_scm can't be imported or setuptools_scm can't determine the +# version, so we catch the generic 'Exception'. +try: + from setuptools_scm import get_version + version = get_version(root='..', relative_to=__file__) +except Exception: + version = '{version}' +""".lstrip() + +setup(use_scm_version={'write_to': os.path.join('saba', 'version.py'), + 'write_to_template': VERSION_TEMPLATE}) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..459ca6b --- /dev/null +++ b/tox.ini @@ -0,0 +1,88 @@ +[tox] +envlist = + py{36,37,38}-test{,-alldeps,-devdeps}{,-cov} + py{36,37,38}-test-numpy{116,117,118} + py{36,37,38}-test-astropy{30,40,lts} + build_docs + codestyle +requires = + setuptools >= 30.3.0 + pip >= 19.3.1 +isolated_build = true + +[testenv] + +# Pass through the following environment variables which may be needed for the CI +passenv = HOME WINDIR LC_ALL LC_CTYPE CC CI TRAVIS + +# Run the tests in a temporary directory to make sure that we don't import +# this package from the source tree +changedir = .tmp/{envname} + +# tox environments are constructed with so-called 'factors' (or terms) +# separated by hyphens, e.g. test-devdeps-cov. Lines below starting with factor: +# will only take effect if that factor is included in the environment name. To +# see a list of example environments that can be run, along with a description, +# run: +# +# tox -l -v +# +description = + run tests + alldeps: with all optional dependencies + devdeps: with the latest developer version of key dependencies + oldestdeps: with the oldest supported version of key dependencies + cov: and test coverage + numpy116: with numpy 1.16.* + numpy117: with numpy 1.17.* + numpy118: with numpy 1.18.* + astropy30: with astropy 3.0.* + astropy40: with astropy 4.0.* + astropylts: with the latest astropy LTS + +# The following provides some specific pinnings for key packages +deps = + + numpy116: numpy==1.16.* + numpy117: numpy==1.17.* + numpy118: numpy==1.18.* + + astropy30: astropy==3.0.* + astropy40: astropy==4.0.* + astropylts: astropy==4.0.* + + devdeps: git+https://github.com/numpy/numpy.git#egg=numpy + devdeps: git+https://github.com/astropy/astropy.git#egg=astropy + +# The following indicates which extras_require from setup.cfg will be installed +extras = + test + alldeps: all + +commands = + pip freeze + !cov: pytest --pyargs saba {toxinidir}/docs {posargs} + cov: pytest --pyargs saba {toxinidir}/docs --cov saba --cov-config={toxinidir}/setup.cfg {posargs} + +[testenv:build_docs] +changedir = docs +description = invoke sphinx-build to build the HTML docs +extras = docs +commands = + pip freeze + sphinx-build -W -b html . _build/html + +[testenv:linkcheck] +changedir = docs +description = check the links in the HTML docs +extras = docs +commands = + pip freeze + sphinx-build -W -b linkcheck . _build/html + +[testenv:codestyle] +skip_install = true +changedir = . +description = check code style, e.g. with flake8 +deps = flake8 +commands = flake8 saba --count --max-line-length=100 From efd269bf3d32f87b8b5b4ef71b87a7f0afdd9146 Mon Sep 17 00:00:00 2001 From: hamogu Date: Mon, 2 Mar 2020 13:59:00 -0500 Subject: [PATCH 4/6] update readthedocs settings --- .readthedocs.yml | 15 +++++++++++---- pip-requirements | 7 ------- readthedocs.yml | 10 ---------- 3 files changed, 11 insertions(+), 21 deletions(-) delete mode 100644 pip-requirements delete mode 100644 readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml index 7e12b4a..91be621 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,8 +1,15 @@ -conda: - file: .rtd-environment.yml +version: 2 + +build: + image: latest python: - setup_py_install: true + version: 3.7 + install: + - method: pip + path: . + extra_requirements: + - docs + - all -# Don't build any extra formats formats: [] diff --git a/pip-requirements b/pip-requirements deleted file mode 100644 index 9403fa4..0000000 --- a/pip-requirements +++ /dev/null @@ -1,7 +0,0 @@ -numpy -cython -jinja2 -Sphinx -Graphviz -Pillow --e git+https://github.com/astropy/astropy.git#egg=astropy diff --git a/readthedocs.yml b/readthedocs.yml deleted file mode 100644 index 7649086..0000000 --- a/readthedocs.yml +++ /dev/null @@ -1,10 +0,0 @@ - -conda: - file: .rtd-environment.yml - -python: - setup_py_install: true - -formats: -- none - From 3137b0aa564d6c5cd87ed813a3b3c2042c23306b Mon Sep 17 00:00:00 2001 From: Moritz Guenther Date: Sun, 12 Apr 2020 22:11:46 -0400 Subject: [PATCH 5/6] Fix order of dependency installation within tox --- docs/conf.py | 2 +- tox.ini | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 2270281..39ae424 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -146,7 +146,7 @@ 'css_files': ['_static/saba.css'], } -intersphinx_mapping['sherpa'] = ('http://sherpa.readthedocs.io/en/stable/', None) +intersphinx_mapping['sherpa'] = ('http://sherpa.readthedocs.io/en/latest/', None) # -- Options for LaTeX output ------------------------------------------------- diff --git a/tox.ini b/tox.ini index 459ca6b..e454bc3 100644 --- a/tox.ini +++ b/tox.ini @@ -41,8 +41,16 @@ description = astropylts: with the latest astropy LTS # The following provides some specific pinnings for key packages + +# Sherpa will only install if numpy is already installed, but it does not have a +# pyproject.toml that specifies this as of April 2020. +# Thus, we need to make sure that ome version of numpy is installed before tox +# installs all the saba dependencies. +# Everything in "deps" will be installed first. We pin numpy for a few environments +# and request numpy (any version) for all those that don't pin an explicit version. deps = + !numpy116-!numpy117-!numpy118: numpy numpy116: numpy==1.16.* numpy117: numpy==1.17.* numpy118: numpy==1.18.* From 084ddccc2486111afc0dcf8e814673a0e0973555 Mon Sep 17 00:00:00 2001 From: Moritz Guenther Date: Mon, 13 Apr 2020 16:58:11 -0400 Subject: [PATCH 6/6] Fix errors in doc build setup --- docs/conf.py | 1 - setup.cfg | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 39ae424..168a352 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -62,7 +62,6 @@ # This is added to the end of RST files - a good place to put substitutions to # be used globally. rst_epilog += """ -.. _astropy: http://www.astropy.org/ .. _matplotlib: http://matplotlib.org/ .. _Sherpa: http://cxc.cfa.harvard.edu/contrib/sherpa/ """ diff --git a/setup.cfg b/setup.cfg index 4abc4c6..9e021d6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,6 +26,7 @@ test = pytest-astropy docs = sphinx-astropy + matplotlib [tool:pytest] testpaths = "saba" "docs"