diff --git a/.github/workflows/deploypypi.yml b/.github/workflows/deploypypi.yml index cc9e97f..2867116 100644 --- a/.github/workflows/deploypypi.yml +++ b/.github/workflows/deploypypi.yml @@ -33,8 +33,8 @@ jobs: pip install setuptools wheel twine build - name: Build and publish env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} run: | python -m build twine upload dist/* diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 55ffc2f..1b204f5 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/README.md b/README.md index 464b514..14b2696 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ pip install jamcodec ## Code examples ```python -from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, Compact, Tuple, Enum +from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, VarInt64, Tuple, Enum # encode a Vec obj = Vec(U16).new() @@ -33,7 +33,7 @@ value = scale_obj.decode(JamBytes("0x020105")) scale_obj = Enum( Bool=Bool(), Number=U32, - Complex=Struct(data=String(), version=Compact(U8)), + Complex=Struct(data=String(), version=VarInt64), None_=None ).new() value = {'Bool': True} diff --git a/docs/index.md b/docs/index.md index 4aaa5bc..bf8e072 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ pip install jamcodec ## Code examples ```python -from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, Compact, Tuple, Enum +from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, VarInt64, Tuple, Enum # encode a Vec obj = Vec(U16).new() @@ -25,7 +25,7 @@ value = scale_obj.decode(JamBytes("0x020105")) scale_obj = Enum( Bool=Bool(), Number=U32, - Complex=Struct(data=String(), version=Compact(U8)), + Complex=Struct(data=String, version=VarInt64), None_=None ).new() value = {'Bool': True} diff --git a/jamcodec/types.py b/jamcodec/types.py index 7f6f78d..a704418 100644 --- a/jamcodec/types.py +++ b/jamcodec/types.py @@ -508,7 +508,7 @@ def example_value(self, _recursion_level: int = 0, max_recursion: int = TYPE_DEC return None, self.some.example_value() -class Compact(JamCodecTypeDef): +class CompactDef(JamCodecTypeDef): def __init__(self, type_: JamCodecTypeDef = None): self.type = type_ self.compact_length = 0 @@ -595,7 +595,6 @@ def __init__(self, type_def: JamCodecTypeDef): self.type_def = type_def def encode(self, value: list) -> JamBytes: - if self.type_def is U8: return Bytes.encode(value) @@ -959,8 +958,11 @@ def __init__(self, key_def: JamCodecTypeDef, value_def: JamCodecTypeDef): def encode(self, value: Union[typing.Mapping, list]) -> JamBytes: if isinstance(value, Mapping): - # Sort Map by keys - value = sorted(value.items(), key=lambda x: x[0]) + # Convert to list + value = value.items() + + # Sort Map by keys + value = sorted(value, key=lambda x: x[0]) # Encode length of Vec data = VarInt64.encode(len(value)) @@ -1137,9 +1139,6 @@ def example_value(self, _recursion_level: int = 0, max_recursion: int = TYPE_DEC class VarInt64Def(JamCodecTypeDef): - def encode(self, value: any, external_call=True) -> JamBytes: - return self.encode(value) - def encode(self, value: int) -> JamBytes: if value < 0: raise ScaleEncodeException("Cannot encode negative value") @@ -1235,3 +1234,4 @@ def example_value(self, _recursion_level: int = 0, max_recursion: int = TYPE_DEC HashMap = Map BTreeMap = Map VarInt64 = VarInt64Def() +Compact = CompactDef() diff --git a/test/test_compact.py b/test/test_compact.py index 79f081b..df04891 100644 --- a/test/test_compact.py +++ b/test/test_compact.py @@ -19,52 +19,52 @@ from jamcodec.base import JamBytes from jamcodec.exceptions import ScaleDecodeException, RemainingScaleBytesNotEmptyException -from jamcodec.types import Compact, U32, U128 +from jamcodec.types import CompactDef, U32, U128 class TestCompact(unittest.TestCase): def test_compact_u32(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.decode(JamBytes("0x02093d00")) self.assertEqual(obj.value, 1000000) def test_compact_u32_1byte(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.decode(JamBytes("0x18")) self.assertEqual(obj.value, 6) def test_compact_u32_remaining_bytes(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() with self.assertRaises(ScaleDecodeException): obj.decode(JamBytes("0x02093d0001"), check_remaining=True) def test_compact_u32_invalid(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() self.assertRaises(RemainingScaleBytesNotEmptyException, obj.decode, JamBytes("0x")) def test_compact_u32_1byte_encode(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.decode(JamBytes("0x18")) - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.encode(6) self.assertEqual(str(obj.data), "0x18") def test_compact_u32_2bytes_encode(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.encode(6000) self.assertEqual(str(obj.data), "0xc15d") def test_compact_u32_4bytes_encode(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.encode(1000000) self.assertEqual(str(obj.data), "0x02093d00") def test_compact_u32_larger_than_4bytes_encode(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.encode(150000000000000) self.assertEqual(str(obj.data), "0x0b0060b7986c88") @@ -72,10 +72,10 @@ def test_compact_u32_encode_decode(self): value = 2000001 - obj = Compact(U32).new() + obj = CompactDef(U32).new() data = obj.encode(value) - obj = Compact(U32).new() + obj = CompactDef(U32).new() self.assertEqual(obj.decode(data), value) @@ -83,10 +83,10 @@ def test_compact_u32_encode_decode_large(self): value = 2**30 - obj = Compact(U32).new() + obj = CompactDef(U32).new() data = obj.encode(value) - obj = Compact(U32).new() + obj = CompactDef(U32).new() self.assertEqual(obj.decode(data), value) @@ -96,7 +96,7 @@ def test_compact_balance_encode_decode(self): Balance = U128 - obj = Compact(Balance).new() + obj = CompactDef(Balance).new() data = obj.encode(value) self.assertEqual(str(scale_data), str(data)) @@ -105,13 +105,13 @@ def test_compact_balance_encode_decode(self): def test_balance(self): Balance = U128 - obj = Compact(Balance).new() + obj = CompactDef(Balance).new() obj.decode(JamBytes("0x130080cd103d71bc22")) self.assertEqual(obj.value, 2503000000000000000) def test_compact_no_type(self): data = JamBytes("0x02093d00") - compact = Compact().new() + compact = CompactDef().new() compact.decode(data) self.assertEqual(compact.value, 1000000) diff --git a/test/test_map.py b/test/test_map.py index ccde808..f6344a6 100644 --- a/test/test_map.py +++ b/test/test_map.py @@ -24,14 +24,13 @@ class TestMap(unittest.TestCase): - def test_map_encode(self): + def test_map_dict_encode(self): obj = Map(H256, Bytes).new() value = { "0xbb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa": b'\x01\x02', - "0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314": b'test', - + "0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314": b'test' } # Should be encoded sorted by key data = obj.encode(value) @@ -40,6 +39,23 @@ def test_map_encode(self): data ) + def test_map_encode_list(self): + obj = Map(H256, Bytes).new() + + value = [ + ("0xbb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa", b'\x01\x02'), + ("0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314", b'test') + ] + + # Should be encoded sorted by key + data = obj.encode(value) + self.assertEqual( + JamBytes( + "0x0203170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c1113140474657374bb30a42c1e62f0afda5f0a4e8a562f7a13a24cea00ee81917b86b89e801314aa020102" + ), + data + ) + def test_map_decode(self): obj = Map(U32, Bytes).new() @@ -49,6 +65,8 @@ def test_map_decode(self): self.assertEqual({2: b'test'}, obj.to_serializable_obj()) + + def test_mapping_type(self): class StorageMap(Mapping): diff --git a/test/test_scale_types.py b/test/test_scale_types.py index 568f651..84bf336 100644 --- a/test/test_scale_types.py +++ b/test/test_scale_types.py @@ -17,7 +17,7 @@ import unittest from jamcodec.base import JamBytes -from jamcodec.types import Compact, U32, U16, Tuple +from jamcodec.types import CompactDef, U32, U16, Tuple class TestScaleTypes(unittest.TestCase): @@ -29,19 +29,19 @@ def test_multiple_decode_without_error(self): self.assertEqual(obj.value, 64302) def test_value_equals_value_serialized_and_value_object(self): - obj = Tuple(Compact(U32), Compact(U32)).new() + obj = Tuple(CompactDef(U32), CompactDef(U32)).new() obj.decode(JamBytes("0x0c00")) self.assertEqual(obj.value, obj.value_serialized) self.assertEqual(obj.value, obj.value_object) def test_value_object(self): - obj = Tuple(Compact(U32), Compact(U32)).new() + obj = Tuple(CompactDef(U32), CompactDef(U32)).new() obj.decode(JamBytes("0x0c00")) self.assertEqual(obj.value_object[0].value_object, 3) self.assertEqual(obj.value_object[1].value_object, 0) def test_value_object_shorthand(self): - obj = Tuple(Compact(U32), Compact(U32)).new() + obj = Tuple(CompactDef(U32), CompactDef(U32)).new() obj.decode(JamBytes("0x0c00")) self.assertEqual(obj[0], 3) self.assertEqual(obj[1], 0) diff --git a/test/test_scalebytes.py b/test/test_scalebytes.py index 9d89870..d8d3af2 100644 --- a/test/test_scalebytes.py +++ b/test/test_scalebytes.py @@ -21,7 +21,7 @@ from jamcodec.base import JamBytes from jamcodec.exceptions import RemainingScaleBytesNotEmptyException -from jamcodec.types import Compact, U32, Array, U8, String +from jamcodec.types import CompactDef, U32, Array, U8, String class TestScaleBytes(unittest.TestCase): @@ -31,7 +31,7 @@ def test_unknown_data_format(self): self.assertRaises(ValueError, JamBytes, 'test') def test_bytes_data_format(self): - obj = Compact(U32).new() + obj = CompactDef(U32).new() obj.decode(JamBytes(b"\x02\x09\x3d\x00")) self.assertEqual(obj.value, 1000000) diff --git a/test/test_tuple.py b/test/test_tuple.py index fc4aacf..ca86964 100644 --- a/test/test_tuple.py +++ b/test/test_tuple.py @@ -18,13 +18,13 @@ import unittest from jamcodec.base import JamBytes -from jamcodec.types import Tuple, Compact, U32, U8 +from jamcodec.types import Tuple, CompactDef, U32, U8 class TestTuple(unittest.TestCase): def test_tuple_decode(self): - obj = Tuple(Compact(U32), Compact(U32)).new() + obj = Tuple(CompactDef(U32), CompactDef(U32)).new() obj.decode(JamBytes("0x0c00")) self.assertEqual(obj.value, (3, 0)) @@ -38,7 +38,7 @@ def test_tuple_encode_decode(self): self.assertEqual(value, scale_obj.value) def test_tuple_deserialize(self): - obj = Tuple(Compact(U32), Compact(U32)).new() + obj = Tuple(CompactDef(U32), CompactDef(U32)).new() obj.deserialize((3, 2)) self.assertEqual(obj.value, (3, 2))