Skip to content

Commit

Permalink
chore: migrate to pytest-doctestplus (#416)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Saransh-cpp committed Jan 29, 2024
1 parent ab111e0 commit f341a0a
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 22 deletions.
6 changes: 3 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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).
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
6 changes: 2 additions & 4 deletions src/vector/backends/awkward.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ def from_fields(cls, array: ak.Array) -> AzimuthalAwkward:
>>> az
AzimuthalAwkwardXY(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var * int64]'>)
>>> az.elements
(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var
* int64]'>)
(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var * int64]'>)
"""
fields = ak.fields(array)
if "x" in fields and "y" in fields:
Expand Down Expand Up @@ -151,8 +150,7 @@ def from_momentum_fields(cls, array: ak.Array) -> AzimuthalAwkward:
>>> az
AzimuthalAwkwardXY(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var * int64]'>)
>>> az.elements
(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var
* int64]'>)
(<Array [[1, 2], None] type='2 * option[var * int64]'>, <Array [None, [1]] type='2 * option[var * int64]'>)
"""
fields = ak.fields(array)
if "x" in fields and "y" in fields:
Expand Down
18 changes: 9 additions & 9 deletions src/vector/backends/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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', '<f8'), ('y', '<f8')])
dtype=[('x', '<f8'), ('y', '<f8')])
"""

ObjectClass = vector.backends.object.AzimuthalObjectXY
Expand Down Expand Up @@ -477,7 +477,7 @@ class AzimuthalNumpyRhoPhi(AzimuthalNumpy, AzimuthalRhoPhi, GetItem, FloatArray)
>>> 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', '<f8'), ('phi', '<f8')])
dtype=[('rho', '<f8'), ('phi', '<f8')])
"""

ObjectClass = vector.backends.object.AzimuthalObjectRhoPhi
Expand Down Expand Up @@ -1036,7 +1036,7 @@ class VectorNumpy2D(VectorNumpy, Planar, Vector2D, FloatArray): # type: ignore[
... dtype=[('x', float), ('y', float)])
>>> vec
VectorNumpy2D([(1.1, 2.1), (1.2, 2.2), (1.3, 2.3), (1.4, 2.4), (1.5, 2.5)],
dtype=[('x', '<f8'), ('y', '<f8')])
dtype=[('x', '<f8'), ('y', '<f8')])
"""

ObjectClass = vector.backends.object.VectorObject2D
Expand Down Expand Up @@ -1088,7 +1088,7 @@ def azimuthal(self) -> 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', '<f8'), ('y', '<f8')])
(1.5, 2.5)], dtype=[('x', '<f8'), ('y', '<f8')])
"""
return self.view(self._azimuthal_type) # type: ignore[return-value]

Expand Down Expand Up @@ -1259,7 +1259,7 @@ class VectorNumpy3D(VectorNumpy, Spatial, Vector3D, FloatArray): # type: ignore
... dtype=[('x', float), ('y', float), ('z', float)])
>>> 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', '<f8'), ('y', '<f8'), ('z', '<f8')])
(1.5, 2.5, 3.5)], dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
"""

ObjectClass = vector.backends.object.VectorObject3D
Expand Down Expand Up @@ -1465,7 +1465,7 @@ class MomentumNumpy3D(SpatialMomentum, VectorNumpy3D): # type: ignore[misc]
... dtype=[('px', float), ('py', float), ('pz', float)])
>>> 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', '<f8'), ('y', '<f8'), ('z', '<f8')])
(1.5, 2.5, 3.5)], dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
"""

ObjectClass = vector.backends.object.MomentumObject3D
Expand Down Expand Up @@ -1524,8 +1524,8 @@ class VectorNumpy4D(VectorNumpy, Lorentz, Vector4D, FloatArray): # type: ignore
... dtype=[('x', float), ('y', float), ('z', float), ('t', float)])
>>> 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', '<f8'), ('y', '<f8'), ('z', '<f8'), ('t', '<f8')])
(1.4, 2.4, 3.4, 4.4), (1.5, 2.5, 3.5, 4.5)],
dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8'), ('t', '<f8')])
"""

ObjectClass = vector.backends.object.VectorObject4D
Expand Down Expand Up @@ -1783,7 +1783,7 @@ class MomentumNumpy4D(LorentzMomentum, VectorNumpy4D): # type: ignore[misc]
... dtype=[('px', float), ('py', float), ('pz', float), ('t', float)])
>>> 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', '<f8'), ('y', '<f8'), ('z', '<f8'), ('t', '<f8')])
"""

Expand Down
1 change: 1 addition & 0 deletions src/vector/backends/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ class VectorObject3D(VectorObject, Spatial, Vector3D):
... longitudinal=vector.backends.object.LongitudinalObjectTheta(3)
... )
>>> vec.x, vec.y, vec.theta
(1, 2, 3)
The following class methods can also be used to
Expand Down

0 comments on commit f341a0a

Please sign in to comment.