Skip to content

Commit 2d3b144

Browse files
authored
Merge pull request #1 from Liam-DeVoe/314-bug-flushing
try flushing 3.14 bug
2 parents 10a2e67 + ef35a6e commit 2d3b144

12 files changed

Lines changed: 1028 additions & 366 deletions

File tree

.github/workflows/main.yml

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,29 @@ on:
1111
jobs:
1212
test:
1313
runs-on: ubuntu-latest
14-
name: Run tests with ${{ matrix.python-version }}
14+
name: Run tests with ${{ matrix.python-version[0] }}
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.13t', 'pypy-3.8']
18+
python-version:
19+
- ['3.9', '3.9']
20+
- ['3.10', '3.10']
21+
- ['3.11', '3.11']
22+
- ['3.12', '3.12']
23+
- ['3.13', '3.13']
24+
- ['3.13t', '3.13t']
25+
- ['3.14-dev', '3.14']
26+
- ['3.14t-dev', '3.14t']
27+
- ['pypy-3.9', 'pypy3.9']
1928
steps:
2029
- uses: actions/checkout@v4
21-
- uses: astral-sh/setup-uv@v3
30+
- uses: actions/setup-python@v5
31+
with:
32+
python-version: ${{ matrix.python-version[0] }}
2233

2334
- name: Install tox
2435
run: |
25-
uv tool install \
26-
--python-preference only-managed \
27-
--python 3.13 \
28-
tox \
29-
--with tox-uv \
30-
--with tox-gh
36+
pip install tox
3137
32-
- name: Install Python
33-
# We've installed Python 3.13 above already
34-
if: matrix.python-version != '3.13'
35-
run: uv python install --python-preference only-managed ${{ matrix.python-version }}
36-
37-
- name: Setup test suite
38-
run: tox run -vv --notest --skip-missing-interpreters false
39-
env:
40-
TOX_GH_MAJOR_MINOR: ${{ matrix.python-version }}
41-
42-
- name: Run test suite
43-
run: tox run --skip-pkg-install
44-
env:
45-
TOX_GH_MAJOR_MINOR: ${{ matrix.python-version }}
38+
- name: Run test suite (${{ matrix.python-version[0] }})
39+
run: tox -e ${{ matrix.python-version[1] }}

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ coverage.xml
5656
.pytest_cache/
5757
cover/
5858
*,cover
59-
.hypothesis/
6059
.pytest_cache
6160

6261
# Translations

README.md

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,30 @@ those fixtures are shared between threads.
6161

6262
## Features
6363

