Skip to content

Commit da6da64

Browse files
authored
Fix deep copy of plutus data (#225)
copy.deepcopy doesn't work natively for CBORTag, which is frequently used in PlutusData. This commit implements __deepcopy__ methods for PlutusData and RawPlutusData by serializing the object into cbor and deserializing them back to new objects.
1 parent 830090a commit da6da64

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

pycardano/plutus.py

+6
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,9 @@ def from_json(cls: Type[PlutusData], data: str) -> PlutusData:
666666
obj = json.loads(data)
667667
return cls.from_dict(obj)
668668

669+
def __deepcopy__(self, memo):
670+
return self.__class__.from_cbor(self.to_cbor())
671+
669672

670673
@dataclass
671674
class RawPlutusData(CBORSerializable):
@@ -692,6 +695,9 @@ def _dfs(obj):
692695
def from_primitive(cls: Type[RawPlutusData], value: CBORTag) -> RawPlutusData:
693696
return cls(value)
694697

698+
def __deepcopy__(self, memo):
699+
return self.__class__.from_cbor(self.to_cbor())
700+
695701

696702
Datum = Union[PlutusData, dict, int, bytes, IndefiniteList, RawCBOR, RawPlutusData]
697703
"""Plutus Datum type. A Union type that contains all valid datum types."""

test/pycardano/test_plutus.py

+32
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import copy
12
import unittest
23
from dataclasses import dataclass
34
from test.pycardano.util import check_two_way_cbor
45
from typing import Dict, List, Union
56

67
import pytest
8+
from cbor2 import CBORTag
79

810
from pycardano.exception import DeserializeException, SerializeException
911
from pycardano.plutus import (
@@ -284,3 +286,33 @@ def test_raw_plutus_data():
284286
raw_plutus_data = RawPlutusData.from_cbor(raw_plutus_cbor)
285287
assert raw_plutus_data.to_cbor() == raw_plutus_cbor
286288
check_two_way_cbor(raw_plutus_data)
289+
290+
291+
def test_clone_raw_plutus_data():
292+
tag = RawPlutusData(CBORTag(121, [1000]))
293+
294+
cloned_tag = copy.deepcopy(tag)
295+
assert cloned_tag == tag
296+
assert cloned_tag.to_cbor() == tag.to_cbor()
297+
298+
tag.data.value = [1001]
299+
300+
assert cloned_tag != tag
301+
302+
303+
def test_clone_plutus_data():
304+
key_hash = bytes.fromhex("c2ff616e11299d9094ce0a7eb5b7284b705147a822f4ffbd471f971a")
305+
deadline = 1643235300000
306+
testa = BigTest(MyTest(123, b"1234", IndefiniteList([4, 5, 6]), {1: b"1", 2: b"2"}))
307+
testb = LargestTest()
308+
my_vesting = VestingParam(
309+
beneficiary=key_hash, deadline=deadline, testa=testa, testb=testb
310+
)
311+
312+
cloned_vesting = copy.deepcopy(my_vesting)
313+
assert cloned_vesting == my_vesting
314+
assert cloned_vesting.to_cbor() == my_vesting.to_cbor()
315+
316+
my_vesting.deadline = 1643235300001
317+
318+
assert cloned_vesting != my_vesting

0 commit comments

Comments
 (0)