pytest-subproc 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.13"
17
+ - run: pip install pre-commit
18
+ - run: pre-commit run --all-files --show-diff-on-failure
19
+
20
+ test:
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ os: [ubuntu-latest, windows-latest]
25
+ python-version: ["3.8", "3.13"]
26
+
27
+ runs-on: ${{ matrix.os }}
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+
34
+ - name: Install dependencies
35
+ run: |
36
+ pip install -e ".[test]"
37
+ pip install pytest-timeout pytest-xdist
38
+
39
+ - name: Run tests
40
+ run: python -m pytest tests/ -v --timeout=60
41
+
42
+ - name: Coverage
43
+ if: matrix.python-version == '3.13' && matrix.os == 'ubuntu-latest'
44
+ run: |
45
+ pip install coverage
46
+ COVERAGE_PROCESS_START=pyproject.toml \
47
+ coverage run -m pytest tests/ --timeout=60 -x
48
+ coverage combine
49
+ coverage report --include="src/pytest_subproc/*" --show-missing
50
+ coverage xml --include="src/pytest_subproc/*"
51
+
52
+ # - name: Upload coverage
53
+ # if: matrix.python-version == '3.13' && matrix.os == 'ubuntu-latest'
54
+ # uses: codecov/codecov-action@v6
55
+ # with:
56
+ # files: coverage.xml
57
+ # fail_ci_if_error: false
@@ -0,0 +1,34 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.13"
22
+
23
+ - name: Build package
24
+ run: |
25
+ pip install build
26
+ python -m build
27
+
28
+ - name: Publish to PyPI
29
+ env:
30
+ TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
31
+ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
32
+ run: |
33
+ pip install twine
34
+ twine upload dist/*
@@ -0,0 +1,39 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg
5
+ *.egg-info/
6
+
7
+ # Build artifacts
8
+ dist/
9
+ build/
10
+
11
+ # Testing / coverage
12
+ .coverage
13
+ .coverage.*
14
+ .cov_subproc_rc
15
+ .cov_subproc_test
16
+ coverage.xml
17
+ htmlcov/
18
+ .tox
19
+ nosetests.xml
20
+ .cache
21
+ .pytest*
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ env/
27
+
28
+ # Editor / OS
29
+ *.swp
30
+ *.swo
31
+ .DS_Store
32
+ nohup.out
33
+
34
+ # AI assistants
35
+ .agents/
36
+ .claude/
37
+
38
+ # Windows-unacceptable file names
39
+ \\*
@@ -0,0 +1,61 @@
1
+ minimum_pre_commit_version: 2.15.0
2
+ default_stages: [commit, merge-commit, push]
3
+ ci:
4
+ autofix_prs: false
5
+ repos:
6
+ - repo: local
7
+ hooks:
8
+ - id: check-yaml
9
+ name: check-yaml
10
+ entry: check-yaml
11
+ language: python
12
+ types_or: [yaml]
13
+ additional_dependencies: [pre-commit-hooks==4.4.0]
14
+ - id: end-of-file-fixer
15
+ name: end-of-file-fixer
16
+ entry: end-of-file-fixer
17
+ language: python
18
+ additional_dependencies: [pre-commit-hooks==4.4.0]
19
+ - id: trailing-whitespace
20
+ name: trailing-whitespace
21
+ entry: trailing-whitespace-fixer
22
+ language: python
23
+ additional_dependencies: [pre-commit-hooks==4.4.0]
24
+ - id: check-illegal-windows-names
25
+ name: check illegal windows names
26
+ entry: Illegal windows filenames detected
27
+ language: fail
28
+ files: '(?i)((^|/)(\\|CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)|:)'
29
+ - repo: local
30
+ hooks:
31
+ - id: flake8
32
+ name: flake8
33
+ description: "Flake8"
34
+ entry: flake8
35
+ language: python
36
+ require_serial: true
37
+ types_or: [python, pyi]
38
+ additional_dependencies: [
39
+ 'flake8==6.1.0; python_version>="3.8"',
40
+ ]
41
+ - repo: local
42
+ hooks:
43
+ - id: black
44
+ name: black
45
+ description: "Black"
46
+ entry: black
47
+ language: python
48
+ require_serial: true
49
+ types_or: [python, pyi]
50
+ additional_dependencies: [black==23.3.0]
51
+ - repo: local
52
+ hooks:
53
+ - id: isort
54
+ name: isort
55
+ description: "isort"
56
+ entry: isort
57
+ language: python
58
+ require_serial: true
59
+ types_or: [python, pyi]
60
+ args: [--profile, black]
61
+ additional_dependencies: [isort==5.11.0]
@@ -0,0 +1,40 @@
1
+ # pytest-subproc — AGENTS.md
2
+
3
+ ## Commands
4
+
5
+ ```bash
6
+ pip install -e ".[test]" # editable + test deps
7
+ pytest tests/ -v --timeout=60 # run all tests
8
+ pytest tests/ -k "xfail" -v # single topic
9
+ pre-commit run --all-files # lint: flake8 + black + isort
10
+ ```
11
+
12
+ Coverage (requires `pip install coverage`):
13
+
14
+ ```bash
15
+ COVERAGE_PROCESS_START=pyproject.toml \
16
+ coverage run -m pytest tests/ --timeout=60 -x
17
+ coverage combine
18
+ coverage report --include="src/pytest_subproc/*" --show-missing
19
+ ```
20
+
21
+ Mark subprocess tests: `@pytest.mark.subproc(timeout=N, condition=bool_or_callable)`.
22
+
23
+ ## Architecture
24
+
25
+ - Entry point: `src/pytest_subproc/__init__.py` — `pytest_runtest_protocol` (tryfirst) intercepts `subproc`-marked items.
26
+ - Subprocess runner: `src/pytest_subproc/_subproc_runner.py`. Runs `pytest.main([nodeid])` — conftest loading, fixture resolution, setup/call/teardown all happen inside the child.
27
+ - No `_pytest` private imports outside a single `_pytest.skipping` call (xfailed_key/evaluate).
28
+ - Result: exception is pickled from child, re-raised in parent so `xfail(raises=...)` works.
29
+
30
+ ## Coverage quirk
31
+
32
+ `_subproc_runner.py` runs as `python _subproc_runner.py` (script, not module import). Coverage with `source = [...]` won't capture it because it's `__main__`. Must use `include = ["src/pytest_subproc/*"]` (path-based) in the coverage config, and set `COVERAGE_PROCESS_START` so the `.pth`-file auto-start mechanism fires in the child. The CI coverage step shows how.
33
+
34
+ ## Testing quirks
35
+
36
+ - All tests use `pytester` fixture (built-in, just `pytest_plugins = "pytester"` in the test file).
37
+ - `assert_outcomes(passed=N, failed=N, xfailed=N)` is preferred over `fnmatch_lines`.
38
+ - Coverage integration test (`test_coverage_collected_from_subprocess`) uses isolated file names (`.cov_subproc_*`) to avoid polluting the parent coverage run.
39
+ - `pytest-flaky` on PyPI is called `flaky` — the dependency name is `flaky`, import is `from flaky import flaky`.
40
+ - Windows CI uses a reduced Python version matrix (3.8, 3.13) to stay within runner time limits.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 WJ SI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ recursive-include src/pytest_subproc *.py
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-subproc
3
+ Version: 0.1.0
4
+ Summary: A pytest plugin to run marked tests in a subprocess
5
+ Requires-Python: >=3.7
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: pytest>=7.0.0
9
+ Provides-Extra: test
10
+ Requires-Dist: pytest-asyncio>=0.21; extra == "test"
11
+ Requires-Dist: pytest-cov>=4.0; extra == "test"
12
+ Requires-Dist: flaky>=3.8; extra == "test"
13
+ Requires-Dist: pytest-timeout>=1.4; extra == "test"
14
+ Dynamic: license-file
15
+
16
+ # pytest-subproc
17
+
18
+ Run marked pytest test functions in an isolated subprocess to protect the main process from crashes caused by C++ panics, segfaults, or hangs.
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install pytest-subproc
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ Mark any test with `@pytest.mark.subproc` to run it in a subprocess:
29
+
30
+ ```python
31
+ import pytest
32
+
33
+ @pytest.mark.subproc
34
+ def test_isolated():
35
+ assert True
36
+ ```
37
+
38
+ ### Parameters
39
+
40
+ `@pytest.mark.subproc(timeout=None, condition=None)`
41
+
42
+ | Parameter | Type | Default | Description |
43
+ |---|---|---|---|
44
+ | `timeout` | `float` | `None` | Timeout in seconds. Kills the subprocess if the test exceeds this limit. Falls back to `subproc_default_timeout` ini option. |
45
+ | `condition` | `bool` or `() -> bool` | `True` | When falsy, the test runs in the main process normally. Useful for conditional isolation (e.g., only in CI). |
46
+
47
+ ```python
48
+ @pytest.mark.subproc(timeout=30)
49
+ def test_with_timeout():
50
+ ...
51
+
52
+ @pytest.mark.subproc(condition=lambda: os.environ.get("CI") == "true")
53
+ def test_ci_only():
54
+ ...
55
+
56
+ @pytest.mark.subproc(timeout=10, condition=False)
57
+ def test_never_subprocess():
58
+ ...
59
+ ```
60
+
61
+ ### Configuration via `pyproject.toml` / `pytest.ini`
62
+
63
+ ```ini
64
+ [tool.pytest.ini_options]
65
+ subproc_default_timeout = 30
66
+ ```
67
+
68
+ Or on the command line:
69
+
70
+ ```bash
71
+ pytest --subprocess-timeout=30
72
+ ```
73
+
74
+ ### Module-level configuration
75
+
76
+ Set defaults for all `@pytest.mark.subproc` tests in a directory tree by calling `pytest_subproc` methods in a `conftest.py`:
77
+
78
+ ```python
79
+ import pytest_subproc
80
+
81
+ # Default timeout (lowest priority: marker > CLI > ini > this)
82
+ pytest_subproc.config_default_timeout(30)
83
+
84
+ # Default condition for spawning (lowest priority: marker > this)
85
+ pytest_subproc.config_global_enabled(True)
86
+ pytest_subproc.config_global_enabled(lambda: os.environ.get("CI") == "true") # callable
87
+ ```
88
+
89
+
90
+ ### `@pytest.mark.timeout` interaction
91
+
92
+ When a test has both `@pytest.mark.subproc(timeout=5)` and `@pytest.mark.timeout(3)`,
93
+ the shorter value (3s) is used as the subprocess timeout. This prevents
94
+ `pytest-timeout` from killing the main process while the subprocess is still
95
+ running — our plugin cancels `pytest-timeout`'s timer and enforces the
96
+ effective timeout on the subprocess itself.
97
+
98
+ ```python
99
+ @pytest.mark.subproc(timeout=5)
100
+ @pytest.mark.timeout(3) # ← effective timeout (shorter wins)
101
+ def test_obey_the_shorter():
102
+ ...
103
+ ```
104
+
105
+
106
+ ## How It Works
107
+
108
+ 1. **Interception** — `pytest_runtest_protocol` (tryfirst) takes over the
109
+ protocol for `subproc`-marked tests.
110
+
111
+ 2. **Isolated run** — The main process spawns a child that runs
112
+ `pytest.main([nodeid, --rootdir, ...])` for that single test.
113
+ The **full lifecycle** (conftest loading, fixture resolution, setup,
114
+ call, teardown) happens inside the subprocess.
115
+
116
+ 3. **Timeout & cleanup** — The child is created with `start_new_session`
117
+ so the **entire process group** (including test‑spawned children) is
118
+ killed when the timeout fires.
119
+
120
+ 4. **Result** — A plugin inside the subprocess captures the outcome and
121
+ exception; these are pickled to a temp file. The parent re‑raises
122
+ the exception so `xfail`, `skip`, etc. work as expected.
123
+
124
+ 5. **Config parity** — `asyncio_mode`, `xfail_strict` and other ini
125
+ settings are forwarded to the subprocess via `--override-ini`.
126
+
127
+ ## Comparison with `pytest-forked`
128
+
129
+ | | `pytest-subproc` | `pytest-forked` |
130
+ |---|---|---|
131
+ | Mechanism | Spawns a new Python process (`subprocess`) | Forks the existing process (`os.fork`) |
132
+ | Fixtures | Re‑evaluated in the child (full conftest + fixture resolution) | Inherited from parent via copy‑on‑write |
133
+ | Windows | ✅ Supported | ❌ Not available |
134
+ | Crash isolation | Full — the child has its own PID and memory space; a segfault cannot reach the parent | Partial — forked process shares file descriptors and some kernel state with the parent |
135
+ | Timeout | Built‑in `timeout` parameter on the marker, with process‑tree termination | Only via external `pytest-timeout` plugin |
136
+ | Process‑tree cleanup | Kills the entire process group on timeout (`os.killpg` / `taskkill /T`) | No automatic child‑process cleanup |
137
+ | Startup cost | Moderate — a new Python interpreter starts and runs `pytest.main` for one test | Low — fork is (mostly) copy‑on‑write |
138
+ | `pytest-xdist` | ✅ Compatible | ✅ Compatible |
139
+
140
+ ## Feature Compatibility
141
+
142
+ | Feature | Status |
143
+ |---|---|
144
+ | Python >= 3.7 | ✅ |
145
+ | Function, session, and module-level fixtures | ✅ |
146
+ | stdout/stderr captured and shown on failure | ✅ |
147
+ | `pytest.mark.asyncio` + `asyncio_mode = "auto"` | ✅ |
148
+ | `@pytest.mark.parametrize` | ✅ |
149
+ | `@pytest.mark.xfail(raises=...)` | ✅ |
150
+ | Custom exception pickling / re-raising | ✅ |
151
+ | `flaky` retries | ✅ |
152
+ | `pytest-timeout` signal handling | ✅ |
153
+ | `pytest-cov` coverage passthrough | ✅ |
154
+
155
+ ## Requirements
156
+
157
+ - Python >= 3.7
158
+ - pytest >= 7.0
159
+
160
+ ## License
161
+
162
+ MIT
@@ -0,0 +1,147 @@
1
+ # pytest-subproc
2
+
3
+ Run marked pytest test functions in an isolated subprocess to protect the main process from crashes caused by C++ panics, segfaults, or hangs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install pytest-subproc
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Mark any test with `@pytest.mark.subproc` to run it in a subprocess:
14
+
15
+ ```python
16
+ import pytest
17
+
18
+ @pytest.mark.subproc
19
+ def test_isolated():
20
+ assert True
21
+ ```
22
+
23
+ ### Parameters
24
+
25
+ `@pytest.mark.subproc(timeout=None, condition=None)`
26
+
27
+ | Parameter | Type | Default | Description |
28
+ |---|---|---|---|
29
+ | `timeout` | `float` | `None` | Timeout in seconds. Kills the subprocess if the test exceeds this limit. Falls back to `subproc_default_timeout` ini option. |
30
+ | `condition` | `bool` or `() -> bool` | `True` | When falsy, the test runs in the main process normally. Useful for conditional isolation (e.g., only in CI). |
31
+
32
+ ```python
33
+ @pytest.mark.subproc(timeout=30)
34
+ def test_with_timeout():
35
+ ...
36
+
37
+ @pytest.mark.subproc(condition=lambda: os.environ.get("CI") == "true")
38
+ def test_ci_only():
39
+ ...
40
+
41
+ @pytest.mark.subproc(timeout=10, condition=False)
42
+ def test_never_subprocess():
43
+ ...
44
+ ```
45
+
46
+ ### Configuration via `pyproject.toml` / `pytest.ini`
47
+
48
+ ```ini
49
+ [tool.pytest.ini_options]
50
+ subproc_default_timeout = 30
51
+ ```
52
+
53
+ Or on the command line:
54
+
55
+ ```bash
56
+ pytest --subprocess-timeout=30
57
+ ```
58
+
59
+ ### Module-level configuration
60
+
61
+ Set defaults for all `@pytest.mark.subproc` tests in a directory tree by calling `pytest_subproc` methods in a `conftest.py`:
62
+
63
+ ```python
64
+ import pytest_subproc
65
+
66
+ # Default timeout (lowest priority: marker > CLI > ini > this)
67
+ pytest_subproc.config_default_timeout(30)
68
+
69
+ # Default condition for spawning (lowest priority: marker > this)
70
+ pytest_subproc.config_global_enabled(True)
71
+ pytest_subproc.config_global_enabled(lambda: os.environ.get("CI") == "true") # callable
72
+ ```
73
+
74
+
75
+ ### `@pytest.mark.timeout` interaction
76
+
77
+ When a test has both `@pytest.mark.subproc(timeout=5)` and `@pytest.mark.timeout(3)`,
78
+ the shorter value (3s) is used as the subprocess timeout. This prevents
79
+ `pytest-timeout` from killing the main process while the subprocess is still
80
+ running — our plugin cancels `pytest-timeout`'s timer and enforces the
81
+ effective timeout on the subprocess itself.
82
+
83
+ ```python
84
+ @pytest.mark.subproc(timeout=5)
85
+ @pytest.mark.timeout(3) # ← effective timeout (shorter wins)
86
+ def test_obey_the_shorter():
87
+ ...
88
+ ```
89
+
90
+
91
+ ## How It Works
92
+
93
+ 1. **Interception** — `pytest_runtest_protocol` (tryfirst) takes over the
94
+ protocol for `subproc`-marked tests.
95
+
96
+ 2. **Isolated run** — The main process spawns a child that runs
97
+ `pytest.main([nodeid, --rootdir, ...])` for that single test.
98
+ The **full lifecycle** (conftest loading, fixture resolution, setup,
99
+ call, teardown) happens inside the subprocess.
100
+
101
+ 3. **Timeout & cleanup** — The child is created with `start_new_session`
102
+ so the **entire process group** (including test‑spawned children) is
103
+ killed when the timeout fires.
104
+
105
+ 4. **Result** — A plugin inside the subprocess captures the outcome and
106
+ exception; these are pickled to a temp file. The parent re‑raises
107
+ the exception so `xfail`, `skip`, etc. work as expected.
108
+
109
+ 5. **Config parity** — `asyncio_mode`, `xfail_strict` and other ini
110
+ settings are forwarded to the subprocess via `--override-ini`.
111
+
112
+ ## Comparison with `pytest-forked`
113
+
114
+ | | `pytest-subproc` | `pytest-forked` |
115
+ |---|---|---|
116
+ | Mechanism | Spawns a new Python process (`subprocess`) | Forks the existing process (`os.fork`) |
117
+ | Fixtures | Re‑evaluated in the child (full conftest + fixture resolution) | Inherited from parent via copy‑on‑write |
118
+ | Windows | ✅ Supported | ❌ Not available |
119
+ | Crash isolation | Full — the child has its own PID and memory space; a segfault cannot reach the parent | Partial — forked process shares file descriptors and some kernel state with the parent |
120
+ | Timeout | Built‑in `timeout` parameter on the marker, with process‑tree termination | Only via external `pytest-timeout` plugin |
121
+ | Process‑tree cleanup | Kills the entire process group on timeout (`os.killpg` / `taskkill /T`) | No automatic child‑process cleanup |
122
+ | Startup cost | Moderate — a new Python interpreter starts and runs `pytest.main` for one test | Low — fork is (mostly) copy‑on‑write |
123
+ | `pytest-xdist` | ✅ Compatible | ✅ Compatible |
124
+
125
+ ## Feature Compatibility
126
+
127
+ | Feature | Status |
128
+ |---|---|
129
+ | Python >= 3.7 | ✅ |
130
+ | Function, session, and module-level fixtures | ✅ |
131
+ | stdout/stderr captured and shown on failure | ✅ |
132
+ | `pytest.mark.asyncio` + `asyncio_mode = "auto"` | ✅ |
133
+ | `@pytest.mark.parametrize` | ✅ |
134
+ | `@pytest.mark.xfail(raises=...)` | ✅ |
135
+ | Custom exception pickling / re-raising | ✅ |
136
+ | `flaky` retries | ✅ |
137
+ | `pytest-timeout` signal handling | ✅ |
138
+ | `pytest-cov` coverage passthrough | ✅ |
139
+
140
+ ## Requirements
141
+
142
+ - Python >= 3.7
143
+ - pytest >= 7.0
144
+
145
+ ## License
146
+
147
+ MIT
@@ -0,0 +1,44 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "setuptools-scm>=8"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pytest-subproc"
7
+ dynamic = ["version"]
8
+ description = "A pytest plugin to run marked tests in a subprocess"
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ dependencies = ["pytest>=7.0.0"]
12
+
13
+ [tool.setuptools_scm]
14
+
15
+ [project.entry-points.pytest11]
16
+ pytest_subproc = "pytest_subproc"
17
+
18
+ [tool.pytest.ini_options]
19
+ testpaths = ["tests"]
20
+ asyncio_mode = "auto"
21
+
22
+ [tool.coverage.run]
23
+ include = ["src/pytest_subproc/*"]
24
+ data_file = ".coverage"
25
+ branch = true
26
+ parallel = true
27
+ cover_pylib = false
28
+ concurrency = ["multiprocessing", "thread"]
29
+ relative_files = true
30
+
31
+ [tool.coverage.paths]
32
+ source = ["src"]
33
+
34
+ [tool.coverage.report]
35
+ show_missing = true
36
+ skip_empty = true
37
+
38
+ [project.optional-dependencies]
39
+ test = [
40
+ "pytest-asyncio>=0.21",
41
+ "pytest-cov>=4.0",
42
+ "flaky>=3.8",
43
+ "pytest-timeout>=1.4",
44
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+