Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 126 additions & 24 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ python = "^3.9"
pydantic = "^2.7"
sympy = "^1.12"
pyparsing ="~3.1.2"
qref = "0.1.0"


[tool.poetry.group.dev.dependencies]
pytest = "^8.1.1"
pytest_diff = "^0.1.14"
mypy = "^1.9.0"
flake8 = "^7.0.0"
black = "^24.4.1"
Expand All @@ -38,4 +40,9 @@ build-backend = "poetry.core.masonry.api"

[tool.black]
line-length = 120
target-version = ['py39']
target-version = ['py39']


[[tool.mypy.overrides]]
module = "qref.*"
ignore_missing_imports = true
3 changes: 1 addition & 2 deletions src/bartiq/_routine.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,7 @@ def relative_path_from(self, ancestor: Optional[Routine]) -> str:
return self.name
else:
try:
# type: ignore
return f"{self.parent.relative_path_from(ancestor)}.{self.name}"
return f"{self.parent.relative_path_from(ancestor)}.{self.name}" # type: ignore
except (ValueError, AttributeError) as e:
raise ValueError("Ancestor not found.") from e

Expand Down
4 changes: 2 additions & 2 deletions src/bartiq/integrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .qart_integration import bartiq_to_qart, qart_to_bartiq
from .qref_integration import bartiq_to_qref, qref_to_bartiq

__all__ = ["bartiq_to_qart", "qart_to_bartiq"]
__all__ = ["bartiq_to_qref", "qref_to_bartiq"]
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@

from typing import Any, Union

from qart import SchemaV1
from qref import SchemaV1

from .. import Port, Routine


def bartiq_to_qart(routine: Routine, version: str = "v1") -> SchemaV1:
"""Convert Bartiq routine to QART object."""
def bartiq_to_qref(routine: Routine, version: str = "v1") -> SchemaV1:
"""Convert Bartiq routine to QREF object."""
if version != "v1":
raise ValueError(f"Unsupported QART schema version {version}")
return SchemaV1.model_validate({"version": "v1", "program": _bartiq_routine_to_qart_v1_dict(routine)})
raise ValueError(f"Unsupported QREF schema version {version}")
return SchemaV1.model_validate({"version": "v1", "program": _bartiq_routine_to_qref_v1_dict(routine)})


def qart_to_bartiq(qart_obj: Union[SchemaV1, dict]) -> Routine:
"""Convert QART object to a Bartiq routine."""
qart_obj = SchemaV1.model_validate(qart_obj)
return _routine_v1_to_bartiq_routine(qart_obj.program)
def qref_to_bartiq(qref_obj: Union[SchemaV1, dict]) -> Routine:
"""Convert QREF object to a Bartiq routine."""
qref_obj = SchemaV1.model_validate(qref_obj)
return _routine_v1_to_bartiq_routine(qref_obj.program)


def _scoped_port_name_from_op_port(port: Port, parent: Routine) -> str:
Expand All @@ -42,11 +42,11 @@ def _ensure_primitive_type(value: Any) -> Union[int, float, str, None]:
return value if value is None or isinstance(value, (int, float, str)) else str(value)


def _bartiq_routine_to_qart_v1_dict(routine: Routine) -> dict:
def _bartiq_routine_to_qref_v1_dict(routine: Routine) -> dict:
return {
"name": routine.name,
"type": routine.type,
"children": [_bartiq_routine_to_qart_v1_dict(child) for child in routine.children.values()],
"children": [_bartiq_routine_to_qref_v1_dict(child) for child in routine.children.values()],
"resources": [
{
"name": resource.name,
Expand Down Expand Up @@ -83,7 +83,7 @@ def _bartiq_routine_to_qart_v1_dict(routine: Routine) -> dict:
}


# Untypes because RoutineV1 is not public in QART
# Untypes because RoutineV1 is not public in QREF
def _routine_v1_to_bartiq_routine(routine_v1) -> Routine:
return Routine(
name=routine_v1.name,
Expand Down
2 changes: 1 addition & 1 deletion src/bartiq/symbolics/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
class SymbolicBackend(Protocol[T_expr]):
"""Protocol describing capabilities of backends used for manipulating symbolic expressions."""

def as_expression(self, value: str | int | float) -> T_expr:
def as_expression(self, value: Union[str, int, float]) -> T_expr:
"""Convert given value into an expression native to this backend."""

def free_symbols_in(self, expr: T_expr) -> Iterable[str]:
Expand Down
4 changes: 2 additions & 2 deletions src/bartiq/symbolics/sympy_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@


@singledispatch
def _as_expression(value: str | int | float) -> T_expr:
def _as_expression(value: Union[str | int | float]) -> T_expr:
return sympify(value)


Expand All @@ -49,7 +49,7 @@ def _parse(value: str) -> T_expr:
return parse_to_sympy(value)


def as_expression(value: str | int | float) -> T_expr:
def as_expression(value: Union[str | int | float]) -> T_expr:
"""Convert numerical or textual value into an expression."""
return _as_expression(value)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from bartiq import Routine

try:
from bartiq.integrations import bartiq_to_qart, qart_to_bartiq

QART_UNAVAILABLE = False
except ImportError:
QART_UNAVAILABLE = True

import pytest
from pytest import fixture

from bartiq import Routine
from bartiq.integrations import bartiq_to_qref, qref_to_bartiq

# Note: fixture example_routine has to be synced with
# the example_schema_v1 fixture further in this module.

Expand Down Expand Up @@ -76,7 +70,7 @@ def example_routine():


@fixture
def example_serialized_qart_v1_object():
def example_serialized_qref_v1_object():
return {
"version": "v1",
"program": {
Expand Down Expand Up @@ -119,17 +113,14 @@ def example_serialized_qart_v1_object():
}


@pytest.mark.skipif(QART_UNAVAILABLE, reason="QART is not installed")
def test_converting_routine_to_qart_v1_gives_correct_output(example_routine, example_serialized_qart_v1_object):
assert bartiq_to_qart(example_routine).model_dump(exclude_unset=True) == example_serialized_qart_v1_object
def test_converting_routine_to_qref_v1_gives_correct_output(example_routine, example_serialized_qref_v1_object):
assert bartiq_to_qref(example_routine).model_dump(exclude_unset=True) == example_serialized_qref_v1_object


@pytest.mark.skipif(QART_UNAVAILABLE, reason="QART is not installed")
def test_converting_qart_v1_object_to_routine_give_correct_output(example_routine, example_serialized_qart_v1_object):
assert qart_to_bartiq(example_serialized_qart_v1_object) == example_routine
def test_converting_qref_v1_object_to_routine_give_correct_output(example_routine, example_serialized_qref_v1_object):
assert qref_to_bartiq(example_serialized_qref_v1_object) == example_routine


@pytest.mark.skipif(QART_UNAVAILABLE, reason="QART is not installed")
def test_conversion_from_bartiq_to_qart_raises_an_error_if_version_is_unsupported(example_routine):
def test_conversion_from_bartiq_to_qref_raises_an_error_if_version_is_unsupported(example_routine):
with pytest.raises(ValueError):
bartiq_to_qart(example_routine, version="v3")
bartiq_to_qref(example_routine, version="v3")