diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 374107ee..b6065ce7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine + pip install build twine - name: Check and get Version Number id: get_version @@ -39,7 +39,7 @@ jobs: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_JM }} run: | - python setup.py sdist bdist_wheel + python -m build twine upload dist/* - name: Create Draft Release diff --git a/doc/source/conf.py b/doc/source/conf.py index 07607375..b62f09d6 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -60,9 +60,9 @@ # built documents. # # The short X.Y version. -version = re.match(r"v?(\d+\.\d+)", snewpy._version.__version__).group(1) +version = re.match(r"v?(\d+\.\d+)", snewpy.__version__).group(1) # The full version, including alpha/beta/rc tags. -release = snewpy._version.__version__ +release = snewpy.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..18663d33 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["setuptools>=61"] +build-backend = "setuptools.build_meta" + +[project] +name = "snewpy" +dynamic = ["version"] +description = "A Python package for working with supernova neutrinos" +authors = [{ name = "SNEWS Collaboration", email = "snews2.0@lists.bnl.gov" }] +license = { text = "BSD" } +readme = {file = "README.md", content-type = "text/markdown"} + +requires-python = ">=3.9" + +dependencies = [ + "numpy", + "scipy", + "astropy >= 4.3", + "pandas", + "tqdm", + "matplotlib", + "h5py", + "requests", + "pyyaml", + "snowglobes_data == 1.3.2" +] + +[project.optional-dependencies] +dev = ["hypothesis", "pytest"] +docs = ["numpydoc"] + +[project.urls] +"Homepage" = "https://github.com/SNEWS2/snewpy" +"Bug Tracker" = "https://github.com/SNEWS2/snewpy/issues" + + +[tool.setuptools.dynamic] +version = {attr = "snewpy.__version__"} + +[tool.setuptools.packages.find] +where = ["python"] +include = [ + "snewpy", + "snewpy.*", +] +exclude = [ + "snewpy.scripts", +] + +[tool.setuptools.package-data] +"snewpy.models" = ["*.yml"] diff --git a/python/snewpy/__init__.py b/python/snewpy/__init__.py index 3c1f0106..62889f5f 100644 --- a/python/snewpy/__init__.py +++ b/python/snewpy/__init__.py @@ -7,7 +7,6 @@ Front-end for supernova models which provide neutrino luminosity and spectra. """ -from ._version import __version__ from sys import exit import os @@ -17,6 +16,10 @@ # when imported by setup.py before dependencies are installed get_cache_dir = lambda: '.' + +__version__ = '1.6b1' + + src_path = os.path.realpath(__path__[0]) base_path = os.sep.join(src_path.split(os.sep)[:-2]) model_path = os.path.join(get_cache_dir(), 'snewpy', 'models') diff --git a/python/snewpy/_git.py b/python/snewpy/_git.py deleted file mode 100644 index b855030d..00000000 --- a/python/snewpy/_git.py +++ /dev/null @@ -1,179 +0,0 @@ -# Git interaction code adapted from https://github.com/desihub/desiutil. -# The desiutil project is distributed under a 3-clause BSD style license: -# -# Copyright (c) 2014-2017, DESI Collaboration <desi-data@desi.lbl.gov> -# 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 DESI Collaboration 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. -# -"""Some code for interacting with git. -""" - -import re -from os.path import abspath, isdir, isfile, join -from setuptools import Command - - -def get_version(): - """Get the value of ``__version__`` without having to import the module. - - Returns - ------- - :class:`str` - The value of ``__version__``. - """ - ver = 'unknown' - try: - version_dir = find_version_directory() - except IOError: - return ver - version_file = join(version_dir, '_version.py') - if not isfile(version_file): - update_version() - with open(version_file, "r") as f: - for line in f.readlines(): - mo = re.match("__version__ = '(.*)'", line) - if mo: - ver = mo.group(1) - return ver - - -def get_git_version(git='git'): - """Use ``git describe`` to generate a version string. - - Parameters - ---------- - git : :class:`str`, optional - Path to the git executable, if not in :envvar:`PATH`. - - Returns - ------- - :class:`str` - A :pep:`386`-compatible version string. - - Notes - ----- - The version string should be compatible with :pep:`386` and - :pep:`440`. - """ - from subprocess import Popen, PIPE - myversion = '0.0.1.dev0' - try: - p = Popen([git, "describe", "--tags", "--dirty", "--always"], - universal_newlines=True, stdout=PIPE, stderr=PIPE) - except OSError: - return myversion - out, err = p.communicate() - if p.returncode != 0: - return myversion - ver = out.rstrip().split('-')[0]+'.dev' - try: - p = Popen([git, "rev-list", "--count", "HEAD"], - universal_newlines=True, stdout=PIPE, stderr=PIPE) - except OSError: - return myversion - out, err = p.communicate() - if p.returncode != 0: - return myversion - ver += out.rstrip() - return ver - - -def update_version(tag=None): - """Update the _version.py file. - - Parameters - ---------- - tag : :class:`str`, optional - Set the version to this string, unconditionally. - - Raises - ------ - IOError - If the repository type could not be determined. - """ - version_dir = find_version_directory() - if tag is not None: - ver = tag - else: - if isdir(".git"): - ver = get_git_version() - else: - raise IOError("Repository type is not git.") - version_file = join(version_dir, '_version.py') - with open(version_file, "w") as f: - f.write("__version__ = '{}'\n".format(ver)) - return - - -def find_version_directory(): - """Return the name of a directory containing version information. - - Looks for files in the following places: - - * python/snewpy/_version.py - * snewpy/_version.py - - Returns - ------- - :class:`str` - Name of a directory that can or does contain version information. - - Raises - ------ - IOError - If no valid directory can be found. - """ - packagename='snewpy' - setup_dir = abspath('.') - if isdir(join(setup_dir, 'python', packagename)): - version_dir = join(setup_dir, 'python', packagename) - elif isdir(join(setup_dir, packagename)): - version_dir = join(setup_dir, packagename) - else: - raise IOError("Could not find a directory containing version information!") - return version_dir - - -class SetVersion(Command): - """Allow users to easily update the package version with - ``python setup.py version``. - """ - description = "update _version.py from git repo" - user_options = [('tag=', 't', - 'Set the version to a name in preparation for tagging.'), - ] - boolean_options = [] - - def initialize_options(self): - self.tag = None - - def finalize_options(self): - pass - - def run(self): - update_version(tag=self.tag) - ver = get_version() - self.announce("Version is now {}.".format(ver), level=2) diff --git a/python/snewpy/_version.py b/python/snewpy/_version.py deleted file mode 100644 index a5f08e49..00000000 --- a/python/snewpy/_version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = '1.6b1' diff --git a/python/snewpy/test/__init__.py b/python/snewpy/test/__init__.py index b32ea693..e69de29b 100644 --- a/python/snewpy/test/__init__.py +++ b/python/snewpy/test/__init__.py @@ -1 +0,0 @@ -from .snewpy_test_suite import runtests diff --git a/python/snewpy/test/snewpy_test_suite.py b/python/snewpy/test/snewpy_test_suite.py deleted file mode 100644 index 70363511..00000000 --- a/python/snewpy/test/snewpy_test_suite.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest - -def snewpy_test_suite(): - """Returns unittest.TestSuite of desiutil tests. - - This is factored out separately from runtests() so that it can be used by - ``python setup.py test``. - """ - from os.path import dirname - pydir = dirname(dirname(__file__)) - tests = unittest.defaultTestLoader.discover(pydir, - top_level_dir=dirname(pydir)) - return tests - -def runtests(): - """Run all tests in snewpy.test.test_*. - """ - # Load all TestCase classes from snewpy/test/test_*.py - tests = snewpy_test_suite() - # Run them - unittest.TextTestRunner(verbosity=2).run(tests) - -if __name__ == "__main__": - runtests() diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 0c737aaa..00000000 --- a/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -numpy -scipy -astropy >=4.3 -pandas -tqdm -matplotlib -h5py -requests -pyyaml -snowglobes_data == 1.3.2 diff --git a/setup.py b/setup.py deleted file mode 100644 index 30bdf9de..00000000 --- a/setup.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# -# Licensed under a 3-clause BSD style license - see LICENSE.rst - -import os -from setuptools import setup, find_packages - -# Git-based version info. Remove? -from python.snewpy._git import get_version, SetVersion - -# -# Begin setup -# -setup_keywords = dict() -# -setup_keywords['name'] = 'snewpy' -setup_keywords['description'] = 'A Python package for working with supernova neutrinos' -setup_keywords['author'] = 'SNEWS Collaboration' -setup_keywords['author_email'] = 'snews2.0@lists.bnl.gov' -setup_keywords['license'] = 'BSD' -setup_keywords['url'] = 'https://github.com/SNEWS2/snewpy' -setup_keywords['version'] = get_version() -# -# Use README.md as a long_description. -# -setup_keywords['long_description'] = '' -if os.path.exists('README.md'): - with open('README.md') as readme: - setup_keywords['long_description'] = readme.read() - setup_keywords['long_description_content_type'] = 'text/markdown' -# -# Set other keywords for the setup function. -# -# Use entry_points to let `pip` create executable scripts for each target platform. -# See https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html -# setup_keywords['entry_points'] = {'console_scripts': ['to_snowglobes = snewpy.to_snowglobes:generate_time_series', ], }, -setup_keywords['provides'] = [setup_keywords['name']] -setup_keywords['python_requires'] = '>=3.9' -setup_keywords['zip_safe'] = False -setup_keywords['packages'] = find_packages('python') -setup_keywords['package_dir'] = {'': 'python'} -setup_keywords['package_data'] = {'':['templates/*.glb', 'models/*.yml']} -setup_keywords['cmdclass'] = {'version': SetVersion} -setup_keywords['test_suite']='snewpy.test.snewpy_test_suite.snewpy_test_suite' - -requires = [] -with open('requirements.txt', 'r') as f: - for line in f: - if line.strip(): - requires.append(line.strip()) -setup_keywords['install_requires'] = requires -setup_keywords['extras_require'] = { # Optional - 'dev': ['pytest','hypothesis'], - 'docs':['numpydoc'] -} -# -# Internal data directories. -# -#setup_keywords['data_files'] = [('snewpy/data/config', glob('data/config/*')), -# ('snewpy/data/spectra', glob('data/spectra/*'))] -# -# Run setup command. -# -setup(**setup_keywords)