pytest-quantum 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.
- pytest_quantum-0.1.0/.github/workflows/ci.yml +138 -0
- pytest_quantum-0.1.0/.github/workflows/publish.yml +37 -0
- pytest_quantum-0.1.0/.gitignore +46 -0
- pytest_quantum-0.1.0/CONTRIBUTING.md +182 -0
- pytest_quantum-0.1.0/LICENSE +21 -0
- pytest_quantum-0.1.0/PKG-INFO +287 -0
- pytest_quantum-0.1.0/README.md +236 -0
- pytest_quantum-0.1.0/docs/_static/.gitkeep +0 -0
- pytest_quantum-0.1.0/docs/api.md +63 -0
- pytest_quantum-0.1.0/docs/assertions.md +706 -0
- pytest_quantum-0.1.0/docs/changelog.md +28 -0
- pytest_quantum-0.1.0/docs/conf.py +46 -0
- pytest_quantum-0.1.0/docs/contributing.md +25 -0
- pytest_quantum-0.1.0/docs/fixtures.md +431 -0
- pytest_quantum-0.1.0/docs/getting-started.md +257 -0
- pytest_quantum-0.1.0/docs/index.md +42 -0
- pytest_quantum-0.1.0/docs/stats.md +433 -0
- pytest_quantum-0.1.0/pyproject.toml +162 -0
- pytest_quantum-0.1.0/src/pytest_quantum/__init__.py +81 -0
- pytest_quantum-0.1.0/src/pytest_quantum/assertions/__init__.py +29 -0
- pytest_quantum-0.1.0/src/pytest_quantum/assertions/distributions.py +173 -0
- pytest_quantum-0.1.0/src/pytest_quantum/assertions/states.py +128 -0
- pytest_quantum-0.1.0/src/pytest_quantum/assertions/structure.py +219 -0
- pytest_quantum-0.1.0/src/pytest_quantum/assertions/unitary.py +195 -0
- pytest_quantum-0.1.0/src/pytest_quantum/converters/__init__.py +11 -0
- pytest_quantum-0.1.0/src/pytest_quantum/converters/to_unitary.py +163 -0
- pytest_quantum-0.1.0/src/pytest_quantum/fixtures/__init__.py +33 -0
- pytest_quantum-0.1.0/src/pytest_quantum/plugin.py +361 -0
- pytest_quantum-0.1.0/src/pytest_quantum/py.typed +0 -0
- pytest_quantum-0.1.0/src/pytest_quantum/stats/__init__.py +20 -0
- pytest_quantum-0.1.0/src/pytest_quantum/stats/shots.py +107 -0
- pytest_quantum-0.1.0/src/pytest_quantum/stats/tests.py +190 -0
- pytest_quantum-0.1.0/tests/conftest.py +11 -0
- pytest_quantum-0.1.0/tests/test_assertions_distributions.py +106 -0
- pytest_quantum-0.1.0/tests/test_assertions_states.py +75 -0
- pytest_quantum-0.1.0/tests/test_assertions_structure.py +88 -0
- pytest_quantum-0.1.0/tests/test_assertions_unitary.py +191 -0
- pytest_quantum-0.1.0/tests/test_integration_cirq.py +120 -0
- pytest_quantum-0.1.0/tests/test_integration_cross_framework.py +149 -0
- pytest_quantum-0.1.0/tests/test_integration_noise.py +93 -0
- pytest_quantum-0.1.0/tests/test_integration_pennylane.py +184 -0
- pytest_quantum-0.1.0/tests/test_integration_qiskit.py +283 -0
- pytest_quantum-0.1.0/tests/test_plugin.py +113 -0
- pytest_quantum-0.1.0/tests/test_stats.py +195 -0
- pytest_quantum-0.1.0/uv.lock +2835 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
# -------------------------------------------------------------------------
|
|
11
|
+
# Lint + type check (fast, runs on every push)
|
|
12
|
+
# -------------------------------------------------------------------------
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint & type check
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
- name: Ruff lint
|
|
22
|
+
run: uv run --group dev ruff check src/ tests/
|
|
23
|
+
- name: Ruff format check
|
|
24
|
+
run: uv run --group dev ruff format --check src/ tests/
|
|
25
|
+
- name: Mypy
|
|
26
|
+
run: uv run --group dev mypy src/
|
|
27
|
+
|
|
28
|
+
# -------------------------------------------------------------------------
|
|
29
|
+
# Core tests (no quantum SDK) — fast, runs on all platforms + Python versions
|
|
30
|
+
# -------------------------------------------------------------------------
|
|
31
|
+
test-core:
|
|
32
|
+
name: Core tests (Python ${{ matrix.python-version }}, ${{ matrix.os }})
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
fail-fast: false
|
|
36
|
+
matrix:
|
|
37
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
38
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
- uses: astral-sh/setup-uv@v5
|
|
42
|
+
with:
|
|
43
|
+
enable-cache: true
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
45
|
+
- name: Install core dependencies only
|
|
46
|
+
run: uv sync --no-group dev
|
|
47
|
+
- name: Run core tests
|
|
48
|
+
run: uv run pytest tests/test_stats.py tests/test_plugin.py tests/test_assertions_states.py tests/test_assertions_distributions.py tests/test_assertions_unitary.py tests/test_assertions_structure.py -v --cov=pytest_quantum --cov-report=xml
|
|
49
|
+
- name: Upload coverage
|
|
50
|
+
uses: codecov/codecov-action@v5
|
|
51
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
52
|
+
with:
|
|
53
|
+
files: ./coverage.xml
|
|
54
|
+
|
|
55
|
+
# -------------------------------------------------------------------------
|
|
56
|
+
# Qiskit integration tests
|
|
57
|
+
# -------------------------------------------------------------------------
|
|
58
|
+
test-qiskit:
|
|
59
|
+
name: Qiskit integration tests
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
- uses: astral-sh/setup-uv@v5
|
|
64
|
+
with:
|
|
65
|
+
enable-cache: true
|
|
66
|
+
python-version: "3.12"
|
|
67
|
+
- name: Install with Qiskit extras
|
|
68
|
+
run: uv sync --extra qiskit
|
|
69
|
+
- name: Run Qiskit tests
|
|
70
|
+
run: uv run pytest tests/test_integration_qiskit.py tests/test_integration_noise.py tests/test_assertions_structure.py tests/test_assertions_unitary.py -v
|
|
71
|
+
|
|
72
|
+
# -------------------------------------------------------------------------
|
|
73
|
+
# Cirq integration tests
|
|
74
|
+
# -------------------------------------------------------------------------
|
|
75
|
+
test-cirq:
|
|
76
|
+
name: Cirq integration tests
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- uses: astral-sh/setup-uv@v5
|
|
81
|
+
with:
|
|
82
|
+
enable-cache: true
|
|
83
|
+
python-version: "3.12"
|
|
84
|
+
- name: Install with Cirq extras
|
|
85
|
+
run: uv sync --extra cirq
|
|
86
|
+
- name: Run Cirq tests
|
|
87
|
+
run: uv run pytest tests/test_integration_cirq.py -v
|
|
88
|
+
|
|
89
|
+
# -------------------------------------------------------------------------
|
|
90
|
+
# Cross-framework tests (needs both Qiskit + Cirq)
|
|
91
|
+
# -------------------------------------------------------------------------
|
|
92
|
+
test-cross-framework:
|
|
93
|
+
name: Cross-framework tests
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@v4
|
|
97
|
+
- uses: astral-sh/setup-uv@v5
|
|
98
|
+
with:
|
|
99
|
+
enable-cache: true
|
|
100
|
+
python-version: "3.12"
|
|
101
|
+
- name: Install Qiskit + Cirq
|
|
102
|
+
run: uv sync --extra qiskit --extra cirq
|
|
103
|
+
- name: Run cross-framework tests
|
|
104
|
+
run: uv run pytest tests/test_integration_cross_framework.py -v
|
|
105
|
+
|
|
106
|
+
# -------------------------------------------------------------------------
|
|
107
|
+
# PennyLane integration tests
|
|
108
|
+
# -------------------------------------------------------------------------
|
|
109
|
+
test-pennylane:
|
|
110
|
+
name: PennyLane integration tests
|
|
111
|
+
runs-on: ubuntu-latest
|
|
112
|
+
steps:
|
|
113
|
+
- uses: actions/checkout@v4
|
|
114
|
+
- uses: astral-sh/setup-uv@v5
|
|
115
|
+
with:
|
|
116
|
+
enable-cache: true
|
|
117
|
+
python-version: "3.12"
|
|
118
|
+
- name: Install with PennyLane extras
|
|
119
|
+
run: uv sync --extra pennylane
|
|
120
|
+
- name: Run PennyLane tests
|
|
121
|
+
run: uv run pytest tests/test_integration_pennylane.py -v
|
|
122
|
+
|
|
123
|
+
# -------------------------------------------------------------------------
|
|
124
|
+
# Graphix integration tests
|
|
125
|
+
# -------------------------------------------------------------------------
|
|
126
|
+
test-graphix:
|
|
127
|
+
name: Graphix integration tests
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
steps:
|
|
130
|
+
- uses: actions/checkout@v4
|
|
131
|
+
- uses: astral-sh/setup-uv@v5
|
|
132
|
+
with:
|
|
133
|
+
enable-cache: true
|
|
134
|
+
python-version: "3.12"
|
|
135
|
+
- name: Install with Graphix extras
|
|
136
|
+
run: uv sync --extra graphix
|
|
137
|
+
- name: Run Graphix tests
|
|
138
|
+
run: uv run pytest tests/test_assertions_states.py tests/test_stats.py -v
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*" # triggers on tags like v0.1.0
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
- name: Build wheel + sdist
|
|
16
|
+
run: uv build
|
|
17
|
+
- uses: actions/upload-artifact@v4
|
|
18
|
+
with:
|
|
19
|
+
name: dist
|
|
20
|
+
path: dist/
|
|
21
|
+
|
|
22
|
+
publish:
|
|
23
|
+
name: Publish to PyPI
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
environment:
|
|
27
|
+
name: pypi
|
|
28
|
+
url: https://pypi.org/p/pytest-quantum
|
|
29
|
+
permissions:
|
|
30
|
+
id-token: write # OIDC trusted publishing — no API token needed
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/download-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: dist
|
|
35
|
+
path: dist/
|
|
36
|
+
- name: Publish
|
|
37
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
*.pyd
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
wheels/
|
|
8
|
+
*.egg-info/
|
|
9
|
+
|
|
10
|
+
# Virtual environments
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
|
|
14
|
+
# uv
|
|
15
|
+
.uv/
|
|
16
|
+
|
|
17
|
+
# pytest
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.cache/
|
|
20
|
+
|
|
21
|
+
# mypy
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
|
|
24
|
+
# ruff
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
|
|
27
|
+
# Coverage
|
|
28
|
+
.coverage
|
|
29
|
+
.coverage.*
|
|
30
|
+
htmlcov/
|
|
31
|
+
coverage.xml
|
|
32
|
+
|
|
33
|
+
# IDE
|
|
34
|
+
.idea/
|
|
35
|
+
.vscode/
|
|
36
|
+
*.swp
|
|
37
|
+
*.swo
|
|
38
|
+
.DS_Store
|
|
39
|
+
|
|
40
|
+
# Sphinx docs build output
|
|
41
|
+
docs/_build/
|
|
42
|
+
|
|
43
|
+
# Quantum SDK artifacts
|
|
44
|
+
*.qasm
|
|
45
|
+
*.quil
|
|
46
|
+
*.braket
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Contributing to pytest-quantum
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing. This document covers everything you need to get set up, run tests, and submit a pull request.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Python 3.11 or 3.12
|
|
10
|
+
- [uv](https://docs.astral.sh/uv/) (fast Python package manager — replaces pip/venv)
|
|
11
|
+
|
|
12
|
+
Install uv if you don't have it:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/qbench/pytest-quantum
|
|
24
|
+
cd pytest-quantum
|
|
25
|
+
|
|
26
|
+
# Create virtual environment and install all dependencies (all quantum SDKs + dev tools)
|
|
27
|
+
uv sync --all-extras --group dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
That's it. `uv sync` creates `.venv/` and installs everything.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Running tests
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Full test suite (111+ tests across all frameworks)
|
|
38
|
+
uv run pytest
|
|
39
|
+
|
|
40
|
+
# Only unit tests (no quantum SDK needed — fast, < 1s)
|
|
41
|
+
uv run pytest tests/test_stats.py tests/test_assertions_distributions.py \
|
|
42
|
+
tests/test_assertions_states.py tests/test_assertions_structure.py
|
|
43
|
+
|
|
44
|
+
# Integration tests only (real quantum circuits)
|
|
45
|
+
uv run pytest tests/test_integration_qiskit.py tests/test_integration_cirq.py \
|
|
46
|
+
tests/test_integration_cross_framework.py \
|
|
47
|
+
tests/test_integration_pennylane.py tests/test_integration_noise.py
|
|
48
|
+
|
|
49
|
+
# Include slow shot-heavy tests
|
|
50
|
+
uv run pytest --quantum-slow
|
|
51
|
+
|
|
52
|
+
# With coverage report
|
|
53
|
+
uv run pytest --cov=pytest_quantum --cov-report=term-missing
|
|
54
|
+
|
|
55
|
+
# Run a specific test file
|
|
56
|
+
uv run pytest tests/test_stats.py -v
|
|
57
|
+
|
|
58
|
+
# Run a specific test by name
|
|
59
|
+
uv run pytest -k "test_bell_state_distribution" -v
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Linting and type checking
|
|
65
|
+
|
|
66
|
+
All three must pass before a PR is merged.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Linter + formatter (ruff does both)
|
|
70
|
+
uv run ruff check src/ tests/ # check
|
|
71
|
+
uv run ruff check src/ tests/ --fix # auto-fix what's fixable
|
|
72
|
+
uv run ruff format src/ tests/ # format
|
|
73
|
+
|
|
74
|
+
# Type checker (strict mypy — no Any leakage in public API)
|
|
75
|
+
uv run mypy src/
|
|
76
|
+
|
|
77
|
+
# Run all three at once
|
|
78
|
+
uv run ruff check src/ tests/ && uv run ruff format --check src/ tests/ && uv run mypy src/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Building docs
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Install docs dependencies
|
|
87
|
+
uv sync --group docs
|
|
88
|
+
|
|
89
|
+
# Build HTML docs
|
|
90
|
+
uv run sphinx-build docs docs/_build/html
|
|
91
|
+
|
|
92
|
+
# Open in browser (macOS)
|
|
93
|
+
open docs/_build/html/index.html
|
|
94
|
+
|
|
95
|
+
# Auto-rebuild on change (requires sphinx-autobuild)
|
|
96
|
+
uv run sphinx-autobuild docs docs/_build/html
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Project structure
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
src/pytest_quantum/
|
|
105
|
+
├── __init__.py # public API — everything users import
|
|
106
|
+
├── plugin.py # pytest entry point: markers, CLI options, all fixtures
|
|
107
|
+
├── assertions/
|
|
108
|
+
│ ├── distributions.py # assert_measurement_distribution, assert_counts_close
|
|
109
|
+
│ ├── states.py # assert_state_fidelity_above, assert_states_close
|
|
110
|
+
│ ├── structure.py # assert_circuit_depth, assert_circuit_width, assert_gate_count
|
|
111
|
+
│ └── unitary.py # assert_unitary, assert_circuits_equivalent
|
|
112
|
+
├── converters/
|
|
113
|
+
│ └── to_unitary.py # any circuit → numpy unitary matrix
|
|
114
|
+
└── stats/
|
|
115
|
+
├── shots.py # min_shots, recommended_shots
|
|
116
|
+
└── tests.py # fidelity, tvd, tvd_from_counts, chi_square_test
|
|
117
|
+
|
|
118
|
+
tests/
|
|
119
|
+
├── test_stats.py # pure math tests, no SDKs needed
|
|
120
|
+
├── test_assertions_*.py # unit tests (mock-based)
|
|
121
|
+
├── test_plugin.py # pytester-based plugin tests
|
|
122
|
+
├── test_integration_qiskit.py # real Qiskit + AerSimulator
|
|
123
|
+
├── test_integration_cirq.py # real Cirq
|
|
124
|
+
├── test_integration_cross_framework.py # Qiskit vs Cirq equivalence
|
|
125
|
+
├── test_integration_pennylane.py # real PennyLane
|
|
126
|
+
└── test_integration_noise.py # depolarizing noise fixture
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Adding support for a new framework
|
|
132
|
+
|
|
133
|
+
1. Add the import detection to `converters/to_unitary.py` — add a `_is_<framework>` function and `_from_<framework>` converter.
|
|
134
|
+
2. Add a fixture to `plugin.py` following the same `scope="session"` pattern.
|
|
135
|
+
3. Add the optional dependency to `pyproject.toml` under `[project.optional-dependencies]`.
|
|
136
|
+
4. Add integration tests to `tests/test_integration_<framework>.py`.
|
|
137
|
+
5. Update `README.md` and `docs/fixtures.md`.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Adding a new assertion
|
|
142
|
+
|
|
143
|
+
1. Add the function to the appropriate file in `src/pytest_quantum/assertions/`.
|
|
144
|
+
2. Register assert rewriting in `__init__.py` (already done for all modules).
|
|
145
|
+
3. Export from `__init__.py` (`from pytest_quantum.assertions.X import ...` and add to `__all__`).
|
|
146
|
+
4. Add unit tests in the corresponding `tests/test_assertions_*.py`.
|
|
147
|
+
5. Add integration tests that use real circuits.
|
|
148
|
+
6. Update `docs/assertions.md`.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Code style
|
|
153
|
+
|
|
154
|
+
- Type annotations required everywhere (`mypy --strict`).
|
|
155
|
+
- Google-style docstrings on every public function.
|
|
156
|
+
- `from __future__ import annotations` at the top of every file.
|
|
157
|
+
- Optional SDK imports must be inside functions (lazy imports) — never at module level.
|
|
158
|
+
- All assertions must produce clear, human-readable error messages with observed vs expected values.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Pull request checklist
|
|
163
|
+
|
|
164
|
+
- [ ] `uv run pytest` passes (136+ tests)
|
|
165
|
+
- [ ] `uv run ruff check src/ tests/` passes
|
|
166
|
+
- [ ] `uv run mypy src/` passes
|
|
167
|
+
- [ ] New assertion or fixture has integration test with a real circuit
|
|
168
|
+
- [ ] Docstring updated with example
|
|
169
|
+
- [ ] `docs/` updated if public API changed
|
|
170
|
+
- [ ] `CHANGELOG.md` entry added under an `Unreleased` section
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Reporting bugs
|
|
175
|
+
|
|
176
|
+
Open an issue at https://github.com/qbench/pytest-quantum/issues with:
|
|
177
|
+
|
|
178
|
+
- Python version (`python --version`)
|
|
179
|
+
- pytest-quantum version (`pip show pytest-quantum`)
|
|
180
|
+
- Quantum SDK versions (e.g. `pip show qiskit qiskit-aer`)
|
|
181
|
+
- Minimal reproducible example
|
|
182
|
+
- Full error output
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qbench
|
|
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.
|