mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-28 18:14:19 -05:00
* Enable PEP604 Ruff rules * Fix harcoded signature in test * Hack CLVMStreamable test with note to fast follow
116 lines
3.4 KiB
Python
116 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import copy
|
|
from dataclasses import dataclass
|
|
|
|
import pytest
|
|
|
|
from chia.util.recursive_replace import recursive_replace
|
|
|
|
|
|
class TestC:
|
|
a: int
|
|
b: str
|
|
|
|
def __init__(self, a: int, b: str):
|
|
self.a = a
|
|
self.b = b
|
|
|
|
# WARNING: this is just a simple stand in for rust classes and is not a good
|
|
# reference for how such a method should be implemented in python
|
|
def replace(self, **kwargs: int | str | TestA | None) -> TestC:
|
|
ret = TestC(copy.deepcopy(self.a), copy.deepcopy(self.b))
|
|
for key, value in kwargs.items():
|
|
if key == "a":
|
|
ret.a = value # type: ignore[assignment]
|
|
elif key == "b": # pragma: no cover
|
|
ret.b = value # type: ignore[assignment]
|
|
else: # pragma: no cover
|
|
raise TypeError(f"unknown field {key}")
|
|
return ret
|
|
|
|
|
|
@dataclass
|
|
class TestA:
|
|
a: int
|
|
b: str
|
|
c: list[int]
|
|
d: TestC | None
|
|
|
|
|
|
class TestB:
|
|
a: int
|
|
b: str
|
|
c: TestA | None
|
|
|
|
def __init__(self, a: int, b: str, c: TestA | None):
|
|
self.a = a
|
|
self.b = b
|
|
self.c = c
|
|
|
|
# WARNING: this is just a simple stand in for rust classes and is not a good
|
|
# reference for how such a method should be implemented in python
|
|
def replace(self, **kwargs: int | str | TestA | None) -> TestB:
|
|
ret = TestB(copy.deepcopy(self.a), copy.deepcopy(self.b), copy.deepcopy(self.c))
|
|
for key, value in kwargs.items():
|
|
if key == "a": # pragma: no cover
|
|
ret.a = value # type: ignore[assignment]
|
|
elif key == "b":
|
|
ret.b = value # type: ignore[assignment]
|
|
elif key == "c":
|
|
ret.c = value # type: ignore[assignment]
|
|
else:
|
|
raise TypeError(f"unknown field {key}")
|
|
return ret
|
|
|
|
def __eq__(self, other: object) -> bool:
|
|
if isinstance(other, TestB):
|
|
return self.a == other.a and self.b == other.b and self.c == self.c
|
|
else:
|
|
return False # pragma: no cover
|
|
|
|
|
|
def test_recursive_replace_dataclass() -> None:
|
|
a = TestA(42, "foobar", [1337, 42], None)
|
|
a2 = recursive_replace(a, "b", "barfoo")
|
|
|
|
assert a.a == a2.a
|
|
assert a.b == "foobar"
|
|
assert a2.b == "barfoo"
|
|
assert a.c == a2.c
|
|
|
|
|
|
def test_recursive_replace_other() -> None:
|
|
b = TestB(42, "foobar", None)
|
|
b2 = recursive_replace(b, "b", "barfoo")
|
|
|
|
assert b.a == b2.a
|
|
assert b.b == "foobar"
|
|
assert b2.b == "barfoo"
|
|
assert b.c == b2.c
|
|
|
|
|
|
def test_recursive_replace() -> None:
|
|
b1 = TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], None))
|
|
b2 = recursive_replace(b1, "c.a", 110)
|
|
|
|
assert b1 == TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], None))
|
|
assert b2 == TestB(42, "foobar", TestA(110, "barfoo", [1, 2, 3], None))
|
|
|
|
|
|
def test_recursive_replace2() -> None:
|
|
b1 = TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], TestC(123, "345")))
|
|
b2 = recursive_replace(b1, "c.d.a", 110)
|
|
|
|
assert b1 == TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], TestC(123, "345")))
|
|
assert b2 == TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], TestC(110, "345")))
|
|
|
|
|
|
def test_recursive_replace_unknown() -> None:
|
|
b = TestB(42, "foobar", TestA(1337, "barfoo", [1, 2, 3], None))
|
|
with pytest.raises(TypeError):
|
|
recursive_replace(b, "c.foobar", 110)
|
|
|
|
with pytest.raises(TypeError):
|
|
recursive_replace(b, "foobar", 110)
|