Skip to content

Commit

Permalink
Merge pull request #19 from qua-platform/feat/Literal-support
Browse files Browse the repository at this point in the history
Add support for literal types
  • Loading branch information
nulinspiratie authored Mar 8, 2024
2 parents f79fd36 + d063435 commit 2601ae3
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 59 deletions.
2 changes: 2 additions & 0 deletions quam/core/quam_instantiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ def instantiate_attr(
if isinstance(attr_val, list):
attr_val = tuple(attr_val)
instantiated_attr = attr_val
elif typing.get_origin(expected_type) == typing.Literal:
instantiated_attr = attr_val
elif typing.get_origin(expected_type) is not None and validate_type:
raise TypeError(
f"Instantiation for type {expected_type} in {str_repr} not implemented"
Expand Down
85 changes: 26 additions & 59 deletions tests/instantiation/test_instantiation.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import pytest
from typing import List, Optional
from typing import List, Literal, Optional

from quam.core import QuamRoot, QuamComponent, quam_dataclass
from quam.examples.superconducting_qubits.components import Transmon
from quam.core.quam_instantiation import *
from quam.utils import (
get_dataclass_attr_annotations,
validate_obj_type,
)
from quam.utils import get_dataclass_attr_annotations


def test_get_dataclass_attributes():
Expand Down Expand Up @@ -75,58 +72,6 @@ class TestClass(AbstractClass):
}


def test_validate_standard_types():
validate_obj_type(1, int)
validate_obj_type(1.0, float)
validate_obj_type("hello", str)
validate_obj_type(":reference", str)
validate_obj_type([1, 2, 3], list)
validate_obj_type((1, 2, 3), tuple)
validate_obj_type({"a": 1, "b": 2}, dict)
validate_obj_type(True, bool)
validate_obj_type(None, type(None))

with pytest.raises(TypeError):
validate_obj_type(1, str)
with pytest.raises(TypeError):
validate_obj_type("hello", int)


def test_validate_type_exceptions():
validate_obj_type("#/reference", int)
validate_obj_type("#/reference", str)
validate_obj_type("#./reference", int)
validate_obj_type("#./reference", str)
validate_obj_type("#../reference", int)
validate_obj_type("#../reference", str)

validate_obj_type(None, int)
validate_obj_type(None, str)


def test_validate_typing_list():
validate_obj_type([1, 2, 3], List[int])
with pytest.raises(TypeError):
validate_obj_type([1, 2, 3], List[str])

validate_obj_type([1, 2, 3], List)
validate_obj_type(["a", "b", "c"], List)
validate_obj_type(["a", "b", "c"], List[str])
with pytest.raises(TypeError):
validate_obj_type(["a", "b", "c"], List[int])


def test_validate_typing_dict():
validate_obj_type({"a": 1, "b": 2}, dict)
validate_obj_type({"a": 1, "b": 2}, Dict[str, int])
with pytest.raises(TypeError):
validate_obj_type({"a": 1, "b": 2}, Dict[str, str])

validate_obj_type("#/reference", Dict[str, int])
validate_obj_type("#./reference", Dict[str, int])
validate_obj_type("#../reference", Dict[str, int])


@quam_dataclass
class QuamComponentTest(QuamComponent):
test_str: str
Expand Down Expand Up @@ -347,6 +292,28 @@ def test_instantiate_sublist():
class TestQuamSubList(QuamComponent):
sublist: List[List[float]]

obj = instantiate_quam_class(TestQuamSubList, {"sublist": [[1,2,3], [4,5,6]]})
obj = instantiate_quam_class(TestQuamSubList, {"sublist": [[1, 2, 3], [4, 5, 6]]})

assert obj.sublist == [[1, 2, 3], [4, 5, 6]]


def test_instantiate_attr_literal():
attr = instantiate_attr(
attr_val="a",
expected_type=Literal["a", "b", "c"],
)
assert attr == "a"

assert obj.sublist == [[1,2,3], [4,5,6]]

def test_instance_attr_literal_fail():
with pytest.raises(TypeError):
instantiate_attr(
attr_val="d",
expected_type=Literal["a", "b", "c"],
)

with pytest.raises(TypeError):
instantiate_attr(
attr_val=1,
expected_type=Literal["a", "b", "c"],
)
67 changes: 67 additions & 0 deletions tests/utils/test_validate_obj_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import pytest
from typing import List, Dict, Literal

from quam.utils.general import validate_obj_type


def test_validate_standard_types():
validate_obj_type(1, int)
validate_obj_type(1.0, float)
validate_obj_type("hello", str)
validate_obj_type(":reference", str)
validate_obj_type([1, 2, 3], list)
validate_obj_type((1, 2, 3), tuple)
validate_obj_type({"a": 1, "b": 2}, dict)
validate_obj_type(True, bool)
validate_obj_type(None, type(None))

with pytest.raises(TypeError):
validate_obj_type(1, str)
with pytest.raises(TypeError):
validate_obj_type("hello", int)


def test_validate_type_exceptions():
validate_obj_type("#/reference", int)
validate_obj_type("#/reference", str)
validate_obj_type("#./reference", int)
validate_obj_type("#./reference", str)
validate_obj_type("#../reference", int)
validate_obj_type("#../reference", str)

validate_obj_type(None, int)
validate_obj_type(None, str)


def test_validate_typing_list():
validate_obj_type([1, 2, 3], List[int])
with pytest.raises(TypeError):
validate_obj_type([1, 2, 3], List[str])

validate_obj_type([1, 2, 3], List)
validate_obj_type(["a", "b", "c"], List)
validate_obj_type(["a", "b", "c"], List[str])
with pytest.raises(TypeError):
validate_obj_type(["a", "b", "c"], List[int])


def test_validate_typing_dict():
validate_obj_type({"a": 1, "b": 2}, dict)
validate_obj_type({"a": 1, "b": 2}, Dict[str, int])
with pytest.raises(TypeError):
validate_obj_type({"a": 1, "b": 2}, Dict[str, str])

validate_obj_type("#/reference", Dict[str, int])
validate_obj_type("#./reference", Dict[str, int])
validate_obj_type("#../reference", Dict[str, int])


def test_validate_typing_literal():
validate_obj_type("a", Literal["a", "b", "c"])
validate_obj_type("b", Literal["a", "b", "c"])

with pytest.raises(TypeError):
validate_obj_type("d", Literal["a", "b", "c"])

with pytest.raises(TypeError):
validate_obj_type(123, Literal["b", "c"])

0 comments on commit 2601ae3

Please sign in to comment.