2121 Iterable ,
2222 List ,
2323 Optional ,
24+ Sequence ,
2425 Set ,
2526 Type ,
2627 TypeVar ,
4647 CBORTag ,
4748 FrozenDict ,
4849 dumps ,
49- loads ,
5050 undefined ,
5151)
5252from frozenlist import FrozenList
@@ -199,6 +199,22 @@ def wrapper(cls, value: Primitive):
199199CBORBase = TypeVar ("CBORBase" , bound = "CBORSerializable" )
200200
201201
202+ def decode_array (self , subtype : int ) -> Sequence [Any ]:
203+ # Major tag 4
204+ length = self ._decode_length (subtype , allow_indefinite = True )
205+
206+ if length is None :
207+ return IndefiniteList (cast (Primitive , self .decode_array (subtype = subtype )))
208+ else :
209+ return self .decode_array (subtype = subtype )
210+
211+
212+ try :
213+ cbor2 ._decoder .major_decoders [4 ] = decode_array
214+ except Exception as e :
215+ logger .warning ("Failed to replace major decoder for indefinite array" , e )
216+
217+
202218def default_encoder (
203219 encoder : CBOREncoder , value : Union [CBORSerializable , IndefiniteList ]
204220):
@@ -265,7 +281,7 @@ class CBORSerializable:
265281 does not refer to itself, which could cause infinite loops.
266282 """
267283
268- def to_shallow_primitive (self ) -> Primitive :
284+ def to_shallow_primitive (self ) -> Union [ Primitive , CBORSerializable ] :
269285 """
270286 Convert the instance to a CBOR primitive. If the primitive is a container, e.g. list, dict, the type of
271287 its elements could be either a Primitive or a CBORSerializable.
@@ -516,7 +532,11 @@ def from_cbor(cls, payload: Union[str, bytes]) -> CBORSerializable:
516532 """
517533 if type (payload ) is str :
518534 payload = bytes .fromhex (payload )
519- value = loads (payload ) # type: ignore
535+
536+ assert isinstance (payload , bytes )
537+
538+ value = cbor2 .loads (payload )
539+
520540 return cls .from_primitive (value )
521541
522542 def __repr__ (self ):
@@ -538,7 +558,7 @@ def _restore_dataclass_field(
538558
539559 if "object_hook" in f .metadata :
540560 return f .metadata ["object_hook" ](v )
541- return _restore_typed_primitive (f .type , v )
561+ return _restore_typed_primitive (cast ( Any , f .type ) , v )
542562
543563
544564def _restore_typed_primitive (
@@ -580,10 +600,14 @@ def _restore_typed_primitive(
580600 raise DeserializeException (
581601 f"List types need exactly one type argument, but got { t_args } "
582602 )
583- t = t_args [0 ]
584- if not isinstance (v , list ):
603+ t_subtype = t_args [0 ]
604+ if not isinstance (v , ( list , IndefiniteList ) ):
585605 raise DeserializeException (f"Expected type list but got { type (v )} " )
586- return IndefiniteList ([_restore_typed_primitive (t , w ) for w in v ])
606+ v_list = [_restore_typed_primitive (t_subtype , w ) for w in v ]
607+ if t == IndefiniteList :
608+ return IndefiniteList (v_list )
609+ else :
610+ return v_list
587611 elif isclass (t ) and t == ByteString :
588612 if not isinstance (v , bytes ):
589613 raise DeserializeException (f"Expected type bytes but got { type (v )} " )
@@ -712,8 +736,10 @@ def to_shallow_primitive(self) -> Primitive:
712736 return primitives
713737
714738 @classmethod
715- @limit_primitive_type (list , tuple )
716- def from_primitive (cls : Type [ArrayBase ], values : Union [list , tuple ]) -> ArrayBase :
739+ @limit_primitive_type (list , tuple , IndefiniteList )
740+ def from_primitive (
741+ cls : Type [ArrayBase ], values : Union [list , tuple , IndefiniteList ]
742+ ) -> ArrayBase :
717743 """Restore a primitive value to its original class type.
718744
719745 Args:
0 commit comments