diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0a5f70cb..3d798739 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -75,14 +75,34 @@ jobs:
poetry run mypy .
- name: Tests with Pytest
+ id: pytest
+ continue-on-error: true
run: |
source venv/Scripts/activate
- PYTHONPATH=${PWD} poetry run coverage run -m pytest --verbose
-
- - name: Report coverage
- run: |
- source venv/Scripts/activate
- poetry run coverage report
+ PYTHONPATH=${PWD} poetry run pytest \
+ -n auto \
+ --dist loadscope \
+ --cov=openseries \
+ --cov-report=term \
+ --cov-report=term-missing \
+ --cov-report=xml \
+ --junitxml=junit.xml
+
+ - name: Create GitHub issue on failure
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
+ with:
+ script: |
+ await github.rest.issues.create({
+ owner: 'CaptorAB',
+ repo: 'openseries',
+ title: `Tests failed on ${new Date().toDateString()}`,
+ body: `See the full logs here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`,
+ })
+
+ - name: Fail job if tests failed
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ run: exit 1
- name: Package and check
run: |
@@ -154,14 +174,34 @@ jobs:
poetry run mypy .
- name: Tests with Pytest
+ id: pytest
+ continue-on-error: true
run: |
source venv/bin/activate
- PYTHONPATH=${PWD} poetry run coverage run -m pytest --verbose
-
- - name: Report coverage
- run: |
- source venv/bin/activate
- poetry run coverage report
+ PYTHONPATH=${PWD} poetry run pytest \
+ -n auto \
+ --dist loadscope \
+ --cov=openseries \
+ --cov-report=term \
+ --cov-report=term-missing \
+ --cov-report=xml \
+ --junitxml=junit.xml
+
+ - name: Create GitHub issue on failure
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
+ with:
+ script: |
+ await github.rest.issues.create({
+ owner: 'CaptorAB',
+ repo: 'openseries',
+ title: `Tests failed on ${new Date().toDateString()}`,
+ body: `See the full logs here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`,
+ })
+
+ - name: Fail job if tests failed
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ run: exit 1
- name: Package and check
run: |
@@ -232,14 +272,27 @@ jobs:
poetry run mypy .
- name: Tests with Pytest
+ id: pytest
+ continue-on-error: true
run: |
source venv/bin/activate
- PYTHONPATH=${PWD} poetry run coverage run -m pytest --verbose
+ PYTHONPATH=${PWD} poetry run pytest --cov=openseries --dist loadscope -n auto
- - name: Report coverage
- run: |
- source venv/bin/activate
- poetry run coverage report
+ - name: Create GitHub issue on failure
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
+ with:
+ script: |
+ await github.rest.issues.create({
+ owner: 'CaptorAB',
+ repo: 'openseries',
+ title: `Tests failed on ${new Date().toDateString()}`,
+ body: `See the full logs here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`,
+ })
+
+ - name: Fail job if tests failed
+ if: ${{ steps.pytest.outcome == 'failure' }}
+ run: exit 1
- name: Package and check
run: |
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index ae6484b2..03e52ae6 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -61,9 +61,18 @@ jobs:
poetry run mypy .
- name: Tests with Pytest
+ id: pytest
+ continue-on-error: true
run: |
source venv/bin/activate
- PYTHONPATH=${PWD} poetry run coverage run -m pytest --verbose
+ PYTHONPATH=${PWD} poetry run pytest \
+ -n auto \
+ --dist loadscope \
+ --cov=openseries \
+ --cov-report=term \
+ --cov-report=term-missing \
+ --cov-report=xml \
+ --junitxml=junit.xml
- name: Create GitHub issue on failure
if: ${{ steps.pytest.outcome == 'failure' }}
@@ -81,19 +90,20 @@ jobs:
if: ${{ steps.pytest.outcome == 'failure' }}
run: exit 1
- - name: Report coverage
- run: |
- source venv/bin/activate
- poetry run coverage xml --quiet
- poetry run coverage report
+ - name: Upload test results to Codecov
+ if: ${{ github.ref_name == 'master' }}
+ uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: junit.xml
+ verbose: true
- name: Upload coverage to Codecov.io
+ if: ${{ github.ref_name == 'master' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: CaptorAB/openseries
- fail_ci_if_error: true
- files: ./coverage.xml
verbose: true
- name: Create Git Tag with version from pyproject.toml
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 463fbaa6..dae4a145 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -90,7 +90,14 @@ jobs:
continue-on-error: true
run: |
source venv/bin/activate
- PYTHONPATH=${PWD} poetry run coverage run -m pytest --verbose
+ PYTHONPATH=${PWD} poetry run pytest \
+ -n auto \
+ --dist loadscope \
+ --cov=openseries \
+ --cov-report=term \
+ --cov-report=term-missing \
+ --cov-report=xml \
+ --junitxml=junit.xml
- name: Create GitHub issue on failure
if: ${{ steps.pytest.outcome == 'failure' }}
@@ -108,17 +115,18 @@ jobs:
if: ${{ steps.pytest.outcome == 'failure' }}
run: exit 1
- - name: Report coverage
- run: |
- source venv/bin/activate
- poetry run coverage xml --quiet
- poetry run coverage report
+ - name: Upload test results to Codecov
+ if: ${{ github.ref_name == 'master' }}
+ uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: junit.xml
+ verbose: true
- name: Upload coverage to Codecov.io
+ if: ${{ github.ref_name == 'master' }}
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: CaptorAB/openseries
- fail_ci_if_error: true
- files: ./coverage.xml
verbose: true
diff --git a/.github/zizmor.yml b/.github/zizmor.yml
index e2c514f8..6737eded 100644
--- a/.github/zizmor.yml
+++ b/.github/zizmor.yml
@@ -20,3 +20,4 @@ rules:
- softprops/action-gh-release
- astral-sh/setup-uv
- codecov/codecov-action
+ - codecov/test-results-action
diff --git a/.gitignore b/.gitignore
index d7602918..fa696127 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ __pycache__/
# Coverage files
.coverage
+coverage.xml
# Environments
/venv/
diff --git a/Makefile b/Makefile
index 178204b9..71ff06e8 100644
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,7 @@ install:
poetry run pre-commit install
test:
- poetry run coverage run -m pytest --verbose
- poetry run coverage xml --quiet
- poetry run coverage report
+ poetry run pytest --cov=openseries --cov-report=term --cov-report=term-missing -n auto
lint:
poetry run ruff check . --fix --exit-non-zero-on-fix
diff --git a/README.md b/README.md
index 2963ce81..77d0abf1 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@

[](https://www.python.org/)
[](https://github.com/CaptorAB/openseries/actions/workflows/test.yml)
-[](https://codecov.io/gh/CaptorAB/openseries/branch/master)
+[](https://codecov.io/gh/CaptorAB/openseries/branch/master)
[](https://python-poetry.org/)
[](https://beta.ruff.rs/docs/)
[](https://github.com/CaptorAB/openseries/blob/master/LICENSE.md)
@@ -54,7 +54,7 @@ _,_=series.plot_series()
### Sample output using the report_html() function:
-
+
## Development Instructions
diff --git a/coverage.xml b/coverage.xml
deleted file mode 100644
index 776fc4a6..00000000
--- a/coverage.xml
+++ /dev/null
@@ -1,1987 +0,0 @@
-
-
-
-
-
- /Users/martinkarrin/workgit/openseries
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/make.ps1 b/make.ps1
index d410a2ea..80a728fa 100644
--- a/make.ps1
+++ b/make.ps1
@@ -95,10 +95,7 @@ switch ($task) {
}
"test" {
- poetry run coverage run -m pytest --verbose
- poetry run coverage xml --quiet
- poetry run coverage report
- poetry run genbadge coverage --silent --local --input-file coverage.xml --output-file coverage.svg
+ poetry run pytest --cov=openseries --cov-report=term --cov-report=term-missing -n auto
}
"lint" {
diff --git a/poetry.lock b/poetry.lock
index 32c1d104..b2063f1d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -61,14 +61,14 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "certifi"
-version = "2025.4.26"
+version = "2025.6.15"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
groups = ["main"]
files = [
- {file = "certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"},
- {file = "certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"},
+ {file = "certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057"},
+ {file = "certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b"},
]
[[package]]
@@ -290,6 +290,9 @@ files = [
{file = "coverage-7.9.1.tar.gz", hash = "sha256:6cf43c78c4282708a28e466316935ec7489a9c487518a77fa68f716c67909cec"},
]
+[package.dependencies]
+tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
+
[package.extras]
toml = ["tomli ; python_full_version <= \"3.11.0a6\""]
@@ -359,6 +362,21 @@ tzdata = "*"
[package.extras]
dev = ["flake8", "hypothesis", "pip-tools", "pytest", "pytest-benchmark", "pytest-xdist"]
+[[package]]
+name = "execnet"
+version = "2.1.1"
+description = "execnet: rapid multi-Python deployment"
+optional = false
+python-versions = ">=3.8"
+groups = ["dev"]
+files = [
+ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"},
+ {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"},
+]
+
+[package.extras]
+testing = ["hatch", "pre-commit", "pytest", "tox"]
+
[[package]]
name = "filelock"
version = "3.18.0"
@@ -848,14 +866,14 @@ virtualenv = ">=20.10.0"
[[package]]
name = "pydantic"
-version = "2.11.6"
+version = "2.11.7"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
- {file = "pydantic-2.11.6-py3-none-any.whl", hash = "sha256:a24478d2be1b91b6d3bc9597439f69ed5e87f68ebd285d86f7c7932a084b72e7"},
- {file = "pydantic-2.11.6.tar.gz", hash = "sha256:12b45cfb4af17e555d3c6283d0b55271865fb0b43cc16dd0d52749dc7abf70e7"},
+ {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"},
+ {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"},
]
[package.dependencies]
@@ -1035,6 +1053,47 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
+[[package]]
+name = "pytest-cov"
+version = "6.2.1"
+description = "Pytest plugin for measuring coverage."
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+files = [
+ {file = "pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5"},
+ {file = "pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2"},
+]
+
+[package.dependencies]
+coverage = {version = ">=7.5", extras = ["toml"]}
+pluggy = ">=1.2"
+pytest = ">=6.2.5"
+
+[package.extras]
+testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
+
+[[package]]
+name = "pytest-xdist"
+version = "3.7.0"
+description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+files = [
+ {file = "pytest_xdist-3.7.0-py3-none-any.whl", hash = "sha256:7d3fbd255998265052435eb9daa4e99b62e6fb9cfb6efd1f858d4d8c0c7f0ca0"},
+ {file = "pytest_xdist-3.7.0.tar.gz", hash = "sha256:f9248c99a7c15b7d2f90715df93610353a485827bc06eefb6566d23f6400f126"},
+]
+
+[package.dependencies]
+execnet = ">=2.1"
+pytest = ">=7.0.0"
+
+[package.extras]
+psutil = ["psutil (>=3.0)"]
+setproctitle = ["setproctitle"]
+testing = ["filelock"]
+
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
@@ -1490,4 +1549,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[metadata]
lock-version = "2.1"
python-versions = ">=3.10,<3.14"
-content-hash = "f0df58f377413e2897bc9e2bbfa780b50127cc3ffd8602d08bb877ae6fa071f5"
+content-hash = "5a2ac8af80bc5cddee878e6f972cadfaab4be86b18283d5996b607582f19e583"
diff --git a/pyproject.toml b/pyproject.toml
index a5ff4f7c..c7722975 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -61,11 +61,12 @@ dependencies = [
[tool.poetry.group.dev.dependencies]
black = ">=24.4.2,<27.0.0"
-coverage = ">=7.2.7,<9.0.0"
mypy = "1.16.0"
pandas-stubs = ">=2.1.2,<3.0.0"
pre-commit = ">=3.7.1,<6.0.0"
pytest = ">=8.2.2,<9.0.0"
+pytest-cov = ">=5.0.0,<7.0.0"
+pytest-xdist = ">=3.3.1,<5.0.0"
ruff = "0.11.13"
types-openpyxl = ">=3.1.2,<5.0.0"
types-python-dateutil = ">=2.8.2,<4.0.0"
@@ -78,7 +79,6 @@ build-backend = "poetry.core.masonry.api"
[tool.coverage.run]
branch = true
omit = ["venv/*", "tests/*", "**/__init__.py"]
-include = ["openseries/*"]
[tool.coverage.report]
omit = ["**/__init__.py"]