Skip to content

Commit

Permalink
Update InvariantValue type so that the value field cannot be reassign…
Browse files Browse the repository at this point in the history
…ed once set.
  • Loading branch information
hemang1729 committed Dec 13, 2024
1 parent 4f428af commit be91675
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 9 deletions.
17 changes: 14 additions & 3 deletions testing/invariant/custom_types/invariant_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,24 @@ def __init__(self, value: Any, addresses: list[str] = None):
):
raise TypeError("addresses must be a list of strings")

self.value = value
self._value = value
self.addresses = addresses if addresses is not None else []

if isinstance(self.value, str):
if isinstance(self._value, str):
for i, a in enumerate(self.addresses):
if ":" not in a:
self.addresses[i] = a + ":0-" + str(len(self.value))
self.addresses[i] = a + ":0-" + str(len(self._value))

@property
def value(self):
"""Read-only property for the value field."""
return self._value

def __setattr__(self, name, new_value):
"""Customize attribute setting to prevent `value` from being reassigned."""
if name == "value":
raise AttributeError("The 'value' attribute cannot be reassigned.")
super().__setattr__(name, new_value)

@staticmethod
def of(value: Any, address: list[str]) -> InvariantValue | "InvariantDict" | None:
Expand Down
5 changes: 5 additions & 0 deletions testing/tests/custom_types/test_invariant_bool.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests for the InvariantBool class."""

import pytest

from invariant.custom_types.invariant_bool import InvariantBool


Expand Down Expand Up @@ -178,6 +179,10 @@ def test_invariant_bool_with_addresses():
assert bool1.addresses == ["address1"]
assert bool3.addresses == ["address2"]

# The value field is read-only.
with pytest.raises(AttributeError, match="'value' attribute cannot be reassigned"):
bool1.value = False


@pytest.mark.parametrize(
"invariant_bool, expected",
Expand Down
13 changes: 13 additions & 0 deletions testing/tests/custom_types/test_invariant_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,16 @@ def test_ocr_detector():
assert not inv_img.ocr_contains_all(["agents", "making", "LLM"])
assert inv_img.ocr_contains_any(["something", "agents", "abc"])
assert not inv_img.ocr_contains_any(["something", "def", "abc"])


def test_invariant_image_value_no_reassignment():
"""Test that the value of an InvariantImage cannot be reassigned."""
with (
open("sample_tests/assets/inv_labs.png", "rb") as image_file_1,
open("sample_tests/assets/Group_of_cats_resized.jpg", "rb") as image_file_2,
):
base64_image_1 = base64.b64encode(image_file_1.read()).decode("utf-8")
base64_image_2 = base64.b64encode(image_file_2.read()).decode("utf-8")
inv_img = InvariantImage(base64_image_1)
with pytest.raises(AttributeError, match="'value' attribute cannot be reassigned"):
inv_img.value = base64_image_2
5 changes: 5 additions & 0 deletions testing/tests/custom_types/test_invariant_number.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests for the InvariantNumber class."""

import pytest

from invariant.custom_types.invariant_bool import InvariantBool
from invariant.custom_types.invariant_number import InvariantNumber

Expand All @@ -15,6 +16,10 @@ def test_invariant_number_initialization():
assert num.value == 3.14
assert num.addresses == []

# The value field is read-only.
with pytest.raises(AttributeError, match="'value' attribute cannot be reassigned"):
num.value = 5

with pytest.raises(TypeError, match="value must be an int or float"):
InvariantNumber("not_a_number")

Expand Down
4 changes: 4 additions & 0 deletions testing/tests/custom_types/test_invariant_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def test_invariant_string_initialization():
assert string.upper() == "WORLD"
assert string.lower() == "world"

# The value field is read-only.
with pytest.raises(AttributeError, match="'value' attribute cannot be reassigned"):
string.value = "new value"

# Test invalid value type
with pytest.raises(TypeError, match="value must be a str"):
InvariantString(123)
Expand Down
17 changes: 11 additions & 6 deletions testing/tests/custom_types/test_invariant_value.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests for the InvariantValue class."""

import pytest

from invariant.custom_types.invariant_bool import InvariantBool
from invariant.custom_types.invariant_dict import InvariantDict
from invariant.custom_types.invariant_number import InvariantNumber
Expand All @@ -11,13 +12,17 @@

def test_invariant_value_initialization():
"""Test initialization of InvariantValue."""
value = InvariantValue("test", ["address1"])
assert value.value == "test"
assert value.addresses == ["address1:0-4"]
invariant_value = InvariantValue("test", ["address1"])
assert invariant_value.value == "test"
assert invariant_value.addresses == ["address1:0-4"]

value = InvariantValue(123)
assert value.value == 123
assert value.addresses == []
invariant_value = InvariantValue(123)
assert invariant_value.value == 123
assert invariant_value.addresses == []

# The value field is read-only.
with pytest.raises(AttributeError, match="'value' attribute cannot be reassigned"):
invariant_value.value = "new value"

with pytest.raises(TypeError, match="addresses must be a list of strings"):
InvariantValue("test", ["address1", 123])
Expand Down

0 comments on commit be91675

Please sign in to comment.