diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ead459d..126376e 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -31,10 +31,11 @@ jobs: - uses: hynek/build-and-inspect-python-package@v2 - publish: + test-publish: needs: [dist] - name: Publish to PyPI - environment: pypi + name: Publish to TestPyPI + environment: + name: testpypi permissions: id-token: write runs-on: ubuntu-latest @@ -49,6 +50,21 @@ jobs: - uses: pypa/gh-action-pypi-publish@release/v1 if: github.event_name == 'release' && github.event.action == 'published' with: - # Remember to tell (test-)pypi about this repo before publishing - # Remove this line to publish to PyPI repository-url: https://test.pypi.org/legacy/ + + publish: + needs: [test-publish] + name: Publish to PyPI + environment: pypi + permissions: + id-token: write + runs-on: ubuntu-latest + if: github.event_name == 'release' && github.event.action == 'published' + + steps: + - uses: actions/download-artifact@v4 + with: + name: Packages + path: dist + + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..4a9f688 --- /dev/null +++ b/conftest.py @@ -0,0 +1,36 @@ +"""Doctest configuration.""" + +import platform +from doctest import ELLIPSIS, NORMALIZE_WHITESPACE +from importlib.util import find_spec + +from sybil import Sybil +from sybil.parsers.rest import DocTestParser, PythonCodeBlockParser, SkipParser + +# TODO: stop skipping doctests on Windows when there is uniform support for +# numpy 2.0+ scalar repr. On windows it is printed as 1.0 instead of +# `np.float64(1.0)`. +parsers = ( + [DocTestParser(optionflags=ELLIPSIS | NORMALIZE_WHITESPACE)] + if platform.system() != "Windows" + else [] +) + [ + PythonCodeBlockParser(), + SkipParser(), +] + +pytest_collect_file = Sybil( + parsers=parsers, + patterns=["*.rst", "*.py"], +).pytest() + + +# TODO: via separate optional_deps package +HAS_ASTROPY = find_spec("astropy") is not None +HAS_GALA = find_spec("gala") is not None + +collect_ignore_glob = [] +if not HAS_ASTROPY: + collect_ignore_glob.append("src/unxt/_interop/unxt_interop_astropy/*") +if not HAS_GALA: + collect_ignore_glob.append("src/unxt/_interop/unxt_interop_gala/*") diff --git a/pyproject.toml b/pyproject.toml index 8767966..ad90256 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,13 @@ "sphinx_autodoc_typehints", "sphinx_copybutton", ] - test = ["numpy", "pytest >=6", "pytest-cov >=3"] + test = [ + "numpy", + "pytest >=6", + "pytest-cov >=3", + "pytest-github-actions-annotate-failures", + "sybil", + ] [project.urls] "Bug Tracker" = "https://github.com/GalacticDynamics/zeroth/issues" @@ -59,12 +65,18 @@ [tool.pytest.ini_options] - addopts = ["--showlocals", "--strict-config", "--strict-markers", "-ra"] + addopts = [ + "--showlocals", + "--strict-config", + "--strict-markers", + "-p no:doctest", # using sybil + "-ra", + ] filterwarnings = ["error"] - log_cli_level = "INFO" - minversion = "6.0" - testpaths = ["tests"] - xfail_strict = true + log_cli_level = "INFO" + minversion = "6.0" + testpaths = ["tests/", "docs", "src/"] + xfail_strict = true [tool.coverage] @@ -93,9 +105,14 @@ [tool.ruff.lint] extend-select = ["ALL"] ignore = [ + "D203", # 1 blank line required before class docstring + "D213", # Multi-line docstring summary should start at the second line + "FIX002", # Line contains TODO, consider resolving the issue "ISC001", # Conflicts with formatter "PLR09", # Too many <...> "PLR2004", # Magic value used in comparison + "TD002", # Missing author in TODO + "TD003" # Missing issue link on the line following this TODO ] [tool.ruff.lint.per-file-ignores] diff --git a/src/zeroth/__init__.py b/src/zeroth/__init__.py index 23339a8..fa398aa 100644 --- a/src/zeroth/__init__.py +++ b/src/zeroth/__init__.py @@ -36,7 +36,7 @@ def zeroth(x: Iterable[T], /) -> T: '0' >>> import numpy as np - >>> zeroth(np.array([1, 2, 3])) + >>> int(zeroth(np.array([1, 2, 3]))) 1 >>> class ReverseIterable: