rustest 0.14.0__cp313-cp313-macosx_11_0_arm64.whl
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.
- rustest/__init__.py +39 -0
- rustest/__main__.py +10 -0
- rustest/approx.py +176 -0
- rustest/builtin_fixtures.py +1137 -0
- rustest/cli.py +135 -0
- rustest/compat/__init__.py +3 -0
- rustest/compat/pytest.py +1141 -0
- rustest/core.py +56 -0
- rustest/decorators.py +968 -0
- rustest/fixture_registry.py +130 -0
- rustest/py.typed +0 -0
- rustest/reporting.py +63 -0
- rustest/rust.cpython-313-darwin.so +0 -0
- rustest/rust.py +23 -0
- rustest/rust.pyi +43 -0
- rustest-0.14.0.dist-info/METADATA +151 -0
- rustest-0.14.0.dist-info/RECORD +20 -0
- rustest-0.14.0.dist-info/WHEEL +4 -0
- rustest-0.14.0.dist-info/entry_points.txt +2 -0
- rustest-0.14.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Global fixture registry for runtime fixture resolution.
|
|
2
|
+
|
|
3
|
+
This module provides a thread-safe global registry that stores fixture information
|
|
4
|
+
and enables dynamic fixture resolution via request.getfixturevalue().
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import inspect
|
|
10
|
+
import threading
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
_registry_lock = threading.Lock()
|
|
14
|
+
_fixture_registry: dict[str, Any] = {}
|
|
15
|
+
_fixture_cache: dict[str, Any] = {}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def register_fixtures(fixtures: dict[str, Any]) -> None:
|
|
19
|
+
"""Register fixtures for the current test context.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
fixtures: Dictionary mapping fixture names to fixture callables
|
|
23
|
+
"""
|
|
24
|
+
with _registry_lock:
|
|
25
|
+
_fixture_registry.clear()
|
|
26
|
+
_fixture_registry.update(fixtures)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def clear_registry() -> None:
|
|
30
|
+
"""Clear the fixture registry and cache."""
|
|
31
|
+
with _registry_lock:
|
|
32
|
+
_fixture_registry.clear()
|
|
33
|
+
_fixture_cache.clear()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_fixture(name: str) -> Any:
|
|
37
|
+
"""Get a fixture callable by name.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name: Name of the fixture
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The fixture callable
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
ValueError: If the fixture is not found
|
|
47
|
+
"""
|
|
48
|
+
with _registry_lock:
|
|
49
|
+
if name not in _fixture_registry:
|
|
50
|
+
raise ValueError(f"fixture '{name}' not found")
|
|
51
|
+
return _fixture_registry[name]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def resolve_fixture(name: str, _executed_fixtures: dict[str, Any] | None = None) -> Any:
|
|
55
|
+
"""Resolve and execute a fixture by name.
|
|
56
|
+
|
|
57
|
+
This handles fixture dependencies recursively and caches results per test.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
name: Name of the fixture to resolve
|
|
61
|
+
_executed_fixtures: Internal cache of already-executed fixtures for this test
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
The fixture value
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
ValueError: If the fixture is not found
|
|
68
|
+
NotImplementedError: If the fixture is async (not yet supported)
|
|
69
|
+
"""
|
|
70
|
+
if _executed_fixtures is None:
|
|
71
|
+
_executed_fixtures = {}
|
|
72
|
+
|
|
73
|
+
# Check if already executed for this test
|
|
74
|
+
if name in _executed_fixtures:
|
|
75
|
+
return _executed_fixtures[name]
|
|
76
|
+
|
|
77
|
+
# Get the fixture callable
|
|
78
|
+
fixture_func = get_fixture(name)
|
|
79
|
+
|
|
80
|
+
# Check if it's async (either async function or async generator)
|
|
81
|
+
if inspect.iscoroutinefunction(fixture_func) or inspect.isasyncgenfunction(fixture_func):
|
|
82
|
+
# Raise a clear, helpful error explaining the issue and how to fix it
|
|
83
|
+
raise NotImplementedError(
|
|
84
|
+
f"\nCannot use async fixture '{name}' with request.getfixturevalue().\n\n"
|
|
85
|
+
+ "Why this fails:\n"
|
|
86
|
+
+ " • getfixturevalue() is a synchronous function that returns values immediately\n"
|
|
87
|
+
+ " • Async fixtures must be awaited, but we can't await in a sync context\n"
|
|
88
|
+
+ " • Calling the async fixture returns a coroutine object, not the actual value\n\n"
|
|
89
|
+
+ "Good news: Async fixtures work perfectly with normal injection!\n\n"
|
|
90
|
+
+ "How to fix:\n"
|
|
91
|
+
+ f" ❌ Don't use: request.getfixturevalue('{name}')\n"
|
|
92
|
+
+ f" ✅ Instead use: def test_something({name}):\n\n"
|
|
93
|
+
+ "Example:\n"
|
|
94
|
+
+ " # This works perfectly:\n"
|
|
95
|
+
+ f" async def test_my_feature({name}):\n"
|
|
96
|
+
+ f" assert {name} is not None\n"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Get fixture parameters
|
|
100
|
+
sig = inspect.signature(fixture_func)
|
|
101
|
+
params = sig.parameters
|
|
102
|
+
|
|
103
|
+
# Resolve dependencies recursively
|
|
104
|
+
resolved_args = {}
|
|
105
|
+
for param_name in params:
|
|
106
|
+
# Use get_fixture() which has lock protection, instead of checking registry directly
|
|
107
|
+
try:
|
|
108
|
+
# Try to get the fixture (thread-safe with lock)
|
|
109
|
+
get_fixture(param_name)
|
|
110
|
+
# It's a fixture - resolve it recursively
|
|
111
|
+
resolved_args[param_name] = resolve_fixture(param_name, _executed_fixtures)
|
|
112
|
+
except ValueError:
|
|
113
|
+
# Not a fixture - skip it
|
|
114
|
+
# Special handling for 'request' parameter
|
|
115
|
+
if param_name == "request":
|
|
116
|
+
# Skip 'request' parameter - will be handled by caller
|
|
117
|
+
resolved_args[param_name] = None
|
|
118
|
+
|
|
119
|
+
# Execute the fixture
|
|
120
|
+
result = fixture_func(**resolved_args)
|
|
121
|
+
|
|
122
|
+
# Handle generator fixtures
|
|
123
|
+
if inspect.isgenerator(result):
|
|
124
|
+
result = next(result)
|
|
125
|
+
# TODO: Store generator for teardown
|
|
126
|
+
|
|
127
|
+
# Cache the result
|
|
128
|
+
_executed_fixtures[name] = result
|
|
129
|
+
|
|
130
|
+
return result
|
rustest/py.typed
ADDED
|
File without changes
|
rustest/reporting.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Utilities for converting raw results from the Rust layer."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
from . import rust
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(slots=True)
|
|
12
|
+
class TestResult:
|
|
13
|
+
"""Structured view of a single test outcome."""
|
|
14
|
+
|
|
15
|
+
__test__ = False # Tell pytest this is not a test class
|
|
16
|
+
|
|
17
|
+
name: str
|
|
18
|
+
path: str
|
|
19
|
+
status: str
|
|
20
|
+
duration: float
|
|
21
|
+
message: str | None
|
|
22
|
+
stdout: str | None
|
|
23
|
+
stderr: str | None
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def from_py(cls, result: rust.PyTestResult) -> "TestResult":
|
|
27
|
+
return cls(
|
|
28
|
+
name=result.name,
|
|
29
|
+
path=result.path,
|
|
30
|
+
status=result.status,
|
|
31
|
+
duration=result.duration,
|
|
32
|
+
message=result.message,
|
|
33
|
+
stdout=result.stdout,
|
|
34
|
+
stderr=result.stderr,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(slots=True)
|
|
39
|
+
class RunReport:
|
|
40
|
+
"""Aggregate statistics for an entire test session."""
|
|
41
|
+
|
|
42
|
+
total: int
|
|
43
|
+
passed: int
|
|
44
|
+
failed: int
|
|
45
|
+
skipped: int
|
|
46
|
+
duration: float
|
|
47
|
+
results: tuple[TestResult, ...]
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def from_py(cls, report: rust.PyRunReport) -> "RunReport":
|
|
51
|
+
return cls(
|
|
52
|
+
total=report.total,
|
|
53
|
+
passed=report.passed,
|
|
54
|
+
failed=report.failed,
|
|
55
|
+
skipped=report.skipped,
|
|
56
|
+
duration=report.duration,
|
|
57
|
+
results=tuple(TestResult.from_py(result) for result in report.results),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def iter_status(self, status: str) -> Iterable[TestResult]:
|
|
61
|
+
"""Yield results with the requested status."""
|
|
62
|
+
|
|
63
|
+
return (result for result in self.results if result.status == status)
|
|
Binary file
|
rustest/rust.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Fallback stub for the compiled rustest extension.
|
|
2
|
+
|
|
3
|
+
This module is packaged with the Python distribution so unit tests can import the
|
|
4
|
+
package without building the Rust extension. Individual tests are expected to
|
|
5
|
+
monkeypatch the functions they exercise.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any, Sequence
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def run(
|
|
14
|
+
_paths: Sequence[str],
|
|
15
|
+
_pattern: str | None,
|
|
16
|
+
_workers: int | None,
|
|
17
|
+
_capture_output: bool,
|
|
18
|
+
) -> Any:
|
|
19
|
+
"""Placeholder implementation that mirrors the extension signature."""
|
|
20
|
+
|
|
21
|
+
raise NotImplementedError(
|
|
22
|
+
"The rustest native extension is unavailable. Tests must patch rustest.rust.run."
|
|
23
|
+
)
|
rustest/rust.pyi
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Type stubs for the rustest Rust extension module."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Sequence
|
|
6
|
+
|
|
7
|
+
class PyTestResult:
|
|
8
|
+
"""Individual test result from the Rust extension."""
|
|
9
|
+
|
|
10
|
+
name: str
|
|
11
|
+
path: str
|
|
12
|
+
status: str
|
|
13
|
+
duration: float
|
|
14
|
+
message: str | None
|
|
15
|
+
stdout: str | None
|
|
16
|
+
stderr: str | None
|
|
17
|
+
|
|
18
|
+
class PyRunReport:
|
|
19
|
+
"""Test run report from the Rust extension."""
|
|
20
|
+
|
|
21
|
+
total: int
|
|
22
|
+
passed: int
|
|
23
|
+
failed: int
|
|
24
|
+
skipped: int
|
|
25
|
+
duration: float
|
|
26
|
+
results: list[PyTestResult]
|
|
27
|
+
|
|
28
|
+
def run(
|
|
29
|
+
paths: Sequence[str],
|
|
30
|
+
pattern: str | None,
|
|
31
|
+
mark_expr: str | None,
|
|
32
|
+
workers: int | None,
|
|
33
|
+
capture_output: bool,
|
|
34
|
+
enable_codeblocks: bool,
|
|
35
|
+
last_failed_mode: str,
|
|
36
|
+
fail_fast: bool,
|
|
37
|
+
pytest_compat: bool,
|
|
38
|
+
verbose: bool,
|
|
39
|
+
ascii: bool,
|
|
40
|
+
no_color: bool,
|
|
41
|
+
) -> PyRunReport:
|
|
42
|
+
"""Execute tests and return a report."""
|
|
43
|
+
...
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rustest
|
|
3
|
+
Version: 0.14.0
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Programming Language :: Rust
|
|
14
|
+
Classifier: Topic :: Software Development :: Testing
|
|
15
|
+
Requires-Dist: typing-extensions>=4.15
|
|
16
|
+
Requires-Dist: basedpyright>=1.19 ; extra == 'dev'
|
|
17
|
+
Requires-Dist: maturin>=1.4,<2 ; extra == 'dev'
|
|
18
|
+
Requires-Dist: packaging>=20.0 ; extra == 'dev'
|
|
19
|
+
Requires-Dist: poethepoet>=0.22 ; extra == 'dev'
|
|
20
|
+
Requires-Dist: pre-commit>=3.5 ; extra == 'dev'
|
|
21
|
+
Requires-Dist: py>=1.11 ; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest>=7.0 ; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest-asyncio>=1.2.0 ; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-codeblocks>=0.17.0 ; extra == 'dev'
|
|
25
|
+
Requires-Dist: ruff>=0.1.9 ; extra == 'dev'
|
|
26
|
+
Requires-Dist: zensical ; extra == 'docs'
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Provides-Extra: docs
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Summary: Rust powered pytest-compatible runner
|
|
31
|
+
Author: rustest contributors
|
|
32
|
+
Requires-Python: >=3.10
|
|
33
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
34
|
+
Project-URL: Homepage, https://github.com/Apex-Engineers-Inc/rustest
|
|
35
|
+
Project-URL: Repository, https://github.com/Apex-Engineers-Inc/rustest
|
|
36
|
+
Project-URL: Documentation, https://apex-engineers-inc.github.io/rustest
|
|
37
|
+
|
|
38
|
+
<div align="center">
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
Rustest is a Rust-powered pytest-compatible test runner delivering **8.5× average speedup** with familiar pytest syntax and zero setup.
|
|
45
|
+
|
|
46
|
+
📚 **[Full Documentation](https://apex-engineers-inc.github.io/rustest)** | [Getting Started](https://apex-engineers-inc.github.io/rustest/getting-started/quickstart/) | [Migration Guide](https://apex-engineers-inc.github.io/rustest/from-pytest/migration/)
|
|
47
|
+
|
|
48
|
+
## 🚀 Try It Now
|
|
49
|
+
|
|
50
|
+
Run your existing pytest tests with rustest — no code changes required:
|
|
51
|
+
|
|
52
|
+
<!--pytest.mark.skip-->
|
|
53
|
+
```bash
|
|
54
|
+
pip install rustest
|
|
55
|
+
rustest --pytest-compat tests/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
See the speedup immediately, then migrate to native rustest for full features.
|
|
59
|
+
|
|
60
|
+
## Why Rustest?
|
|
61
|
+
|
|
62
|
+
- 🚀 **8.5× average speedup** over pytest (up to 19× on large suites)
|
|
63
|
+
- 🧪 **pytest-compatible** — Run existing tests with `--pytest-compat`
|
|
64
|
+
- ✅ **Familiar API** — Same `@fixture`, `@parametrize`, `@mark` decorators
|
|
65
|
+
- 🔄 **Built-in async & mocking** — No pytest-asyncio or pytest-mock plugins needed
|
|
66
|
+
- 🐛 **Clear error messages** — Vitest-style output with Expected/Received diffs
|
|
67
|
+
- 📝 **Markdown testing** — Test code blocks in documentation
|
|
68
|
+
- 🛠️ **Rich fixtures** — `tmp_path`, `monkeypatch`, `mocker`, `capsys`, `caplog`, `cache`, and more
|
|
69
|
+
|
|
70
|
+
## Performance
|
|
71
|
+
|
|
72
|
+
Rustest delivers consistent speedups across test suites of all sizes:
|
|
73
|
+
|
|
74
|
+
| Test Count | pytest | rustest | Speedup |
|
|
75
|
+
|-----------:|-------:|--------:|--------:|
|
|
76
|
+
| 20 | 0.45s | 0.12s | 3.8× |
|
|
77
|
+
| 500 | 1.21s | 0.15s | 8.3× |
|
|
78
|
+
| 5,000 | 7.81s | 0.40s | 19.4× |
|
|
79
|
+
|
|
80
|
+
**Expected speedups:** 3-4× for small suites, 5-8× for medium suites, 11-19× for large suites.
|
|
81
|
+
|
|
82
|
+
**[📊 Full Performance Analysis →](https://apex-engineers-inc.github.io/rustest/advanced/performance/)**
|
|
83
|
+
|
|
84
|
+
## Installation
|
|
85
|
+
|
|
86
|
+
<!--pytest.mark.skip-->
|
|
87
|
+
```bash
|
|
88
|
+
pip install rustest
|
|
89
|
+
# or
|
|
90
|
+
uv add rustest
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Python 3.10-3.14 supported.** [📖 Installation Guide →](https://apex-engineers-inc.github.io/rustest/getting-started/installation/)
|
|
94
|
+
|
|
95
|
+
## Quick Start
|
|
96
|
+
|
|
97
|
+
Write a test in `test_example.py`:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from rustest import fixture, parametrize, mark, raises
|
|
101
|
+
|
|
102
|
+
@fixture
|
|
103
|
+
def numbers():
|
|
104
|
+
return [1, 2, 3, 4, 5]
|
|
105
|
+
|
|
106
|
+
def test_sum(numbers):
|
|
107
|
+
assert sum(numbers) == 15
|
|
108
|
+
|
|
109
|
+
@parametrize("value,expected", [(2, 4), (3, 9)])
|
|
110
|
+
def test_square(value, expected):
|
|
111
|
+
assert value ** 2 == expected
|
|
112
|
+
|
|
113
|
+
@mark.asyncio
|
|
114
|
+
async def test_async():
|
|
115
|
+
result = 42
|
|
116
|
+
assert result == 42
|
|
117
|
+
|
|
118
|
+
def test_exception():
|
|
119
|
+
with raises(ZeroDivisionError):
|
|
120
|
+
1 / 0
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Run your tests:
|
|
124
|
+
|
|
125
|
+
<!--pytest.mark.skip-->
|
|
126
|
+
```bash
|
|
127
|
+
rustest # Run all tests
|
|
128
|
+
rustest tests/ # Run specific directory
|
|
129
|
+
rustest -k "test_sum" # Filter by name
|
|
130
|
+
rustest -m "slow" # Filter by mark
|
|
131
|
+
rustest --lf # Rerun last failed
|
|
132
|
+
rustest -x # Exit on first failure
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**[📖 Full Documentation →](https://apex-engineers-inc.github.io/rustest)**
|
|
136
|
+
|
|
137
|
+
## Learn More
|
|
138
|
+
|
|
139
|
+
- **[Getting Started](https://apex-engineers-inc.github.io/rustest/getting-started/quickstart/)** — Complete quickstart guide
|
|
140
|
+
- **[Migration from pytest](https://apex-engineers-inc.github.io/rustest/from-pytest/migration/)** — 5-minute migration guide
|
|
141
|
+
- **[User Guide](https://apex-engineers-inc.github.io/rustest/guide/writing-tests/)** — Fixtures, parametrization, marks, assertions
|
|
142
|
+
- **[API Reference](https://apex-engineers-inc.github.io/rustest/api/overview/)** — Complete API documentation
|
|
143
|
+
|
|
144
|
+
## Contributing
|
|
145
|
+
|
|
146
|
+
Contributions welcome! See the [Development Guide](https://apex-engineers-inc.github.io/rustest/advanced/development/) for setup instructions.
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
|
151
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
rustest-0.14.0.dist-info/METADATA,sha256=8xmM0nheAoAgm-JHbIe5mRPVjEmrAGwyZuXcVAfP9KE,5338
|
|
2
|
+
rustest-0.14.0.dist-info/WHEEL,sha256=WjzAfvqut_Q5Xaf14OBgb9ZsnYHdVRd7o0GDAayVL0I,105
|
|
3
|
+
rustest-0.14.0.dist-info/entry_points.txt,sha256=7fUa3LO8vudQ4dKG1sTRaDnxcMdBSZsWs9EyuxFQ7Lk,48
|
|
4
|
+
rustest-0.14.0.dist-info/licenses/LICENSE,sha256=s64ibUGtb6jEDBsYuxUFtMr_c4PaqYP-vj3YY6QtTGw,1075
|
|
5
|
+
rustest/__init__.py,sha256=eg_pai6AXfe-F-GVaSPcbBVfW0yyJ7NKBLK1Sy5yTLQ,841
|
|
6
|
+
rustest/__main__.py,sha256=bBvo5gsSluUzlDTDvn5bP_gZZEXMwJQZMqVA5W1M1v8,178
|
|
7
|
+
rustest/approx.py,sha256=tHDkWqNQAj94eXsBclFcOukc169qiWuZTSh2-rCjz9c,6455
|
|
8
|
+
rustest/builtin_fixtures.py,sha256=3wNdhSV_LjlroCgMV0VKDN6ZpbWiUlDFh6M6umqUcuU,36322
|
|
9
|
+
rustest/cli.py,sha256=ZYBxpimBZEaBhmL-PI1XFz50FWPvqxaYslbhETrQpns,3870
|
|
10
|
+
rustest/compat/__init__.py,sha256=seRdlvStizCfkarfll8aIS_eikEK2V9kjlnJY6iiWA4,70
|
|
11
|
+
rustest/compat/pytest.py,sha256=UgNNEDj9Amhl-M8J74XSth6k6es8kKyC3uUMA8QobzM,37214
|
|
12
|
+
rustest/core.py,sha256=IJHo-z60MPnJtCZS1ha1yjRN0XJ9IPvnGlnKC5Ai50Y,1953
|
|
13
|
+
rustest/decorators.py,sha256=mxZAYHsBeZfpsDVCd65sPrYzjurvf32eFBKjPMy9De4,34416
|
|
14
|
+
rustest/fixture_registry.py,sha256=Rs7_wxBSox5XUWW5Mpb84Lcy3tjZuGxzsOJkYOxPmHI,4339
|
|
15
|
+
rustest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
rustest/reporting.py,sha256=3-R8aljv2ZbmjOa9Q9KZeCPsMaitm8nZ96LoJS_NnUQ,1623
|
|
17
|
+
rustest/rust.cpython-313-darwin.so,sha256=8PhJ2VJlQyljyXOPQzefgBL3oYA9mUdEHsyI22mz6FA,2413712
|
|
18
|
+
rustest/rust.py,sha256=tCIvjYd06VxoT_rKvv2o8CpXW_pFNua5VgcRDjLgU78,659
|
|
19
|
+
rustest/rust.pyi,sha256=QCEy3Qc8pZqOSUR7cgsWnTQThgQVcsKrM1skpGVMCgc,891
|
|
20
|
+
rustest-0.14.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Apex Engineers Inc
|
|
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.
|