64-
- Three global CLI flags:
64+
- Global CLI flags:
6565
- `--parallel-threads` to run a test suite in parallel
6666
- `--iterations` to run multiple times in each thread
6767
- `--skip-thread-unsafe` to skip running tests marked as or
6868
detected to be thread-unsafe.
69+
- `--mark-warnings-as-unsafe` and `--mark-ctypes-as-unsafe`
70+
to always skip running tests that use the `warnings` or
71+
`ctypes` modules, respectively. These are useful if you are
72+
adding support for Python 3.14 to a library that already
73+
runs tests under pytest-run-parallel on Python 3.13 or
74+
older.
75+
- `--mark-hypothesis-as-unsafe`, to always skip runing tests that
76+
use [hypothesis](https://github.com/hypothesisworks/hypothesis).
77+
While newer version of Hypothesis are thread-safe, and versions
78+
which are not are automatically skipped by `pytest-run-parallel`,
79+
this flag is an escape hatch in case you run into thread-safety
80+
problems caused by Hypothesis, or in tests that happen to use
81+
hypothesis and were skipped in older versions of pytest-run-parallel.
82+
- `--ignore-gil-enabled`, to ignore the RuntimeWarning generated
83+
when the GIL is enabled at runtime on the free-threaded build
84+
and run the tests despite the fact that the GIL is enabled.
85+
This option has no effect if pytest is configured to treat warnings
86+
as errors.
87+
6988

7089
- Three corresponding markers:
7190
- `pytest.mark.parallel_threads(n)` to mark a single test to run
@@ -80,6 +99,8 @@ those fixtures are shared between threads.
8099
- `num_parallel_threads`: The number of threads the test will run in
81100
- `num_iterations`: The number of iterations the test will run in
82101
each thread
102+
- `thread_index`: An index for the test's current thread.
103+
- `iteration_index`: An index for the test's current iteration.
83104

84105
**Note**: It's possible to specify `--parallel-threads=auto` or
85106
`pytest.mark.parallel_threads("auto")` which will let
@@ -125,18 +146,24 @@ current design with `@pytest.mark.thread_unsafe` or
125146
`@pytest.mark.thread_unsafe(reason="...")`.
126147

127148
The following functions and modules are known to be thread-unsafe and
128-
pytest-run-parallel will automatically not run tests using them in
149+
pytest-run-parallel will automatically skip running tests using them in
129150
parallel:
130151

131-
- `pytest.warns`
132-
- `pytest.deprecated_call`
133152
- The pytest `capsys` fixture
134153
- The pytest `monkeypath` fixture
154+
155+
The following fixtures are known to be thread-unsafe on Python 3.13 and older,
156+
or on 3.14 and newer if Python isn't configured correctly:
157+
158+
- `pytest.warns`
159+
- `pytest.deprecated_call`
135160
- The pytest `recwarn` fixture
136161
- `warnings.catch_warnings`
137162
- `unittest.mock`
138163
- `ctypes`
139-
- Any test using [hypothesis](https://hypothesis.readthedocs.io/en/latest/).
164+
165+
If an older version of `hypothesis` that is known to be thread-unsafe is
166+
installed, tests using `hypothesis` are skipped.
140167

141168
Additionally, if a set of fixtures is known to be thread unsafe, tests
142169
that use them can be automatically marked as thread unsafe by declaring
@@ -237,6 +264,20 @@ Both modes of operations are supported simultaneously, i.e.,
237264
$ pytest -x -v --parallel-threads=5 test_file.py
238265
```
239266

267+
You can skip tests marked as or detected to be thread-unsafe by passing
268+
`--skip-thread-unsafe` in your pytest invocation. This is useful when running
269+
pytest-run-parallel under [Thread
270+
Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html). Setting
271+
`--skip-thread-unsafe=True` will avoid unnecessarily running tests where thread
272+
sanitizer cannot detect races because the test is not parallelized.
273+
274+
Older versions of pytest-run-parallel always marked tests using the `warnings`
275+
and `ctypes` modules as thread-unsafe, since both were not thread-safe until
276+
Python 3.14. If you are adding support for Python 3.14 and would like to
277+
continue marking tests that use `warnings` or `ctypes`, pass
278+
`--mark-warnings-as-unsafe` or `--mark-ctypes-as-unsafe`, respectively, in your
279+
`pytest` invocation.
280+
240281
Additionally, `pytest-run-parallel` exposes the `num_parallel_threads`
241282
and `num_iterations` fixtures which enable a test to be aware of the
242283
number of threads that are being spawned and the number of iterations
@@ -252,12 +293,19 @@ def test_skip_if_parallel(num_parallel_threads):
252293
...
253294
```
254295

255-
You can skip tests marked as or detected to be thread-unsafe by passing
256-
`--skip-thread-unsafe` in your pytest invocation. This is useful when running
257-
pytest-run-parallel under [Thread
258-
Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html). Setting
259-
`--skip-thread-unsafe=True` will avoid unnecessarily running tests where thread
260-
sanitizer cannot detect races because the test is not parallelized.
296+
The `thread_index` and `iteration_index` fixtures are also avaliable, which enable
297+
tests to display different behavior between threads and iterations.
298+
299+
```python
300+
# test_file.py
301+
import numpy as np
302+
303+
def test_unique_rng_streams(thread_index):
304+
# create an RNG stream with a seed that is deterministic
305+
# but still unique to this thread
306+
rng = np.random.default_rng(thread_index)
307+
...
308+
```
261309

262310
Finally, the `thread_comp` fixture allows for parallel test debugging,
263311
by providing an instance of `ThreadComparator`, whose `__call__` method

RELEASE.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
To release a new version of `pytest-run-parallel`:
22
1. Update version in `pyproject.toml`, remove `-dev` suffix
3-
2. Make release commit using git add -A && git commit -m "chore(release): release vX.X.X"
4-
3. git tag -a vX.X.X -m "Release vX.X.X"
5-
4. Increment minor version and append the `-dev` suffix
6-
5. git add -A && git commit -m "chore: set development version to vY.Y.Y"
7-
6. git push && git push --tags
8-
7. Create a new release in GitHub and wait for package distribution to be
9-
uploaded to PyPi.
3+
2. Open PR with the version change
4+
3. After PR is merged, run git tag -a vX.X.X -m "Release vX.X.X"
5+
4. Create a new release in GitHub pointing to the new tag. Use autogenerated
6+
release notes. Edit to remove any unnecessary stuff like the release PRs.
7+
Wheels will be uploaded automatically by `.github/workflows/release.yml`.
8+
5. Increment minor version and append the `-dev` suffix in `pyproject.toml`
9+
6. Open PR with the version change
10+
7. Monitor [conda-forge feedstock](https://github.com/conda-forge/pytest-run-parallel-feedstock)
11+
for anything that might be off in the auto-generated (and automerged) PR.
12+
13+
For major releases consider the following manual testing steps before releasing
14+
1. Run test collection for the following projects which use pytest-run-parallel in CI
15+
* SciPy
16+
* CFFI
17+
* pyyaml-ft
18+
19+
The full tests are not necessary to run as most issues happen during AST parsing.

pyproject.toml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ build-backend = "setuptools.build_meta"
77
[project]
88
name = "pytest-run-parallel"
99
description = "A simple pytest plugin to run tests concurrently"
10-
version = "0.4.5-dev"
10+
version = "0.6.2-dev"
1111
readme = "README.md"
12-
requires-python = ">=3.8"
12+
requires-python = ">=3.9"
1313
dependencies = [
1414
"pytest>=6.2.0",
1515
]
@@ -28,7 +28,6 @@ classifiers = [
2828
"Topic :: Software Development :: Testing",
2929
"Operating System :: OS Independent",
3030
"Programming Language :: Python",
31-
"Programming Language :: Python :: 3.8",
3231
"Programming Language :: Python :: 3.9",
3332
"Programming Language :: Python :: 3.10",
3433
"Programming Language :: Python :: 3.11",
@@ -53,7 +52,7 @@ psutil = [
5352
[dependency-groups]
5453
dev = [
5554
"pre-commit>=3.5.0",
56-
"pytest-cov>=5.0.0",
55+
"coverage[toml]>=7.5",
5756
"pytest-order>=1.3.0",
5857
"ruff>=0.7.2",
5958
"tox>=4.23.2",
@@ -66,26 +65,34 @@ exclude = ["docs/conf.py"]
6665
select = ["E4", "E7", "E9", "F", "I"]
6766

6867
[tool.tox]
69-
env_list = ["py38", "py39", "py310", "py311", "py312", "py313", "py313t", "psutil", "pypy3", "ruff"]
68+
env_list = ["py39", "py310", "py311", "py312", "py313", "py313t", "psutil", "pypy3", "ruff"]
7069

7170
[tool.tox.env_run_base]
7271
deps = [
7372
"pytest>=6.2.0",
74-
"pytest-cov",
73+
"coverage[toml]>=7.5",
7574
"pytest-order",
7675
"check-manifest",
77-
"hypothesis",
76+
"hypothesis>=6.135.33",
7877
]
7978
commands = [
8079
[
80+
"coverage",
81+
"run",
82+
"--source=pytest_run_parallel,tests",
83+
"-m",
8184
"pytest",
85+
"-W",
86+
"error",
8287
"-v",
83-
"--cov-report", "lcov",
84-
"--cov", "src/pytest_run_parallel",
85-
"--cov", "tests",
8688
"{posargs:tests}"
8789
],
8890
[
91+
"coverage",
92+
"report",
93+
"-m"
94+
],
95+
[
8996
"check-manifest",
9097
"-u",
9198
"-v",
@@ -104,11 +111,10 @@ extras = ["psutil"]
104111

105112

106113
[tool.tox.gh.python]
107-
"3.8" = ["py38"]
108114
"3.9" = ["py39"]
109115
"3.10" = ["py310"]
110116
"3.11" = ["py311"]
111117
"3.12" = ["py312"]
112118
"3.13" = ["py313", "psutil"]
113119
"3.13t" = ["py313t"]
114-
"pypy-3.8" = ["pypy3"]
120+
"pypy-3.9" = ["pypy3"]

0 commit comments

Comments
 (0)