From f341a0a8a358d047760f9ac65f7347f09a2c6c96 Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Mon, 29 Jan 2024 12:28:55 +0100 Subject: [PATCH] chore: migrate to pytest-doctestplus (#416) * chore: migrate to pytest-doctestplus * Add nox as a dev dependency * Skip numba modules on python 3.12 * Don't import numba on Python 3.12 * Separate job for doctests * Better name --- .github/CONTRIBUTING.md | 6 +++--- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/ci.yml | 12 ++++++++++-- noxfile.py | 2 +- pyproject.toml | 6 ++++-- src/vector/backends/awkward.py | 6 ++---- src/vector/backends/numpy.py | 18 +++++++++--------- src/vector/backends/object.py | 1 + 8 files changed, 31 insertions(+), 22 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b533f620..313bbcd2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -94,7 +94,7 @@ If you would like to skip the failing checks and push the code for further discu ## Testing vector -`vector` is tested using `pytest` and `xdoctest`. `pytest` is responsible for testing the code, whose configuration is available in [pyproject.toml](https://github.com/scikit-hep/vector/blob/main/pyproject.toml).`xdoctest` is responsible for testing the examples available in every docstring, which prevents them from going stale. Additionally, `vector` also uses `pytest-cov` to calculate the coverage of these unit tests. +`vector` is tested using `pytest` and `pytest-doctestplus`. `pytest` is responsible for testing the code, whose configuration is available in [pyproject.toml](https://github.com/scikit-hep/vector/blob/main/pyproject.toml).`pytest-doctestplus` is responsible for testing the examples available in every docstring, which prevents them from going stale. Additionally, `vector` also uses `pytest-cov` to calculate the coverage of these unit tests. ### Running tests locally @@ -119,13 +119,13 @@ python -m pytest --cov=vector tests/ The doctests can be executed using the `test` dependencies of `vector` in the following way - ```bash -xdoctest ./src/vector/ +python -m pytest --doctest-plus src/vector/ ``` or, one can run the doctests along with the unit tests in the following way - ```bash -python -m pytest --xdoctest . +python -m pytest --doctest-plus . ``` A much more detailed guide on testing with `pytest` for `Scikit-HEP` packages is available [here](https://scikit-hep.org/developer/pytest). diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 498ebce3..c59d4da2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,7 +11,7 @@ _Please describe the purpose of this pull request. Reference and link to any rel - [ ] Does your submission pass pre-commit? (`$ pre-commit run --all-files` or `$ nox -s lint`) - [ ] Does your submission pass tests? (`$ pytest` or `$ nox -s tests`) - [ ] Does the documentation build with your changes? (`$ cd docs; make clean; make html` or `$ nox -s docs`) -- [ ] Does your submission pass the doctests? (`$ xdoctest ./src/vector` or `$ nox -s doctests`) +- [ ] Does your submission pass the doctests? (`$ pytest --doctest-plus src/vector/` or `$ nox -s doctests`) ## Before Merging diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 276f8012..51e73912 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,8 +86,12 @@ jobs: - name: Install awkward v1 run: python -m pip install -U "awkward<2" + - name: Run doctests on Python 3.11 with awkward v1.x + if: matrix.python-version == '3.11' + run: python -m pytest -ra --doctest-plus src/vector/ + - name: Test package with awkward v1.x - run: python -m pytest -ra --cov=vector --xdoctest --ignore tests/test_notebooks.py . + run: python -m pytest -ra --cov=vector --ignore tests/test_notebooks.py . check-awkward-v2: needs: [check-light] @@ -118,8 +122,12 @@ jobs: - name: Install awkward v2 run: python -m pip install -U --pre "awkward>=2.0.0rc1" + - name: Run doctests on Python 3.11 with awkward v2.x + if: matrix.python-version == 3.11 + run: python -m pytest -ra --doctest-plus src/vector/ + - name: Test package with awkward v2.x - run: python -m pytest -ra --cov=vector --xdoctest --ignore tests/test_notebooks.py . + run: python -m pytest -ra --cov=vector --ignore tests/test_notebooks.py . - name: Upload coverage report uses: codecov/codecov-action@v3.1.4 diff --git a/noxfile.py b/noxfile.py index 8cd3d09a..cb268151 100644 --- a/noxfile.py +++ b/noxfile.py @@ -45,7 +45,7 @@ def coverage(session: nox.Session) -> None: def doctests(session: nox.Session) -> None: """Run the doctests.""" session.install("-e", ".[awkward,test,test-extras]") - session.run("xdoctest", "./src/vector/", *session.posargs) + session.run("pytest", "--doctest-plus", "src/vector/", *session.posargs) @nox.session(python=ALL_PYTHONS, reuse_venv=True) diff --git a/pyproject.toml b/pyproject.toml index 7eb7603d..7e8c8c5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,11 +47,12 @@ awkward = [ ] dev = [ "awkward>=1.2", + "nox", 'numba>=0.57; python_version < "3.12"', "papermill>=2.4", "pytest>=6", "pytest-cov>=3", - "xdoctest>=1", + "pytest-doctestplus", ] docs = [ "awkward>=1.2", @@ -64,10 +65,11 @@ docs = [ "sphinx_copybutton", ] test = [ + "nox", "papermill>=2.4", "pytest>=6", "pytest-cov>=3", - "xdoctest>=1", + "pytest-doctestplus", ] test-extras = [ "spark-parser", diff --git a/src/vector/backends/awkward.py b/src/vector/backends/awkward.py index d1817744..4b50f0a1 100644 --- a/src/vector/backends/awkward.py +++ b/src/vector/backends/awkward.py @@ -122,8 +122,7 @@ def from_fields(cls, array: ak.Array) -> AzimuthalAwkward: >>> az AzimuthalAwkwardXY(, ) >>> az.elements - (, ) + (, ) """ fields = ak.fields(array) if "x" in fields and "y" in fields: @@ -151,8 +150,7 @@ def from_momentum_fields(cls, array: ak.Array) -> AzimuthalAwkward: >>> az AzimuthalAwkwardXY(, ) >>> az.elements - (, ) + (, ) """ fields = ak.fields(array) if "x" in fields and "y" in fields: diff --git a/src/vector/backends/numpy.py b/src/vector/backends/numpy.py index f0538495..a2a9819a 100644 --- a/src/vector/backends/numpy.py +++ b/src/vector/backends/numpy.py @@ -426,7 +426,7 @@ class AzimuthalNumpyXY(AzimuthalNumpy, AzimuthalXY, GetItem, FloatArray): # typ >>> import vector >>> vector.backends.numpy.AzimuthalNumpyXY([(1, 1), (2.1, 3.1)], dtype=[("x", float), ("y", float)]) AzimuthalNumpyXY([(1. , 1. ), (2.1, 3.1)], - dtype=[('x', '>> import vector >>> vector.backends.numpy.AzimuthalNumpyRhoPhi([(1, 1), (2.1, 3.1)], dtype=[("rho", float), ("phi", float)]) AzimuthalNumpyRhoPhi([(1. , 1. ), (2.1, 3.1)], - dtype=[('rho', '>> vec VectorNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)], - dtype=[('x', ' AzimuthalNumpy: ... ], dtype=[("x", float), ("y", float)]) >>> vec.azimuthal AzimuthalNumpyXY([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), - (1.5, 2.5)], dtype=[('x', '>> vec VectorNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4), - (1.5, 2.5, 3.5)], dtype=[('x', '>> vec MomentumNumpy3D([(1.1, 2.1, 3.1), (1.2, 2.2, 3.2), (1.3, 2.3, 3.3), (1.4, 2.4, 3.4), - (1.5, 2.5, 3.5)], dtype=[('x', '>> vec VectorNumpy4D([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3), - (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)], - dtype=[('x', '>> vec MomentumNumpy4D([(1.1, 2.1, 3.1, 4.1), (1.2, 2.2, 3.2, 4.2), (1.3, 2.3, 3.3, 4.3), - (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)], + (1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)], dtype=[('x', '>> vec.x, vec.y, vec.theta + (1, 2, 3) The following class methods can also be used to