jamcodec 0.0.1__tar.gz → 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. jamcodec-0.1.0/PKG-INFO +90 -0
  2. jamcodec-0.1.0/README.md +66 -0
  3. jamcodec-0.1.0/jamcodec/__init__.py +22 -0
  4. jamcodec-0.1.0/jamcodec/base.py +370 -0
  5. jamcodec-0.1.0/jamcodec/constants.py +1 -0
  6. jamcodec-0.1.0/jamcodec/exceptions.py +43 -0
  7. jamcodec-0.1.0/jamcodec/mixins.py +100 -0
  8. jamcodec-0.1.0/jamcodec/types.py +1234 -0
  9. jamcodec-0.1.0/jamcodec.egg-info/PKG-INFO +90 -0
  10. jamcodec-0.1.0/jamcodec.egg-info/SOURCES.txt +35 -0
  11. jamcodec-0.1.0/jamcodec.egg-info/requires.txt +10 -0
  12. {jamcodec-0.0.1 → jamcodec-0.1.0}/jamcodec.egg-info/top_level.txt +1 -0
  13. jamcodec-0.1.0/pyproject.toml +48 -0
  14. jamcodec-0.1.0/requirements.txt +1 -0
  15. jamcodec-0.1.0/test/test_array.py +82 -0
  16. jamcodec-0.1.0/test/test_bitarray.py +81 -0
  17. jamcodec-0.1.0/test/test_bitvec.py +108 -0
  18. jamcodec-0.1.0/test/test_boolean.py +57 -0
  19. jamcodec-0.1.0/test/test_bytes.py +71 -0
  20. jamcodec-0.1.0/test/test_compact.py +123 -0
  21. jamcodec-0.1.0/test/test_enum.py +65 -0
  22. jamcodec-0.1.0/test/test_float.py +53 -0
  23. jamcodec-0.1.0/test/test_hashmap.py +38 -0
  24. jamcodec-0.1.0/test/test_integer.py +60 -0
  25. jamcodec-0.1.0/test/test_map.py +87 -0
  26. jamcodec-0.1.0/test/test_mixins.py +156 -0
  27. jamcodec-0.1.0/test/test_option.py +61 -0
  28. jamcodec-0.1.0/test/test_scale_types.py +47 -0
  29. jamcodec-0.1.0/test/test_scalebytes.py +62 -0
  30. jamcodec-0.1.0/test/test_string.py +57 -0
  31. jamcodec-0.1.0/test/test_struct.py +99 -0
  32. jamcodec-0.1.0/test/test_tuple.py +54 -0
  33. jamcodec-0.1.0/test/test_varint.py +53 -0
  34. jamcodec-0.1.0/test/test_vec.py +52 -0
  35. jamcodec-0.0.1/PKG-INFO +0 -222
  36. jamcodec-0.0.1/README.md +0 -3
  37. jamcodec-0.0.1/jamcodec/__init__.py +0 -6
  38. jamcodec-0.0.1/jamcodec.egg-info/PKG-INFO +0 -222
  39. jamcodec-0.0.1/jamcodec.egg-info/SOURCES.txt +0 -10
  40. jamcodec-0.0.1/jamcodec.egg-info/requires.txt +0 -5
  41. jamcodec-0.0.1/pyproject.toml +0 -39
  42. jamcodec-0.0.1/requirements.txt +0 -1
  43. {jamcodec-0.0.1 → jamcodec-0.1.0}/LICENSE +0 -0
  44. {jamcodec-0.0.1 → jamcodec-0.1.0}/jamcodec.egg-info/dependency_links.txt +0 -0
  45. {jamcodec-0.0.1 → jamcodec-0.1.0}/setup.cfg +0 -0
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.2
2
+ Name: jamcodec
3
+ Version: 0.1.0
4
+ Summary: Python JAM Codec Library
5
+ Author-email: JAMdot Technologies <dev@jamdot.tech>
6
+ Project-URL: Homepage, https://github.com/JAMdotTech/py-jam-codec
7
+ Keywords: jam,codec
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: <4,>=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: more-itertools>=8.6.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: coverage==5.3; extra == "dev"
18
+ Requires-Dist: pytest>=6.1.2; extra == "dev"
19
+ Requires-Dist: mkdocs; extra == "dev"
20
+ Requires-Dist: mkdocs-material; extra == "dev"
21
+ Requires-Dist: mkdocs-autorefs; extra == "dev"
22
+ Requires-Dist: mkdocstrings; extra == "dev"
23
+ Requires-Dist: mkdocstrings[python]; extra == "dev"
24
+
25
+ # Python JAM Codec
26
+
27
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/polkascan/py-scale-codec/unittests.yml?branch=master)](https://github.com/polkascan/py-scale-codec/actions/workflows/unittests.yml?query=workflow%3A%22Run+unit+tests%22)
28
+ [![Latest Version](https://img.shields.io/pypi/v/scalecodec.svg)](https://pypi.org/project/scalecodec/)
29
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/scalecodec.svg)](https://pypi.org/project/scalecodec/)
30
+ [![License](https://img.shields.io/pypi/l/scalecodec.svg)](https://github.com/polkascan/py-scale-codec/blob/master/LICENSE)
31
+
32
+
33
+ ## Description
34
+ Python implementation of the JAM codec as specified in the graypaper.
35
+
36
+
37
+ ## Installation
38
+ ```bash
39
+ pip install jamcodec
40
+ ```
41
+
42
+ ## Code examples
43
+
44
+ ```python
45
+ from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, Compact, Tuple, Enum
46
+
47
+ # encode a Vec<u16>
48
+ obj = Vec(U16).new()
49
+ value = [1, 2]
50
+ data = obj.encode(value)
51
+
52
+ # Define and decode a Struct
53
+ scale_obj = Struct(test=U8, test2=Tuple(U8, U8)).new()
54
+ value = scale_obj.decode(JamBytes("0x020105"))
55
+
56
+ # Define and encode an Enum
57
+ scale_obj = Enum(
58
+ Bool=Bool(),
59
+ Number=U32,
60
+ Complex=Struct(data=String(), version=Compact(U8)),
61
+ None_=None
62
+ ).new()
63
+ value = {'Bool': True}
64
+
65
+ data = scale_obj.encode(value)
66
+ ```
67
+
68
+ ## Examples of different types
69
+
70
+ | Type | Description | Example SCALE decoding value | SCALE encoded value |
71
+ |------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|---------------------------------------------------------------------------------|
72
+ | `bool` | Boolean values are encoded using the least significant bit of a single byte. | `True` | `0x01` |
73
+ | `u16` | Basic integers are encoded using a fixed-width little-endian (LE) format. | `42` | `0x2a00` |
74
+ | `VarInt64` | xxxxxxx | `0` | `0x00` |
75
+ | | | `1` | `0x04` |
76
+ | | | `42` | `0xa8` |
77
+ | | | `69` | `0x1501` |
78
+ | | | `100000000000000` | `0x0b00407a10f35a` |
79
+ | `Vec` | A collection of same-typed values is encoded, prefixed with a compact encoding of the number of items, followed by each item's encoding concatenated in turn. | `[4, 8, 15, 16, 23, 42]` | `0x18040008000f00100017002a00` |
80
+ | `BitVec` | A sequence of bools, represented in a more space efficient bit format | `0b00000010_01111101` | `0x287d02` |
81
+ | `str`,`Bytes`, `String` | Strings are Vectors of bytes (`Vec<u8>`) containing a valid UTF8 sequence. | `"Test"` | `0x1054657374` |
82
+ | | | `b"Test"` | `0x1054657374` |
83
+ | | | `[84, 101, 115, 116]` | `0x1054657374` |
84
+ | `[u8; 4]` | Fixed sized array of in this case an `u8` | `b"babe"` | `0x62616265` |
85
+ | | | `"0x62616265"` | `0x62616265` |
86
+ | | | `[98, 97, 98, 101]` | `0x62616265` |
87
+ | `Enum` Example: `enum IntOrBool { Int(u8), Bool(bool),}` | A fixed number of variants, each mutually exclusive and potentially implying a further value or series of values. Encoded as the first byte identifying the index of the variant that the value is. Any further bytes are used to encode any data that the variant implies. Thus, no more than 256 variants are supported. | `{'Int': 8}` | `0x002a` |
88
+ | | | `{'Bool': True}` | `0x0101` |
89
+ | `Struct` Example: `struct Motion { pub votes: Vec<AccountId>, pub id: u32 }` | For structures, the values are named, but that is irrelevant for the encoding (names are ignored - only order matters). All containers store elements consecutively. The order of the elements is not fixed, depends on the container, and cannot be relied on at decoding. This implicitly means that decoding some byte-array into a specified structure that enforces an order and then re-encoding it could result in a different byte array than the original that was decoded. | `{"votes": ["5GDyPHLVHcQYPTWfygtPYeo gQjyZy7J9fsi4brPhgEFq4pcv"], "id": 4}` | `0x04b80269ec500e458a630846b99105c397ee57 4125823d6f4388e9c7572e115c0504000000` |
90
+
@@ -0,0 +1,66 @@
1
+ # Python JAM Codec
2
+
3
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/polkascan/py-scale-codec/unittests.yml?branch=master)](https://github.com/polkascan/py-scale-codec/actions/workflows/unittests.yml?query=workflow%3A%22Run+unit+tests%22)
4
+ [![Latest Version](https://img.shields.io/pypi/v/scalecodec.svg)](https://pypi.org/project/scalecodec/)
5
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/scalecodec.svg)](https://pypi.org/project/scalecodec/)
6
+ [![License](https://img.shields.io/pypi/l/scalecodec.svg)](https://github.com/polkascan/py-scale-codec/blob/master/LICENSE)
7
+
8
+
9
+ ## Description
10
+ Python implementation of the JAM codec as specified in the graypaper.
11
+
12
+
13
+ ## Installation
14
+ ```bash
15
+ pip install jamcodec
16
+ ```
17
+
18
+ ## Code examples
19
+
20
+ ```python
21
+ from jamcodec.types import JamBytes, Bool, String, U32, U8, U16, Struct, Vec, Compact, Tuple, Enum
22
+
23
+ # encode a Vec<u16>
24
+ obj = Vec(U16).new()
25
+ value = [1, 2]
26
+ data = obj.encode(value)
27
+
28
+ # Define and decode a Struct
29
+ scale_obj = Struct(test=U8, test2=Tuple(U8, U8)).new()
30
+ value = scale_obj.decode(JamBytes("0x020105"))
31
+
32
+ # Define and encode an Enum
33
+ scale_obj = Enum(
34
+ Bool=Bool(),
35
+ Number=U32,
36
+ Complex=Struct(data=String(), version=Compact(U8)),
37
+ None_=None
38
+ ).new()
39
+ value = {'Bool': True}
40
+
41
+ data = scale_obj.encode(value)
42
+ ```
43
+
44
+ ## Examples of different types
45
+
46
+ | Type | Description | Example SCALE decoding value | SCALE encoded value |
47
+ |------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|---------------------------------------------------------------------------------|
48
+ | `bool` | Boolean values are encoded using the least significant bit of a single byte. | `True` | `0x01` |
49
+ | `u16` | Basic integers are encoded using a fixed-width little-endian (LE) format. | `42` | `0x2a00` |
50
+ | `VarInt64` | xxxxxxx | `0` | `0x00` |
51
+ | | | `1` | `0x04` |
52
+ | | | `42` | `0xa8` |
53
+ | | | `69` | `0x1501` |
54
+ | | | `100000000000000` | `0x0b00407a10f35a` |
55
+ | `Vec` | A collection of same-typed values is encoded, prefixed with a compact encoding of the number of items, followed by each item's encoding concatenated in turn. | `[4, 8, 15, 16, 23, 42]` | `0x18040008000f00100017002a00` |
56
+ | `BitVec` | A sequence of bools, represented in a more space efficient bit format | `0b00000010_01111101` | `0x287d02` |
57
+ | `str`,`Bytes`, `String` | Strings are Vectors of bytes (`Vec<u8>`) containing a valid UTF8 sequence. | `"Test"` | `0x1054657374` |
58
+ | | | `b"Test"` | `0x1054657374` |
59
+ | | | `[84, 101, 115, 116]` | `0x1054657374` |
60
+ | `[u8; 4]` | Fixed sized array of in this case an `u8` | `b"babe"` | `0x62616265` |
61
+ | | | `"0x62616265"` | `0x62616265` |
62
+ | | | `[98, 97, 98, 101]` | `0x62616265` |
63
+ | `Enum` Example: `enum IntOrBool { Int(u8), Bool(bool),}` | A fixed number of variants, each mutually exclusive and potentially implying a further value or series of values. Encoded as the first byte identifying the index of the variant that the value is. Any further bytes are used to encode any data that the variant implies. Thus, no more than 256 variants are supported. | `{'Int': 8}` | `0x002a` |
64
+ | | | `{'Bool': True}` | `0x0101` |
65
+ | `Struct` Example: `struct Motion { pub votes: Vec<AccountId>, pub id: u32 }` | For structures, the values are named, but that is irrelevant for the encoding (names are ignored - only order matters). All containers store elements consecutively. The order of the elements is not fixed, depends on the container, and cannot be relied on at decoding. This implicitly means that decoding some byte-array into a specified structure that enforces an order and then re-encoding it could result in a different byte array than the original that was decoded. | `{"votes": ["5GDyPHLVHcQYPTWfygtPYeo gQjyZy7J9fsi4brPhgEFq4pcv"], "id": 4}` | `0x04b80269ec500e458a630846b99105c397ee57 4125823d6f4388e9c7572e115c0504000000` |
66
+
@@ -0,0 +1,22 @@
1
+ # Python SCALE Codec Library
2
+ #
3
+ # Copyright 2018-2024 Stichting Polkascan (Polkascan Foundation).
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ import os
18
+
19
+ if os.getenv('GITHUB_REF') and os.getenv('GITHUB_REF').startswith('refs/tags/v'):
20
+ __version__ = os.getenv('GITHUB_REF').replace('refs/tags/v', '')
21
+ else:
22
+ __version__ = '0.0.0-dev1'
@@ -0,0 +1,370 @@
1
+ # Python SCALE Codec Library
2
+ #
3
+ # Copyright 2018-2024 Stichting Polkascan (Polkascan Foundation).
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ import typing
17
+ from abc import abstractmethod
18
+ from typing import Optional, Union
19
+
20
+ from jamcodec.constants import TYPE_DECOMP_MAX_RECURSIVE
21
+ from jamcodec.exceptions import RemainingScaleBytesNotEmptyException, ScaleDecodeException
22
+
23
+ if typing.TYPE_CHECKING:
24
+ from jamcodec.mixins import Serializable
25
+
26
+
27
+ class JamBytes:
28
+ """
29
+ Representation of SCALE encoded Bytes.
30
+ """
31
+
32
+ def __init__(self, data: Union[str, bytes, bytearray, int]):
33
+ """
34
+ Constructs a SCALE bytes-stream with provided `data`
35
+
36
+ Parameters
37
+ ----------
38
+ data
39
+ """
40
+ self.offset = 0
41
+
42
+ if type(data) is bytearray:
43
+ self.data = data
44
+ elif type(data) is bytes:
45
+ self.data = bytearray(data)
46
+ elif type(data) is str and data[0:2] == '0x':
47
+ self.data = bytearray.fromhex(data[2:])
48
+ else:
49
+ raise ValueError("Provided data is not in supported format: provided '{}'".format(type(data)))
50
+
51
+ self.length = len(self.data)
52
+
53
+ def get_next_bytes(self, length: int) -> bytearray:
54
+ """
55
+ Retrieve `length` amount of bytes of the stream
56
+
57
+ Parameters
58
+ ----------
59
+ length: amount of requested bytes
60
+
61
+ Returns
62
+ -------
63
+ bytearray
64
+ """
65
+ if self.offset + length > self.length:
66
+ raise RemainingScaleBytesNotEmptyException(
67
+ f'No more bytes available (needed: {self.offset + length} / total: {self.length})'
68
+ )
69
+
70
+ data = self.data[self.offset:self.offset + length]
71
+ self.offset += length
72
+ return data
73
+
74
+ def get_remaining_bytes(self) -> bytearray:
75
+ """
76
+ Retrieves all remaining bytes from the stream
77
+
78
+ Returns
79
+ -------
80
+ bytearray
81
+ """
82
+
83
+ data = self.data[self.offset:]
84
+ self.offset = self.length
85
+ return data
86
+
87
+ def get_remaining_length(self) -> int:
88
+ """
89
+ Returns how many bytes are left in the stream
90
+
91
+ Returns
92
+ -------
93
+ int
94
+ """
95
+ return self.length - self.offset
96
+
97
+ def reset(self):
98
+ """
99
+ Resets the pointer of the stream to the beginning
100
+
101
+ Returns
102
+ -------
103
+
104
+ """
105
+ self.offset = 0
106
+
107
+ def copy(self):
108
+ return JamBytes(self.data)
109
+
110
+ def __str__(self):
111
+ return "0x{}".format(self.data.hex())
112
+
113
+ def __eq__(self, other):
114
+ if not hasattr(other, 'data'):
115
+ return False
116
+ return self.data == other.data
117
+
118
+ def __len__(self):
119
+ return len(self.data)
120
+
121
+ def __repr__(self):
122
+ return "<{}(data=0x{})>".format(self.__class__.__name__, self.data.hex())
123
+
124
+ def __add__(self, data):
125
+
126
+ if type(data) is JamBytes:
127
+ return JamBytes(self.data + data.data)
128
+
129
+ if type(data) is bytes:
130
+ data = bytearray(data)
131
+ elif type(data) == str and data[0:2] == '0x':
132
+ data = bytearray.fromhex(data[2:])
133
+
134
+ if type(data) is bytearray:
135
+ return JamBytes(self.data + data)
136
+
137
+ def __bytes__(self):
138
+ return self.to_bytes()
139
+
140
+ def to_bytes(self):
141
+ return bytes(self.data)
142
+
143
+ def to_hex(self) -> str:
144
+ """
145
+ Return a hex-string (e.g. "0x00") representation of the byte-stream
146
+
147
+ Returns
148
+ -------
149
+ str
150
+ """
151
+ return f'0x{self.data.hex()}'
152
+
153
+
154
+ class JamCodecTypeDef:
155
+
156
+ scale_type_cls = None
157
+ _deserialize_type = None
158
+
159
+ def __init__(self, name: str = None, metadata=None):
160
+ if self.scale_type_cls is None:
161
+ self.scale_type_cls = JamCodecType
162
+ self.name = name
163
+ self.runtime_config = None
164
+ self.metadata = metadata
165
+
166
+ def new(self, **kwargs) -> 'JamCodecType':
167
+ obj = self.scale_type_cls(type_def=self, **kwargs)
168
+ if 'value' in kwargs:
169
+ obj.deserialize(kwargs['value'])
170
+
171
+ if 'scale' in kwargs:
172
+ obj.decode(kwargs['scale'])
173
+
174
+ return obj
175
+
176
+ def impl(self, scale_type_cls: type = None, runtime_config=None) -> 'JamCodecTypeDef':
177
+ """
178
+
179
+ Returns:
180
+ object:
181
+ """
182
+ if scale_type_cls:
183
+ self.scale_type_cls = scale_type_cls
184
+ if runtime_config:
185
+ self.runtime_config = runtime_config
186
+
187
+ return self
188
+
189
+ # def create_from_registry_type(self, registry_type):
190
+
191
+
192
+ def encode(self, value: any) -> JamBytes:
193
+ pass
194
+
195
+ @abstractmethod
196
+ def decode(self, data: JamBytes) -> any:
197
+ pass
198
+
199
+ @abstractmethod
200
+ def serialize(self, value: any) -> any:
201
+ raise NotImplementedError()
202
+
203
+ @abstractmethod
204
+ def deserialize(self, value: any) -> any:
205
+ raise NotImplementedError()
206
+
207
+ def to_serializable_obj(self, value_object: any) -> 'Serializable':
208
+ return value_object
209
+
210
+
211
+ # TODO implement
212
+
213
+ @abstractmethod
214
+ def example_value(self, _recursion_level: int = 0, max_recursion: int = TYPE_DECOMP_MAX_RECURSIVE):
215
+
216
+ if _recursion_level > max_recursion:
217
+ return self.__class__.__name__
218
+ return self.__class__.__name__
219
+
220
+
221
+ class JamCodecType:
222
+
223
+ def __init__(self, type_def: JamCodecTypeDef, **kwargs):
224
+ # TODO remove kwargs
225
+
226
+ self.meta_info = None
227
+ self.type_def: JamCodecTypeDef = type_def
228
+ self.value_serialized = None
229
+ self.value_object = None
230
+
231
+ self._data = None
232
+ self._data_start_offset = 0
233
+ self._data_end_offset = 0
234
+
235
+ super().__init__()
236
+
237
+ def encode(self, value: Optional[any] = None) -> JamBytes:
238
+ if value is not None and issubclass(self.__class__, value.__class__):
239
+ # Accept instance of current class directly
240
+ self._data = value.data
241
+ self.value_object = value.value_object
242
+ self.value_serialized = value.value_serialized
243
+ return value.data
244
+
245
+ if value is None:
246
+ value = self.value_serialized
247
+
248
+ self._data = self.type_def.encode(value)
249
+ self._data_start_offset = self._data.offset
250
+ self._data_end_offset = self._data.length
251
+
252
+ self.value_serialized = value
253
+ self.value_object = self.deserialize(value)
254
+
255
+ return self._data
256
+
257
+ def decode(self, data: JamBytes, check_remaining=False) -> any:
258
+ self._data = data
259
+ self._data_start_offset = data.offset
260
+ # Decode type
261
+ self.value_object = self.type_def.decode(data)
262
+
263
+ self._data_end_offset = data.offset
264
+
265
+ if check_remaining and self._data_end_offset != self._data.length:
266
+ raise ScaleDecodeException(
267
+ f'Remaining ScaleBytes - Current offset: {self._data_end_offset} / length: {self._data.length}'
268
+ )
269
+
270
+ self.value_serialized = self.serialize()
271
+ return self.value_serialized
272
+
273
+ def serialize(self) -> Union[int, str, dict, tuple, bool]:
274
+ self.value_serialized = self.type_def.serialize(self.value_object)
275
+ return self.value_serialized
276
+
277
+ def deserialize(self, value_serialized: any):
278
+ if value_serialized and issubclass(self.__class__, self.value_serialized.__class__):
279
+ # Accept instance of current class directly
280
+ self.value_object = self.value_serialized.value_object
281
+ self.value_serialized = self.value_serialized.value_serialized
282
+ return self.value_object
283
+
284
+ self.value_object = self.type_def.deserialize(value_serialized)
285
+ self.value_serialized = self.type_def.serialize(self.value_object)
286
+
287
+ return self.value_object
288
+
289
+ def to_serializable_obj(self):
290
+ return self.type_def.to_serializable_obj(self.value_object)
291
+
292
+ @property
293
+ def value(self):
294
+ return self.value_serialized
295
+
296
+ @value.setter
297
+ def value(self, value):
298
+ self.value_serialized = value
299
+
300
+ @property
301
+ def data(self) -> Optional[JamBytes]:
302
+ """
303
+ Returns a ScaleBytes instance of the SCALE-bytes used in the decoding process
304
+
305
+ Returns
306
+ -------
307
+ bytearray
308
+ """
309
+ if self._data is not None:
310
+ return JamBytes(self._data.data[self._data_start_offset:self._data_end_offset])
311
+
312
+ def example_value(self):
313
+ return self.type_def.example_value()
314
+
315
+ def __repr__(self):
316
+
317
+ # if self.__class__ is not ScaleType:
318
+ # name = self.__class__.__name__
319
+ # else:
320
+ # name = self.type_def.__class__.__name__
321
+
322
+ name = self.type_def.__class__.__name__
323
+
324
+ if self.value_serialized is not None:
325
+ return f"<{name}(value={self.value_serialized})>"
326
+ elif self.data:
327
+ return f"<{name}(data={self.data.to_hex()})>"
328
+ else:
329
+ return f"<{name}>"
330
+
331
+ def __getitem__(self, item):
332
+ return self.value_object[item]
333
+
334
+ def __iter__(self):
335
+ for item in self.value_object:
336
+ yield item
337
+
338
+ def __eq__(self, other):
339
+ if isinstance(other, JamCodecType):
340
+ return other.value_serialized == self.value_serialized
341
+ else:
342
+ return other == self.value_serialized
343
+
344
+ def __gt__(self, other):
345
+ if isinstance(other, JamCodecType):
346
+ return self.value_serialized > other.value_serialized
347
+ else:
348
+ return self.value_serialized > other
349
+
350
+ def __ge__(self, other):
351
+ if isinstance(other, JamCodecType):
352
+ return self.value_serialized >= other.value_serialized
353
+ else:
354
+ return self.value_serialized >= other
355
+
356
+ def __lt__(self, other):
357
+ if isinstance(other, JamCodecType):
358
+ return self.value_serialized < other.value_serialized
359
+ else:
360
+ return self.value_serialized < other
361
+
362
+ def __le__(self, other):
363
+ if isinstance(other, JamCodecType):
364
+ return self.value_serialized <= other.value_serialized
365
+ else:
366
+ return self.value_serialized <= other
367
+
368
+
369
+ class JamCodecPrimitive(JamCodecTypeDef):
370
+ pass
@@ -0,0 +1 @@
1
+ TYPE_DECOMP_MAX_RECURSIVE = 9
@@ -0,0 +1,43 @@
1
+ # Python SCALE Codec Library
2
+ #
3
+ # Copyright 2018-2024 Stichting Polkascan (Polkascan Foundation).
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ class RemainingScaleBytesNotEmptyException(Exception):
19
+ pass
20
+
21
+
22
+ class InvalidScaleTypeValueException(Exception):
23
+ pass
24
+
25
+
26
+ class MetadataCallFunctionNotFound(ValueError):
27
+ pass
28
+
29
+
30
+ class ScaleDecodeException(ValueError):
31
+ pass
32
+
33
+
34
+ class ScaleEncodeException(ValueError):
35
+ pass
36
+
37
+
38
+ class ScaleDeserializeException(ValueError):
39
+ pass
40
+
41
+
42
+ class ScaleSerializeException(ValueError):
43
+ pass