diff --git a/.cspell/library_terms.txt b/.cspell/library_terms.txt index cda36ee..e54cc6b 100644 --- a/.cspell/library_terms.txt +++ b/.cspell/library_terms.txt @@ -179,6 +179,7 @@ warpfunctions weathersit windspeed workingday +worksteal xlabel xlim xscale diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 451e107..fa44af2 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,7 +48,7 @@ jobs: - name: Debug - uv pip freeze run: uv pip freeze - name: Assess coverage of unit tests - run: uv run pytest tests/units tests/test_doctests.py --cov + run: uv run pytest tests/units tests/test_doctests.py --cov -n auto --dist worksteal - name: Extract total coverage percentage id: cov run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6aab092..286b819 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -116,10 +116,10 @@ jobs: - name: Debug - uv pip freeze run: uv pip freeze - name: Test with pytest - run: uv run pytest tests --ignore=tests/test_examples.py + run: uv run pytest tests --ignore=tests/test_examples.py -n auto --dist worksteal # The example notebooks are slow, so only run if all other tests pass. - name: Test example notebooks - run: uv run pytest tests/test_examples.py + run: uv run pytest tests/test_examples.py -n auto --dist worksteal release-github: name: Create GitHub draft release needs: test diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 04a1619..bdf21fc 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -66,6 +66,8 @@ jobs: --ignore=tests/test_examples.py -W "error::vanguard.utils.UnseededRandomWarning" -m "no_beartype" + -n auto + --dist worksteal if: matrix.python-version == '3.13' - name: Test with pytest (and type checking) run: > @@ -74,12 +76,16 @@ jobs: -W "error::vanguard.utils.UnseededRandomWarning" -m "not no_beartype" --beartype-packages="vanguard" + -n auto + --dist worksteal if: matrix.python-version == '3.13' - name: Run all tests run: > uv run pytest --ignore=tests/test_examples.py -W "error::vanguard.utils.UnseededRandomWarning" + -n auto + --dist worksteal if: matrix.python-version != '3.13' - name: Minimize UV cache run: uv cache prune --ci diff --git a/.github/workflows/unittests_lowest.yml b/.github/workflows/unittests_lowest.yml index 48a656f..fc07e9a 100644 --- a/.github/workflows/unittests_lowest.yml +++ b/.github/workflows/unittests_lowest.yml @@ -71,6 +71,8 @@ jobs: uv run --frozen --no-dev pytest --ignore=tests/test_examples.py -W "error::vanguard.utils.UnseededRandomWarning" + -n auto + --dist worksteal - name: Minimize UV cache run: uv cache prune --ci if: always() diff --git a/pyproject.toml b/pyproject.toml index 05b7e4f..069b0b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ test = [ "tqdm>=4", # for notebook tests "pytest-beartype>=0.1", "pytest-cov>=5", + "pytest-xdist>=3.6.1", "pytest>=8.3.3", "beartype>=0.19, !=0.20", ] diff --git a/uv.lock b/uv.lock index 8c8edfc..7b275b3 100644 --- a/uv.lock +++ b/uv.lock @@ -785,6 +785,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, ] +[[package]] +name = "execnet" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 }, +] + [[package]] name = "executing" version = "2.2.0" @@ -2337,7 +2346,7 @@ name = "nvidia-cudnn-cu12" version = "9.1.0.70" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cublas-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 }, @@ -2348,7 +2357,7 @@ name = "nvidia-cufft-cu12" version = "11.2.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9", size = 211459117 }, @@ -2367,9 +2376,9 @@ name = "nvidia-cusolver-cu12" version = "11.6.1.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12" }, - { name = "nvidia-cusparse-cu12" }, - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-cublas-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, + { name = "nvidia-cusparse-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260", size = 127936057 }, @@ -2380,7 +2389,7 @@ name = "nvidia-cusparse-cu12" version = "12.3.1.170" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12" }, + { name = "nvidia-nvjitlink-cu12", marker = "(python_full_version < '3.13' and platform_python_implementation == 'PyPy') or (python_full_version < '3.10' and platform_python_implementation != 'PyPy' and sys_platform == 'win32') or (python_full_version < '3.13' and sys_platform != 'win32') or (os_name != 'nt' and platform_python_implementation == 'PyPy') or (os_name != 'nt' and sys_platform != 'win32')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1", size = 207454763 }, @@ -2515,7 +2524,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "(python_full_version < '3.10' and platform_python_implementation != 'PyPy') or platform_python_implementation == 'PyPy' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } wheels = [ @@ -2845,6 +2854,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, ] +[[package]] +name = "pytest-xdist" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108 }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -3984,6 +4006,7 @@ test = [ { name = "pytest" }, { name = "pytest-beartype" }, { name = "pytest-cov" }, + { name = "pytest-xdist" }, { name = "tqdm" }, ] @@ -4029,6 +4052,7 @@ requires-dist = [ { name = "pytest", marker = "extra == 'test'", specifier = ">=8.3.3" }, { name = "pytest-beartype", marker = "extra == 'test'", specifier = ">=0.1" }, { name = "pytest-cov", marker = "extra == 'test'", specifier = ">=5" }, + { name = "pytest-xdist", marker = "extra == 'test'", specifier = ">=3.6.1" }, { name = "scikit-learn", specifier = ">=1.5.0" }, { name = "scikit-learn", marker = "python_full_version >= '3.13'", specifier = ">=1.6.0" }, { name = "scipy", specifier = ">=1.13" },