diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000..65dd95ba48 --- /dev/null +++ b/.flake8 @@ -0,0 +1,6 @@ +[flake8] +# E203: whitespace before ':' +# E402: module level import not at top of file +# E501: line too long +extend-ignore = E203, E402, E501 +max-line-length = 88 diff --git a/.github/ISSUE_TEMPLATE/~release-checklist.md b/.github/ISSUE_TEMPLATE/~release-checklist.md index 5567cbcf7a..12de456ab8 100644 --- a/.github/ISSUE_TEMPLATE/~release-checklist.md +++ b/.github/ISSUE_TEMPLATE/~release-checklist.md @@ -32,7 +32,7 @@ about: Checklist for core developers to complete as part of making a release * [ ] Verify that a Binder has properly built for the new release. * [ ] Watch for a GitHub notification that there is an automatic PR to the [Conda-forge feedstock](https://github.com/conda-forge/pyhf-feedstock). This may take multiple hours to happen. If there are any changes needed to the Conda-forge release make them **from a personal account** and not from an organization account to have workflows properly trigger. - [ ] Check if any requirements need to be updated by commenting "@conda-grayskull show requirements" on the PR. - - [ ] Verify the requirements in the [Conda-forge feedstock](https://github.com/conda-forge/pyhf-feedstock) recipe `meta.yaml` match those in `setup.cfg` and `pyproject.toml`. + - [ ] Verify the requirements in the [Conda-forge feedstock](https://github.com/conda-forge/pyhf-feedstock) recipe `meta.yaml` match those in `pyproject.toml`. ## After Release diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 6266de94c5..1433ad7fee 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -37,16 +37,12 @@ jobs: with: python-version: '3.10' - - name: Install python-build, check-manifest, and twine + - name: Install python-build and twine run: | - python -m pip install --upgrade pip setuptools wheel - python -m pip install build check-manifest twine + python -m pip install --upgrade pip + python -m pip install build twine python -m pip list - - name: Check MANIFEST - run: | - check-manifest - - name: Build a wheel and a sdist run: | PYTHONWARNINGS=error,default::DeprecationWarning python -m build . diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index e5af33dbdc..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,13 +0,0 @@ -prune ** -graft src -exclude src/conftest.py - -include setup.py -include setup.cfg -include LICENSE -include README.rst -include pyproject.toml -include MANIFEST.in -include AUTHORS - -global-exclude __pycache__ *.py[cod] diff --git a/pyproject.toml b/pyproject.toml index 07e289515f..a0b4bc34cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,149 @@ [build-system] -# Minimum requirements for the build system to execute. -requires = ["setuptools>=61.0.0", "setuptools_scm>=7.0.1"] -build-backend = "setuptools.build_meta" +requires = ["hatchling>=1.0.0", "hatch-vcs"] +build-backend = "hatchling.build" -[tool.setuptools_scm] -write_to = "src/pyhf/_version.py" +[project] +name = "pyhf" +dynamic = ["version"] +description = "pure-Python HistFactory implementation with tensors and autodiff" +readme = "README.rst" +license = { text = "Apache-2.0" } # SPDX short identifier +requires-python = ">=3.8" +authors = [ + { name = "Lukas Heinrich", email = "lukas.heinrich@cern.ch" }, + { name = "Matthew Feickert", email = "matthew.feickert@cern.ch" }, + { name = "Giordon Stark", email = "gstark@cern.ch" }, +] +maintainers = [ {name = "The Scikit-HEP admins", email = "scikit-hep-admins@googlegroups.com"} ] +keywords = [ + "fitting", + "jax", + "numpy", + "physics", + "pytorch", + "scipy", + "tensorflow", +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Physics", +] +dependencies = [ + "click>=8.0.0", # for console scripts + "importlib_resources>=1.4.0; python_version < '3.9'", # for resources in schema + "jsonpatch>=1.15", + "jsonschema>=4.15.0", # for utils + "pyyaml>=5.1", # for parsing CLI equal-delimited options + "scipy>=1.5.1", # requires numpy, which is required by pyhf and tensorflow + "tqdm>=4.56.0", # for readxml + "numpy", # compatible versions controlled through scipy +] + +[project.scripts] +pyhf = "pyhf.cli:cli" + +[project.urls] +Documentation = "https://pyhf.readthedocs.io/" +Homepage = "https://github.com/scikit-hep/pyhf" +"Issue Tracker" = "https://github.com/scikit-hep/pyhf/issues" +"Release Notes" = "https://pyhf.readthedocs.io/en/stable/release-notes.html" +"Source Code" = "https://github.com/scikit-hep/pyhf" + +[project.optional-dependencies] +shellcomplete = ["click_completion"] +tensorflow = [ + "tensorflow>=2.7.0", # c.f. PR #1962 + "tensorflow-probability>=0.11.0", # c.f. PR #1657 +] +torch = ["torch>=1.10.0"] # c.f. PR #1657 +jax = [ + "jax>=0.4.1", # c.f. PR #2079 + "jaxlib>=0.4.1", # c.f. PR #2079 +] +xmlio = ["uproot>=4.1.1"] # c.f. PR #1567 +minuit = ["iminuit>=2.7.0"] # c.f. PR #1895 +contrib = [ + "matplotlib>=3.0.0", + "requests>=2.22.0", +] +backends = ["pyhf[tensorflow,torch,jax,minuit]"] +all = ["pyhf[backends,xmlio,contrib,shellcomplete]"] + +# Developer extras +test = [ + "pyhf[all]", + "scikit-hep-testdata>=0.4.11", + "pytest>=6.0", + "coverage[toml]>=6.0.0", + "pytest-mock", + "requests-mock>=1.9.0", + "pytest-benchmark[histogram]", + "pytest-console-scripts", + "pytest-mpl", + "pydocstyle", + "papermill~=2.3.4", + "scrapbook~=0.5.0", + "jupyter", + "graphviz", + "pytest-socket>=0.2.0", # c.f. PR #1917 +] +docs = [ + "pyhf[xmlio,contrib]", + "sphinx>=5.1.1", # c.f. https://github.com/scikit-hep/pyhf/pull/1926 + "sphinxcontrib-bibtex~=2.1", + "sphinx-click", + "sphinx_rtd_theme", + "nbsphinx!=0.8.8", # c.f. https://github.com/spatialaudio/nbsphinx/issues/620 + "ipywidgets", + "sphinx-issues", + "sphinx-copybutton>=0.3.2", + "sphinx-togglebutton>=0.3.0", + "ipython!=8.7.0", # c.f. https://github.com/scikit-hep/pyhf/pull/2068 +] +develop = [ + "pyhf[test,docs]", + "tbump>=6.7.0", + "pre-commit", + "nox", + "codemetapy>=2.3.0", +] + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.version.raw-options] local_scheme = "no-local-version" +[tool.hatch.build.hooks.vcs] +version-file = "src/pyhf/_version.py" + +[tool.hatch.build.targets.sdist] +# only-include needed to properly include src/pyhf/schemas +# c.f. https://github.com/pypa/hatch/pull/299 +only-include = [ + "/src", + "/LICENSE", + "/README.rst", + "/pyproject.toml", + "/AUTHORS", + "/CITATION.cff" +] +exclude = [ + "/src/conftest.py" +] + +[tool.hatch.build.targets.wheel] +packages = ["src/pyhf"] + [tool.black] line-length = 88 target-version = ['py38', 'py39', 'py310'] @@ -21,24 +158,6 @@ exclude = ''' )/ ''' -[tool.check-manifest] -ignore = [ - 'docs*', - 'validation*', - 'examples*', - 'tests*', - 'docker*', - 'binder*', - '.*', - 'pyproject.toml', - 'pytest.ini', - 'codecov.yml', - 'codemeta.json', - 'CODE_OF_CONDUCT.md', - 'CONTRIBUTING.md', - 'AUTHORS', -] - [tool.pytest.ini_options] minversion = "6.0" xfail_strict = true diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index f48dda4ff3..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,58 +0,0 @@ -[metadata] -name = pyhf -description = pure-Python HistFactory implementation with tensors and autodiff -long_description = file: README.rst -long_description_content_type = text/x-rst -url = https://github.com/scikit-hep/pyhf -author = Lukas Heinrich, Matthew Feickert, Giordon Stark -author_email = lukas.heinrich@cern.ch, matthew.feickert@cern.ch, gstark@cern.ch -license = Apache -license_files = LICENSE -keywords = physics fitting numpy scipy tensorflow pytorch jax -project_urls = - Documentation = https://pyhf.readthedocs.io/ - Source Code = https://github.com/scikit-hep/pyhf - Issue Tracker = https://github.com/scikit-hep/pyhf/issues - Release Notes = https://pyhf.readthedocs.io/en/stable/release-notes.html -classifiers = - Development Status :: 4 - Beta - License :: OSI Approved :: Apache Software License - Intended Audience :: Science/Research - Topic :: Scientific/Engineering - Topic :: Scientific/Engineering :: Physics - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: Implementation :: CPython - -[options] -packages = find_namespace: -package_dir = - = src -include_package_data = True -python_requires = >=3.8 -install_requires = - scipy>=1.5.1 # requires numpy, which is required by pyhf and tensorflow - click>=8.0.0 # for console scripts - tqdm>=4.56.0 # for readxml - jsonschema>=4.15.0 # for utils - jsonpatch>=1.15 - pyyaml>=5.1 # for parsing CLI equal-delimited options - importlib_resources>=1.4.0; python_version < "3.9" # for resources in schema - numpy # compatible versions controlled through scipy - -[options.packages.find] -where = src - -[options.entry_points] -console_scripts = - pyhf = pyhf.cli:cli - -[flake8] -# E203: whitespace before ':' -# E402: module level import not at top of file -# E501: line too long -extend-ignore = E203, E402, E501 -max-line-length = 88 diff --git a/setup.py b/setup.py deleted file mode 100644 index f7d97fd6fe..0000000000 --- a/setup.py +++ /dev/null @@ -1,87 +0,0 @@ -from setuptools import setup - -extras_require = { - 'shellcomplete': ['click_completion'], - 'tensorflow': [ - 'tensorflow>=2.7.0', # c.f. PR #1962 - 'tensorflow-probability>=0.11.0', # c.f. PR #1657 - ], - 'torch': ['torch>=1.10.0'], # c.f. PR #1657 - 'jax': ['jax>=0.4.1', 'jaxlib>=0.4.1'], # c.f. PR #2079 - 'xmlio': ['uproot>=4.1.1'], # c.f. PR #1567 - 'minuit': ['iminuit>=2.7.0'], # c.f. PR #1895 -} -extras_require['backends'] = sorted( - set( - extras_require['tensorflow'] - + extras_require['torch'] - + extras_require['jax'] - + extras_require['minuit'] - ) -) -extras_require['contrib'] = sorted({'matplotlib', 'requests'}) -extras_require['test'] = sorted( - set( - extras_require['backends'] - + extras_require['xmlio'] - + extras_require['contrib'] - + extras_require['shellcomplete'] - + [ - 'scikit-hep-testdata>=0.4.11', - 'pytest>=6.0', - 'coverage[toml]>=6.0.0', - 'pytest-mock', - 'requests-mock>=1.9.0', - 'pytest-benchmark[histogram]', - 'pytest-console-scripts', - 'pytest-mpl', - 'pydocstyle', - 'papermill~=2.3.4', - 'scrapbook~=0.5.0', - 'jupyter', - 'graphviz', - 'pytest-socket>=0.2.0', # c.f. PR #1917 - ] - ) -) -extras_require['docs'] = sorted( - set( - extras_require['xmlio'] - + extras_require['contrib'] - + [ - 'sphinx>=5.1.1', # c.f. https://github.com/scikit-hep/pyhf/pull/1926 - 'sphinxcontrib-bibtex~=2.1', - 'sphinx-click', - 'sphinx_rtd_theme', - 'nbsphinx!=0.8.8', # c.f. https://github.com/spatialaudio/nbsphinx/issues/620 - 'ipywidgets', - 'sphinx-issues', - 'sphinx-copybutton>=0.3.2', - 'sphinx-togglebutton>=0.3.0', - 'ipython!=8.7.0', # c.f. https://github.com/scikit-hep/pyhf/pull/2068 - ] - ) -) -extras_require['develop'] = sorted( - set( - extras_require['docs'] - + extras_require['test'] - + [ - 'nbdime', - 'tbump>=6.7.0', - 'ipython', - 'pre-commit', - 'nox', - 'check-manifest', - 'codemetapy>=2.3.0', - 'twine', - ] - ) -) -extras_require['complete'] = sorted(set(sum(extras_require.values(), []))) - - -setup( - extras_require=extras_require, - use_scm_version=lambda: {'local_scheme': lambda version: ''}, -)