From ac388d143d9499b0e9705de34db03c0993da91d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Mon, 8 Apr 2024 15:41:56 +0200 Subject: [PATCH] Initial version of docs + rename (#5) * Add docs stub * Add language server info to mkdocs.yml * Add basic docs structure * Add basic program/circuit example * Add short desription of QART format * Add API reference * Update mkdocs.yml * Remove copyright notices * Rename hqar package to qart * Remove copyright checks * Remove remaining copyright notices * Reorganize chapter on QART Python library * Add content to index.md * Add required plugins * Reorganize docs for python library * Remove whitespace * Update example yaml and svg (my_algorithm -> my_program) * Add basic development guide * Update links in index.md * Add docs-related dependencies * Add more descriptions to format chapter * Add job for building docs * Attempt running mkdocs through poetry run * Add missing dependency on mkdocstrings * Apply changes suggested in the review * Add missing images --- .flake8 | 4 - .github/workflows/quality_checks.yaml | 16 + .pre-commit-config.yaml | 1 - README.md | 44 +- docs/development.md | 37 + docs/examples/basic_circuit.svg | 136 ++++ docs/examples/basic_program.json | 97 +++ docs/examples/basic_program.pdf | Bin 0 -> 29962 bytes docs/examples/basic_program.yaml | 27 + docs/format.md | 134 ++++ docs/images/basic_circuit.svg | 136 ++++ docs/images/basic_program.svg | 97 +++ docs/index.md | 41 + .../reference/qart.experimental.rendering.md | 3 + docs/library/reference/qart.md | 6 + docs/library/userguide.md | 78 ++ example_routine.svg | 78 +- example_routine.yaml | 2 +- mkdocs.yml | 57 ++ poetry.lock | 740 +++++++++++++++++- pyproject.toml | 14 +- src/{hqar => qart}/__init__.py | 12 +- src/{hqar => qart}/_schema_v1.py | 13 +- src/{hqar => qart}/experimental/__init__.py | 0 src/{hqar => qart}/experimental/rendering.py | 11 +- tests/conftest.py | 12 +- tests/hqar/experimental/test_rendering.py | 33 - .../data/invalid_program_examples.yaml | 0 .../data/valid_programs/example_0.yaml | 0 .../data/valid_programs/example_1.yaml | 0 .../data/valid_programs/example_2.yaml | 0 .../data/valid_programs/example_3.yaml | 0 tests/qart/experimental/test_rendering.py | 23 + .../{hqar => qart}/test_schema_validation.py | 14 +- 34 files changed, 1707 insertions(+), 159 deletions(-) create mode 100644 docs/development.md create mode 100644 docs/examples/basic_circuit.svg create mode 100644 docs/examples/basic_program.json create mode 100644 docs/examples/basic_program.pdf create mode 100644 docs/examples/basic_program.yaml create mode 100644 docs/format.md create mode 100644 docs/images/basic_circuit.svg create mode 100644 docs/images/basic_program.svg create mode 100644 docs/index.md create mode 100644 docs/library/reference/qart.experimental.rendering.md create mode 100644 docs/library/reference/qart.md create mode 100644 docs/library/userguide.md create mode 100644 mkdocs.yml rename src/{hqar => qart}/__init__.py (60%) rename src/{hqar => qart}/_schema_v1.py (85%) rename src/{hqar => qart}/experimental/__init__.py (100%) rename src/{hqar => qart}/experimental/rendering.py (92%) delete mode 100644 tests/hqar/experimental/test_rendering.py rename tests/{hqar => qart}/data/invalid_program_examples.yaml (100%) rename tests/{hqar => qart}/data/valid_programs/example_0.yaml (100%) rename tests/{hqar => qart}/data/valid_programs/example_1.yaml (100%) rename tests/{hqar => qart}/data/valid_programs/example_2.yaml (100%) rename tests/{hqar => qart}/data/valid_programs/example_3.yaml (100%) create mode 100644 tests/qart/experimental/test_rendering.py rename tests/{hqar => qart}/test_schema_validation.py (71%) diff --git a/.flake8 b/.flake8 index 371c258..5f6e78d 100644 --- a/.flake8 +++ b/.flake8 @@ -25,7 +25,3 @@ ignore = per-file-ignores = tests/**/test_*.py:D103,D102,D101 __init__.py:F401 -copyright-check = True -copyright-regexp = Copyright\s+(©\s+)?\d{4}([-,]\d{4})*\s+%(author)s -copyright-author = PsiQuantum Corp. -copyright-min-file-size = 1 diff --git a/.github/workflows/quality_checks.yaml b/.github/workflows/quality_checks.yaml index 32152fa..0a1d82f 100644 --- a/.github/workflows/quality_checks.yaml +++ b/.github/workflows/quality_checks.yaml @@ -40,3 +40,19 @@ jobs: pre-commit run -a - name: Run mypy run: MYPYPATH=src poetry run mypy --install-types --non-interactive src + + test_docs_are_building: + runs-on: ubuntu-latest + steps: + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - uses: actions/checkout@v2 + - name: Setup poetry + uses: abatilo/actions-poetry@v2 + - name: Install package and deps + run: | + poetry install --with docs + - name: Build docs + run: poetry run mkdocs build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bc9350a..d20cd1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,4 +20,3 @@ repos: rev: 6.0.0 hooks: - id: flake8 - additional_dependencies: [flake8-copyright] diff --git a/README.md b/README.md index 7a73422..e885114 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,30 @@ -# HQAR -Hierarchical Quantum Algorithms Representation is an open format for representing +# QART +Quantum Algorithms Represented Topologically (QART) is an open format for representing quantum algorithms, optimized for usage in quantum resource estimation (QRE). -HQAR comprises: +QART comprises: - Definition of data format, formalized as a JSON schema. -- A Python library for validation of quantum programs written in HQAR format using [Pydantic](https://docs.pydantic.dev/). -- Rudimentary visualization tool `hqar-render`. +- A Python library for validation of quantum programs written in QART format using [Pydantic](https://docs.pydantic.dev/). +- Rudimentary visualization tool `qart-render`. ## Installation -Using HQAR data format does not require installation - you can easily write quantum +Using QART data format does not require installation - you can easily write quantum programs in YAML or JSON. -To install HQAR Python package, clone this repository and install it as usual with `pip`: +To install QART Python package, clone this repository and install it as usual with `pip`: ```bash -# Clone HQAR repo (you can use HTTP link as well) -git clone git@github.com:PsiQ/hqar.git -cd hqar +# Clone QART repo (you can use HTTP link as well) +git clone git@github.com:PsiQ/qart.git +cd qart pip install . ``` -## HQAR format +## QART format -HQAR format represents quantum programs as a hierarchical directed acyclic graphs (DAGs). +QART format represents quantum programs as a hierarchical directed acyclic graphs (DAGs). That's a mouthful, so let us unpack what it means: - *hierarchical*: each node can contain subgraphs, i.e. routines can be nested inside @@ -36,7 +36,7 @@ Consider the following hierarchical DAG of a hypothetical quantum program: ![program example](example_routine.svg) -It can be succinctly written in HQAR format as: +It can be succinctly written in QART format as: ```yaml @@ -103,21 +103,21 @@ program: ``` -For full description of HQAR format, check our [docs](https://example.com). +For full description of QART format, check our [docs](https://example.com). -## Using HQAR package +## Using QART package -### Using JSON schema for validating data in HQAR format +### Using JSON schema for validating data in QART format -JSON schema for HQAR format can be obtained by calling `generate_program_schema` function. +JSON schema for QART format can be obtained by calling `generate_program_schema` function. Such schema can be then used for validating user's input, e.g. using `jsonschema` package: ```python from jsonschema import validate -from hqar import generate_program_schema +from qart import generate_program_schema # Hypothetical function loading your data as native Python dictionary. -data = load_some_program() +data = load_some_program() schema = generate_program_schema() # This will raise if there are some validation errors. @@ -126,12 +126,12 @@ validate(schema, data) ### Validation using Pydantic models -If you are familiar with Pydantic, you might find it easier to work with HQAR Pydantic +If you are familiar with Pydantic, you might find it easier to work with QART Pydantic models instead of interacting with JSON schema directly. In the example below, we create -an instance of `SchemaV1` model from validated data stored in HQAR format: +an instance of `SchemaV1` model from validated data stored in QART format: ```python -from hqar import SchemaV1 +from qart import SchemaV1 data = load_some_program() diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000..78a9880 --- /dev/null +++ b/docs/development.md @@ -0,0 +1,37 @@ +# Development guide + +## Setting up development environment + +QART uses [Poetry](https://python-poetry.org/) for managing dependencies. +Therefore, we recommend you use Poetry to setup your environment. However, +if you insist on not using Poetry, the more traditional way of using +editable install with `pip` is still avaiable. + +### Using editable install with Poetry + +To setup your development environment install poetry (if you don't have it yet): + +```bash +pip install poetry +``` + +And then install the project and its dependencies: + +```bash +poetry install +``` + +### Using editable install with pip + +You can also develop Poetry using `pip`: + +```bash +pip install -e . +``` + +!!! Warning + + If you are planning to add/modify dependencies of QART, we + highly recommend you use Poetry instead of pip editable install. + Without Poetry, you will need to edit dependencies manually, + which is very error-prone. diff --git a/docs/examples/basic_circuit.svg b/docs/examples/basic_circuit.svg new file mode 100644 index 0000000..735cb3f --- /dev/null +++ b/docs/examples/basic_circuit.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/examples/basic_program.json b/docs/examples/basic_program.json new file mode 100644 index 0000000..eec661c --- /dev/null +++ b/docs/examples/basic_program.json @@ -0,0 +1,97 @@ +{ + "version": "v1", + "program": { + "name": "my_program", + "ports": [ + { + "direction": "input", + "name": "in_0", + "size": 1 + }, + { + "direction": "input", + "name": "in_1", + "size": 2 + }, + { + "direction": "output", + "name": "out", + "size": 3 + } + ], + "children": [ + { + "name": "subroutine_1", + "ports": [ + { + "direction": "input", + "name": "in", + "size": 1 + }, + { + "direction": "output", + "name": "out", + "size": 1 + } + ] + }, + { + "name": "subroutine_2", + "ports": [ + { + "direction": "input", + "name": "in", + "size": 2 + }, + { + "direction": "output", + "name": "out", + "size": 2 + } + ] + }, + { + "name": "merge", + "ports": [ + { + "direction": "input", + "name": "in_0", + "size": 1 + }, + { + "direction": "input", + "name": "in_1", + "size": 2 + }, + { + "direction": "output", + "name": "out", + "size": 3 + } + ] + } + ], + "connections": [ + { + "source": "in_0", + "target": "subroutine_1.in" + }, + { + "source": "in_1", + "target": "subroutine_2.in" + }, + { + "source": "subroutine_1.out", + "target": "merge.in_1" + }, + { + "source": "subroutine_2.out", + "target": "merge.in_0" + }, + { + "source": "merge.out", + "target": "out" + } + ] + } +} \ No newline at end of file diff --git a/docs/examples/basic_program.pdf b/docs/examples/basic_program.pdf new file mode 100644 index 0000000000000000000000000000000000000000..67993a1b85a1cb67a92f1b1590cfb2a51d89506e GIT binary patch literal 29962 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

>p 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 eaCl{3$gZ)2Nb`k&p literal 0 HcmV?d00001 diff --git a/docs/examples/basic_program.yaml b/docs/examples/basic_program.yaml new file mode 100644 index 0000000..317bd73 --- /dev/null +++ b/docs/examples/basic_program.yaml @@ -0,0 +1,27 @@ +version: v1 +program: + name: my_program + ports: + - {direction: input, name: in_0, size: 1} + - {direction: input, name: in_1, size: 2} + - {direction: output, name: out, size: 3} + children: + - name: subroutine_1 + ports: + - {direction: input, name: in, size: 1} + - {direction: output, name: out, size: 1} + - name: subroutine_2 + ports: + - {direction: input, name: in, size: 2} + - {direction: output, name: out, size: 2} + - name: merge + ports: + - {direction: input, name: in_0, size: 1} + - {direction: input, name: in_1, size: 2} + - {direction: output, name: out, size: 3} + connections: + - {source: in_0, target: subroutine_1.in} + - {source: in_1, target: subroutine_2.in} + - {source: subroutine_1.out, target: merge.in_1} + - {source: subroutine_2.out, target: merge.in_0} + - {source: merge.out, target: out} diff --git a/docs/format.md b/docs/format.md new file mode 100644 index 0000000..bf222a7 --- /dev/null +++ b/docs/format.md @@ -0,0 +1,134 @@ +# Data format + +## Introduction +QART format is a domain-specific language (DSL) for describing quantum algorithms +built on top of JSON for the purpose of resource estimation. + +In QART, the algorithms are described as programs comprising hierarchical, directed +acyclic graph (henceforth hierarchical DAGs) of subroutines. Let's break down +what this means: + +- *Hierarchical* means that routines can be nested. +- *Directed* means that every edge connecting two routines also defines in which + direction the information flows between them. +- *Acyclic* means that traversing the graph along its edges (respecting their direction) + will never lead to visiting the same node twice. + +Besides specifying the connectivity between routines in the algorithms, the QART format +also specifies how to store information relevant to resource estimation, such as +known and unknown resources, parameters that might affect them and how the parameters +propagate in the algorithm's graph. + +Before describing the format in detail, let us first exemplify its usage on a simple program. + +## Basic example + +In QART, the quantum programs are represented as graphs. If you are not used to +representing computations as graph, don't worry! Before describing QART format, +we'll demostrate how a simple circuit can be represented as a graph. + +Consider a hypothetical quantum program as depicted in the following circuit. + +![example_circuit](images/basic_circuit.svg){width="500"} + +Let's forget for a while that the depicted algorithm doesn't make much sense. +We can see that the circuit comprises two subroutines: + +- `subroutine_1` operating on a single-qubit register. +- `subroutine_2` operating on a two-qubit register. + +We also labelled inputs to the subroutines as `in_0` and `in_1`, and the whole +output of our program (i.e. combined outputs of both subroutines) as `out`. + +Representing such a circuit as a graph is straightforward, it might look like this: + +![example_routine](images/basic_program.svg) + +As we can see, the graph contains both subroutines form the original circuit, +and an artificially introduced `merge` operation used to combine outputs +from the subprograms into one final outputs. + +Now that we have our graph, let's see how it can be represented in QART format. +As already mentioned, QART format is built on top of JSON, so we can write QART +files in either JSON or YAML. For our examples, those might look as follows: + +=== "YAML" + + ```yaml + --8<-- "basic_program.yaml" + ``` + +=== "JSON" + + ```json + --8<-- "basic_program.json" + ``` + +Let's dissect our example. The top-level object has two mandatory properties: + +- `version`: Set to `v1` (which is the only version so far) +- `program`: This contains the actual description of the program. + +So what do we have in a `program` object? + +- `name`: Mandatory name of the program, here set to the string `my_program`. +- `ports`: A collection of ports. They roughly correspond to quantum registers. +- `children`: A list of children, or subroutines, of the program. +- `connections`: A list defining edges of our graph. + +### Ports + +Let us first take a look at ports, like the first input port of our program: + +```yaml +{direction: input, name: in_0, size: 1} +``` + +Ports, like most other components in QART, have names, which should be distinct +among all ports of any given program (or subroutine). Each port also has +direction, which can be either `input` or `output`. Finally, each port has size. +In our simple scenario, all sizes are positive integers. However, QART +is not limited to them, and size of a port can be either: + +- A positive integer. +- A symbol or symbolic expression (e.g. `N` or `2L + 1`) +- A `null`, signifying that the size of the port can be deduced from sizes of + other ports it is connected to (possibly transitively). + +### Children + +The `children` list comprises all subroutines of the program. Each entry has the +same structure as the program itself (one could say that the schema of the `program` +is recursive). In particular, each child should have a name (unique in the scope +of their immediate parent) and some ports. They can also have connections, and their +own children. + +### Connections + +The last component of any program (and most subroutines) are connections defining the +edges of a graph. The `connections` field is a list of objects, each having `source` +and `target`. Both `source` and `target` can either be: + +- A name of the port of the program/subroutine the connection belongs to, i.e. `out_0` +- A reference to a port of one of program/subroutine's direct children. + Such a reference is formatted as `child.port_name`. + +There are three types of connections: + +- Connections joining two distinct children, e.g. + ```yaml + {source: subroutine_1.out, target: merge.in_1} + ``` +- Connections joining a child and its parent. e.g.: + ```yaml + {source: in_0, target: subroutine_1.in} + ``` + or + ```yaml + {source: merge.out, target: out} + ``` +- Connections joining input and output port of a parent, known as passthroughs. + There are no passthroughs in our simple example, but one could look like: + ```yaml + {source: in_0, target: out} + ``` diff --git a/docs/images/basic_circuit.svg b/docs/images/basic_circuit.svg new file mode 100644 index 0000000..735cb3f --- /dev/null +++ b/docs/images/basic_circuit.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/images/basic_program.svg b/docs/images/basic_program.svg new file mode 100644 index 0000000..e5d4c5b --- /dev/null +++ b/docs/images/basic_program.svg @@ -0,0 +1,97 @@ + + + + + + + + +cluster_.my_program + +my_program + + + +.my_program.in_0 + +in_0 + + + +.my_program.subroutine_1 + +in + +subroutine_1 + +out + + + +.my_program.in_0->.my_program.subroutine_1:in + + + + + +.my_program.in_1 + +in_1 + + + +.my_program.subroutine_2 + +in + +subroutine_2 + +out + + + +.my_program.in_1->.my_program.subroutine_2:in + + + + + +.my_program.out + +out + + + +.my_program.merge + +in_0 + +in_1 + +merge + +out + + + +.my_program.subroutine_1:out->.my_program.merge:in_1 + + + + + +.my_program.subroutine_2:out->.my_program.merge:in_0 + + + + + +.my_program.merge:out->.my_program.out + + + + + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..6478741 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,41 @@ +# QART + +Quantum Algorithms Represented Topologically (QART) is an open format for representing +quantum algorithms, optimized for usage in quantum resource estimation (QRE). + +
+ +- :material-code-json:{ .lg .middle } It's just JSON (or YAML) + + --- + + QART's data format is built on top of JSON, which makes it easy to + write and read. + + [:octicons-arrow-right-24: Learn more](format) + +- :fontawesome-brands-markdown:{ .lg .middle } __Cross-language support__ + + --- + + QART's JSON schema can be used for data validation in any language. + +- :material-language-python:{ .lg .middle } __Python library__ + + --- + + QART's Python package provides programmatic access + to QART's JSON schema and ready-to-use Pydantic models. + + + [:octicons-arrow-right-24: See user guide](library/userguide) + +- :material-scale-balance:{ .lg .middle } __Open Source, MIT__ + + --- + + QART is licensed under the MIT license and lives on GitHub. + + [:octicons-arrow-right-24: See QART on GH](https://github.com/psiq/hqar) + +
diff --git a/docs/library/reference/qart.experimental.rendering.md b/docs/library/reference/qart.experimental.rendering.md new file mode 100644 index 0000000..ede8019 --- /dev/null +++ b/docs/library/reference/qart.experimental.rendering.md @@ -0,0 +1,3 @@ + +::: qart.experimental.rendering + handler: python diff --git a/docs/library/reference/qart.md b/docs/library/reference/qart.md new file mode 100644 index 0000000..0f15c61 --- /dev/null +++ b/docs/library/reference/qart.md @@ -0,0 +1,6 @@ +::: qart + handler: python + options: + members: + - generate_program_schema + - SchemaV1 diff --git a/docs/library/userguide.md b/docs/library/userguide.md new file mode 100644 index 0000000..5fc3a4c --- /dev/null +++ b/docs/library/userguide.md @@ -0,0 +1,78 @@ +# User guide + +## Installation + +To install QART Python package, clone QARt repository and install it as usual with `pip`: + +```bash +# Clone QART repo (you can use HTTP link as well) +git clone git@github.com:PsiQ/qart.git +cd qart +pip install . +``` + +Please note that to use rendering features you need a working [graphviz](https://graphviz.org) +installation. + +## Usage + + +### Using JSON schema for validating data in QART format + +JSON schema for QART format can be obtained by calling +[`generate_program_schema`][qart.generate_program_schema] function. +Such schema can be then used for validating user's input, e.g. using +[`jsonschema`](https://pypi.org/project/jsonschema/) package: + +```python +from jsonschema import validate +from qart import generate_program_schema + +# Hypothetical function loading your data as native Python dictionary. +data = load_some_program() +schema = generate_program_schema() + +# This will raise if there are some validation errors. +validate(schema, data) +``` + +### Validation using Pydantic models + +If you are familiar with [Pydantic](https://docs.pydantic.dev/latest/), you might find +it easier to work with QART Pydantic models instead of interacting with JSON schema directly. +In the example below, we create an instance of [`SchemaV1`][qart.SchemaV1] model from +validated data stored in QART format: + +```python +from qart import SchemaV1 + +data = load_some_program() + +# This will raise if data is not valid +program = SchemaV1.model_validate(data) +``` + +### Rendering QART files using `qart-render` (experimental) + +!!! Warning + + This feature is considered experimental and may occassionally produce + incorrect results. + + +QART comes with a CLI tool for rendering hierarchical graphs of quantum +algorithms. To render an algorithm stored in a file named `my_program.yaml` into a +file `my_program_graph.svg` run: + +```bash +qart-render my_program.yaml my_program_graph.svg +``` + +The `qart-render` tool supports `yaml` and `json` input formats, and all +output formats supported by [graphviz](https://graphviz.org/). + +If, instead of using CLI, you'd like to invoke QART's rendering capabilities +from Python script, you can look at [qart.experimental.rendering][qart.experimental.rendering] +module which exposes experimental API for performing the same task as `qart-render`. + + diff --git a/example_routine.svg b/example_routine.svg index baf8372..bbe2c43 100644 --- a/example_routine.svg +++ b/example_routine.svg @@ -1,7 +1,7 @@ - -cluster_.my_algorithm +cluster_.my_program -my_algorithm +my_program - + -.my_algorithm.in_0 +.my_program.in_0 in_0 - + -.my_algorithm.subroutine_1 +.my_program.subroutine_1 in_0 @@ -29,21 +29,21 @@ out_0 - + -.my_algorithm.in_0->.my_algorithm.subroutine_1:in_0 - - +.my_program.in_0->.my_program.subroutine_1:in_0 + + - + -.my_algorithm.in_1 +.my_program.in_1 in_1 - + -.my_algorithm.subroutine_2 +.my_program.subroutine_2 in_0 @@ -53,21 +53,21 @@ out_1 - + -.my_algorithm.in_1->.my_algorithm.subroutine_2:in_0 - - +.my_program.in_1->.my_program.subroutine_2:in_0 + + - + -.my_algorithm.out_0 +.my_program.out_0 out_0 - + -.my_algorithm.merge +.my_program.merge in_0 @@ -79,29 +79,29 @@ out_0 - + -.my_algorithm.subroutine_1:out_0->.my_algorithm.merge:in_2 - - +.my_program.subroutine_1:out_0->.my_program.merge:in_2 + + - + -.my_algorithm.subroutine_2:out_0->.my_algorithm.merge:in_0 - - +.my_program.subroutine_2:out_0->.my_program.merge:in_0 + + - + -.my_algorithm.subroutine_2:out_1->.my_algorithm.merge:in_1 - - +.my_program.subroutine_2:out_1->.my_program.merge:in_1 + + - + -.my_algorithm.merge:out_0->.my_algorithm.out_0 - - +.my_program.merge:out_0->.my_program.out_0 + +
diff --git a/example_routine.yaml b/example_routine.yaml index d4b13f6..7d672a4 100644 --- a/example_routine.yaml +++ b/example_routine.yaml @@ -1,6 +1,6 @@ version: v1 program: - name: my_algorithm + name: my_program ports: - direction: input name: in_0 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..5b21403 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,57 @@ +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json +site_name: QART +site_description: Quantum Algorithms Represented Topologically +site_author: PsiQuantum Corp. +copyright: Copyright © 2023-2024 PsiQuantum Corp. +repo_url: https://github.com/psiq/qart +nav: + - format.md + - Python Library: + - library/userguide.md + - API Reference: + - qart: library/reference/qart.md + - qart.experimental.rendering: library/reference/qart.experimental.rendering.md + - development.md +theme: + name: material + features: + - content.code.copy +markdown_extensions: + - admonition + - attr_list + - md_in_html + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets: + base_path: + - docs/examples + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true +plugins: + - autorefs + - search + - link-marker + - open-in-new-tab + - mkdocstrings: + handlers: + python: + options: + annotation_path: full + heading_level: 1 + show_source: true + show_signature_annotations: true + members_order: source + separate_signature: true + show_if_no_docstring: true + show_root_heading: true + docstring_options: + ignore_init_summary: true + merge_init_into_class: true + show_docstring_returns: true diff --git a/poetry.lock b/poetry.lock index f88e8a0..11021ef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -30,6 +30,20 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +[[package]] +name = "babel" +version = "2.14.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "black" version = "24.2.0" @@ -76,6 +90,116 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + [[package]] name = "click" version = "8.1.7" @@ -131,6 +255,23 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.11.0,<2.12.0" pyflakes = ">=3.2.0,<3.3.0" +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + [[package]] name = "graphviz" version = "0.20.3" @@ -147,6 +288,50 @@ dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] docs = ["sphinx (>=5,<7)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] +[[package]] +name = "griffe" +version = "0.42.1" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +optional = false +python-versions = ">=3.8" +files = [ + {file = "griffe-0.42.1-py3-none-any.whl", hash = "sha256:7e805e35617601355edcac0d3511cedc1ed0cb1f7645e2d336ae4b05bbae7b3b"}, + {file = "griffe-0.42.1.tar.gz", hash = "sha256:57046131384043ed078692b85d86b76568a686266cc036b9b56b704466f803ce"}, +] + +[package.dependencies] +colorama = ">=0.4" + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "importlib-metadata" +version = "7.1.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, + {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -158,6 +343,23 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "jsonschema" version = "4.21.1" @@ -193,6 +395,93 @@ files = [ [package.dependencies] referencing = ">=0.31.0" +[[package]] +name = "markdown" +version = "3.6" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, + {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -204,6 +493,177 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.5.3" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"}, + {file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "1.0.1" +description = "Automatically link across pages in MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_autorefs-1.0.1-py3-none-any.whl", hash = "sha256:aacdfae1ab197780fb7a2dac92ad8a3d8f7ca8049a9cbe56a4218cd52e8da570"}, + {file = "mkdocs_autorefs-1.0.1.tar.gz", hash = "sha256:f684edf847eced40b570b57846b15f0bf57fb93ac2c510450775dcf16accb971"}, +] + +[package.dependencies] +Markdown = ">=3.3" +markupsafe = ">=2.0.1" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-link-marker" +version = "0.1.3" +description = "MkDocs plugin for marking external or mail links in your documentation." +optional = false +python-versions = ">=3.4" +files = [ + {file = "mkdocs-link-marker-0.1.3.tar.gz", hash = "sha256:6d8760c819a376650675f02c7de82f5fbc0a992e7ed3239955cc01021a1af779"}, + {file = "mkdocs_link_marker-0.1.3-py3-none-any.whl", hash = "sha256:798a6bfbb059ce49a81f724e84306bec8f1d5241aace89e54ae7d9088beeab5b"}, +] + +[package.dependencies] +jinja2 = "*" +mkdocs = ">=1.0" + +[[package]] +name = "mkdocs-material" +version = "9.5.17" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.17-py3-none-any.whl", hash = "sha256:14a2a60119a785e70e765dd033e6211367aca9fc70230e577c1cf6a326949571"}, + {file = "mkdocs_material-9.5.17.tar.gz", hash = "sha256:06ae1275a72db1989cf6209de9e9ecdfbcfdbc24c58353877b2bb927dbe413e4"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.5.3,<1.6.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "mkdocs-open-in-new-tab" +version = "1.0.3" +description = "MkDocs plugin to open outgoing links and PDFs in new tab." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-open-in-new-tab-1.0.3.tar.gz", hash = "sha256:a40231901b12f01a1d4b798112712d475741356e550d8f3adf3ca23e332a7d2c"}, + {file = "mkdocs_open_in_new_tab-1.0.3-py3-none-any.whl", hash = "sha256:e2ddfa02f53d7c16d8430f5c0b3d98c4b98c82e1b8aa6fbdc91c78e89bbeb5f1"}, +] + +[package.dependencies] +mkdocs = "*" + +[[package]] +name = "mkdocstrings" +version = "0.24.2" +description = "Automatic documentation from sources, for MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings-0.24.2-py3-none-any.whl", hash = "sha256:61440b77542170238099a7d87882c3417897771950e3aafe6e22abff3d1c51fb"}, + {file = "mkdocstrings-0.24.2.tar.gz", hash = "sha256:b91b9cdd9490ef2e8957000bff1d34a4b308b9cd57b10f26169f085def4c6a92"}, +] + +[package.dependencies] +click = ">=7.0" +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.11.1" +Markdown = ">=3.3" +MarkupSafe = ">=1.1" +mkdocs = ">=1.4" +mkdocs-autorefs = ">=0.3.1" +mkdocstrings-python = {version = ">=0.5.2", optional = true, markers = "extra == \"python\""} +platformdirs = ">=2.2.0" +pymdown-extensions = ">=6.3" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "1.9.2" +description = "A Python handler for mkdocstrings." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocstrings_python-1.9.2-py3-none-any.whl", hash = "sha256:96d82f6424e08db6245e4a15ca95619f4ecd0ddd254c0aa590d4181814e16ee5"}, + {file = "mkdocstrings_python-1.9.2.tar.gz", hash = "sha256:8546a103c9b22e1778c72c887696acc39a6635fedde3c912ce00f967518a8847"}, +] + +[package.dependencies] +griffe = ">=0.37" +mkdocstrings = ">=0.24.2" + [[package]] name = "mypy" version = "1.9.0" @@ -273,6 +733,16 @@ files = [ {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + [[package]] name = "pathspec" version = "0.12.1" @@ -446,6 +916,39 @@ files = [ {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, ] +[[package]] +name = "pygments" +version = "2.17.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, +] + +[package.extras] +plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pymdown-extensions" +version = "10.7.1" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.7.1-py3-none-any.whl", hash = "sha256:f5cc7000d7ff0d1ce9395d216017fa4df3dde800afb1fb72d1c7d3fd35e710f4"}, + {file = "pymdown_extensions-10.7.1.tar.gz", hash = "sha256:c70e146bdd83c744ffc766b4671999796aba18842b268510a329f7f64700d584"}, +] + +[package.dependencies] +markdown = ">=3.5" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + [[package]] name = "pytest" version = "8.1.1" @@ -468,6 +971,20 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + [[package]] name = "pyyaml" version = "6.0.1" @@ -528,6 +1045,20 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + [[package]] name = "referencing" version = "0.33.0" @@ -543,6 +1074,129 @@ files = [ attrs = ">=22.2.0" rpds-py = ">=0.7.0" +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + [[package]] name = "rpds-py" version = "0.18.0" @@ -651,6 +1305,17 @@ files = [ {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, ] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "tomli" version = "2.0.1" @@ -673,7 +1338,80 @@ files = [ {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "watchdog" +version = "4.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "zipp" +version = "3.18.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "a92eed0b5238eff7943419c128dcb3d5c65d4fdd475cf6dfec61279c307bda16" +content-hash = "5b573892b248220308700d228282eda67dd34b5384e292d7e6e6efe15bf1d6ca" diff --git a/pyproject.toml b/pyproject.toml index 6ccb055..81c2b97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] -name = "hqar" +name = "qart" version = "0.1.0" -description = "Hierarchical Quantum Algorithms Representation" +description = "Quantum Algorithms, Represented Topologically" authors = ["PsiQuantum"] license = "MIT" readme = "README.md" @@ -21,8 +21,16 @@ pyyaml = "^6" jsonschema = "^4" + +[tool.poetry.group.docs.dependencies] +mkdocs = "^1.5.3" +mkdocs-link-marker = "^0.1.3" +mkdocs-material = "^9.5.15" +mkdocs-open-in-new-tab = "^1.0.3" +mkdocstrings = {version = "^0.24.2", extras = ["python"]} + [tool.poetry.scripts] -hqar-render = "hqar.experimental.rendering:render_entry_point" +qart-render = "qart.experimental.rendering:render_entry_point" [build-system] diff --git a/src/hqar/__init__.py b/src/qart/__init__.py similarity index 60% rename from src/hqar/__init__.py rename to src/qart/__init__.py index 697d196..327b28b 100644 --- a/src/hqar/__init__.py +++ b/src/qart/__init__.py @@ -1,14 +1,4 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. - -Public API of HQAR. -""" +"""Public API of QART.""" from typing import Any diff --git a/src/hqar/_schema_v1.py b/src/qart/_schema_v1.py similarity index 85% rename from src/hqar/_schema_v1.py rename to src/qart/_schema_v1.py index ccac3b1..b0dc4a7 100644 --- a/src/hqar/_schema_v1.py +++ b/src/qart/_schema_v1.py @@ -1,14 +1,4 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. - -Pydantic models used for defining V1 schema of Routine. -""" +"""Pydantic models used for defining V1 schema of Routine.""" from __future__ import annotations @@ -20,7 +10,6 @@ NAME_PATTERN = "[A-Za-z_][A-Za-z0-9_]*" NAMESPACED_NAME_PATTERN = rf"{NAME_PATTERN}\.{NAME_PATTERN}" - Name = Annotated[str, StringConstraints(pattern=rf"^{NAME_PATTERN}$")] NamespacedName = Annotated[str, StringConstraints(pattern=rf"^{NAMESPACED_NAME_PATTERN}")] OptionallyNamespacedName = Annotated[ diff --git a/src/hqar/experimental/__init__.py b/src/qart/experimental/__init__.py similarity index 100% rename from src/hqar/experimental/__init__.py rename to src/qart/experimental/__init__.py diff --git a/src/hqar/experimental/rendering.py b/src/qart/experimental/rendering.py similarity index 92% rename from src/hqar/experimental/rendering.py rename to src/qart/experimental/rendering.py index d6b98af..9ea371e 100644 --- a/src/hqar/experimental/rendering.py +++ b/src/qart/experimental/rendering.py @@ -1,13 +1,4 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. - -Experimental visualization capabilities for HQAR. +"""Experimental visualization capabilities for QART. Currently, the visualizations are done with graphviz, which does not suport hierarchical structures. Therefore, we have to use a somewhat hacky representation diff --git a/tests/conftest.py b/tests/conftest.py index 84b10a0..ea14d27 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,19 +1,11 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. -""" +"""Common fixtures for QART tests.""" from pathlib import Path import pytest import yaml -VALID_PROGRAMS_ROOT_PATH = Path(__file__).parent / "hqar/data/valid_programs" +VALID_PROGRAMS_ROOT_PATH = Path(__file__).parent / "qart/data/valid_programs" def _load_valid_examples(): diff --git a/tests/hqar/experimental/test_rendering.py b/tests/hqar/experimental/test_rendering.py deleted file mode 100644 index 11a7a5a..0000000 --- a/tests/hqar/experimental/test_rendering.py +++ /dev/null @@ -1,33 +0,0 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. - -Sanity checks for hqar rendering capabilities. -""" - -import json -from subprocess import Popen - -from hqar.experimental.rendering import to_graphviz - - -def test_example_valid_programs_can_converted_to_graphviz(valid_program): - to_graphviz(valid_program) - - -def test_example_valid_programs_can_be_rendered_from_cli(valid_program, tmp_path): - input_path = tmp_path / "input.json" - output_path = tmp_path / "output.svg" - - with open(input_path, "wt") as f: - json.dump(valid_program, f) - - process = Popen(["hqar-render", input_path, output_path]) - process.wait() - - assert process.returncode == 0 diff --git a/tests/hqar/data/invalid_program_examples.yaml b/tests/qart/data/invalid_program_examples.yaml similarity index 100% rename from tests/hqar/data/invalid_program_examples.yaml rename to tests/qart/data/invalid_program_examples.yaml diff --git a/tests/hqar/data/valid_programs/example_0.yaml b/tests/qart/data/valid_programs/example_0.yaml similarity index 100% rename from tests/hqar/data/valid_programs/example_0.yaml rename to tests/qart/data/valid_programs/example_0.yaml diff --git a/tests/hqar/data/valid_programs/example_1.yaml b/tests/qart/data/valid_programs/example_1.yaml similarity index 100% rename from tests/hqar/data/valid_programs/example_1.yaml rename to tests/qart/data/valid_programs/example_1.yaml diff --git a/tests/hqar/data/valid_programs/example_2.yaml b/tests/qart/data/valid_programs/example_2.yaml similarity index 100% rename from tests/hqar/data/valid_programs/example_2.yaml rename to tests/qart/data/valid_programs/example_2.yaml diff --git a/tests/hqar/data/valid_programs/example_3.yaml b/tests/qart/data/valid_programs/example_3.yaml similarity index 100% rename from tests/hqar/data/valid_programs/example_3.yaml rename to tests/qart/data/valid_programs/example_3.yaml diff --git a/tests/qart/experimental/test_rendering.py b/tests/qart/experimental/test_rendering.py new file mode 100644 index 0000000..f576698 --- /dev/null +++ b/tests/qart/experimental/test_rendering.py @@ -0,0 +1,23 @@ +"""Sanity checks for QART rendering capabilities.""" + +import json +from subprocess import Popen + +from qart.experimental.rendering import to_graphviz + + +def test_example_valid_programs_can_converted_to_graphviz(valid_program): + to_graphviz(valid_program) + + +def test_example_valid_programs_can_be_rendered_from_cli(valid_program, tmp_path): + input_path = tmp_path / "input.json" + output_path = tmp_path / "output.svg" + + with open(input_path, "wt") as f: + json.dump(valid_program, f) + + process = Popen(["qart-render", input_path, output_path]) + process.wait() + + assert process.returncode == 0 diff --git a/tests/hqar/test_schema_validation.py b/tests/qart/test_schema_validation.py similarity index 71% rename from tests/hqar/test_schema_validation.py rename to tests/qart/test_schema_validation.py index 3aaa945..b3f2883 100644 --- a/tests/hqar/test_schema_validation.py +++ b/tests/qart/test_schema_validation.py @@ -1,14 +1,4 @@ -""" -.. Copyright © 2023-2024 PsiQuantum Corp. All rights reserved. - PSIQUANTUM CORP. CONFIDENTIAL - This file includes unpublished proprietary source code of PsiQuantum Corp. - The copyright notice above does not evidence any actual or intended publication - of such source code. Disclosure of this source code or any related proprietary - information is strictly prohibited without the express written permission of - PsiQuantum Corp. - -Test cases checking that schema matches data that we expect it to match. -""" +"""Test cases checking that schema matches data that we expect it to match.""" from pathlib import Path @@ -17,7 +7,7 @@ import yaml # type: ignore[import-untyped] from jsonschema import ValidationError, validate -from hqar import SchemaV1, generate_program_schema +from qart import SchemaV1, generate_program_schema def validate_with_v1(data):