@@ -36,14 +36,14 @@ def __call__(cls, *args, **kwargs) -> MetaType | BaseType:
3636 if len (args ) == 1 and not isinstance (args [0 ], cls ):
3737 stream = args [0 ]
3838
39- if hasattr (stream , "read" ):
39+ if _is_readable_type (stream ):
4040 return cls ._read (stream )
4141
4242 if issubclass (cls , bytes ) and isinstance (stream , bytes ) and len (stream ) == cls .size :
4343 # Shortcut for char/bytes type
4444 return type .__call__ (cls , * args , ** kwargs )
4545
46- if isinstance (stream , ( bytes , memoryview , bytearray ) ):
46+ if _is_buffer_type (stream ):
4747 return cls .reads (stream )
4848
4949 return type .__call__ (cls , * args , ** kwargs )
@@ -83,7 +83,7 @@ def read(cls, obj: BinaryIO | bytes) -> BaseType:
8383 Returns:
8484 The parsed value of this type.
8585 """
86- if isinstance (obj , ( bytes , memoryview , bytearray ) ):
86+ if _is_buffer_type (obj ):
8787 return cls .reads (obj )
8888
8989 return cls ._read (obj )
@@ -113,7 +113,7 @@ def dumps(cls, value: Any) -> bytes:
113113 cls ._write (out , value )
114114 return out .getvalue ()
115115
116- def _read (cls , stream : BinaryIO , context : dict [str , Any ] = None ) -> BaseType :
116+ def _read (cls , stream : BinaryIO , context : dict [str , Any ] | None = None ) -> BaseType :
117117 """Internal function for reading value.
118118
119119 Must be implemented per type.
@@ -124,7 +124,7 @@ def _read(cls, stream: BinaryIO, context: dict[str, Any] = None) -> BaseType:
124124 """
125125 raise NotImplementedError ()
126126
127- def _read_array (cls , stream : BinaryIO , count : int , context : dict [str , Any ] = None ) -> list [BaseType ]:
127+ def _read_array (cls , stream : BinaryIO , count : int , context : dict [str , Any ] | None = None ) -> list [BaseType ]:
128128 """Internal function for reading array values.
129129
130130 Allows type implementations to do optimized reading for their type.
@@ -145,7 +145,7 @@ def _read_array(cls, stream: BinaryIO, count: int, context: dict[str, Any] = Non
145145
146146 return [cls ._read (stream , context ) for _ in range (count )]
147147
148- def _read_0 (cls , stream : BinaryIO , context : dict [str , Any ] = None ) -> list [BaseType ]:
148+ def _read_0 (cls , stream : BinaryIO , context : dict [str , Any ] | None = None ) -> list [BaseType ]:
149149 """Internal function for reading null-terminated data.
150150
151151 "Null" is type specific, so must be implemented per type.
@@ -179,7 +179,7 @@ def _write_0(cls, stream: BinaryIO, array: list[BaseType]) -> int:
179179 stream: The stream to read from.
180180 array: The array to write.
181181 """
182- return cls ._write_array (stream , array + [cls ()])
182+ return cls ._write_array (stream , array + [cls . default ()])
183183
184184
185185class _overload :
@@ -225,7 +225,10 @@ class ArrayMetaType(MetaType):
225225 num_entries : int | Expression | None
226226 null_terminated : bool
227227
228- def _read (cls , stream : BinaryIO , context : dict [str , Any ] = None ) -> Array :
228+ def default (cls ) -> BaseType :
229+ return type .__call__ (cls , [cls .type .default ()] * (cls .num_entries if isinstance (cls .num_entries , int ) else 0 ))
230+
231+ def _read (cls , stream : BinaryIO , context : dict [str , Any ] | None = None ) -> Array :
229232 if cls .null_terminated :
230233 return cls .type ._read_0 (stream , context )
231234
@@ -243,11 +246,6 @@ def _read(cls, stream: BinaryIO, context: dict[str, Any] = None) -> Array:
243246
244247 return cls .type ._read_array (stream , num , context )
245248
246- def default (cls ) -> BaseType :
247- return type .__call__ (
248- cls , [cls .type .default () for _ in range (0 if cls .dynamic or cls .null_terminated else cls .num_entries )]
249- )
250-
251249
252250class Array (list , BaseType , metaclass = ArrayMetaType ):
253251 """Implements a fixed or dynamically sized array type.
@@ -261,7 +259,7 @@ class Array(list, BaseType, metaclass=ArrayMetaType):
261259 """
262260
263261 @classmethod
264- def _read (cls , stream : BinaryIO , context : dict [str , Any ] = None ) -> Array :
262+ def _read (cls , stream : BinaryIO , context : dict [str , Any ] | None = None ) -> Array :
265263 return cls (ArrayMetaType ._read (cls , stream , context ))
266264
267265 @classmethod
@@ -275,5 +273,13 @@ def _write(cls, stream: BinaryIO, data: list[Any]) -> int:
275273 return cls .type ._write_array (stream , data )
276274
277275
276+ def _is_readable_type (value : Any ) -> bool :
277+ return hasattr (value , "read" )
278+
279+
280+ def _is_buffer_type (value : Any ) -> bool :
281+ return isinstance (value , (bytes , memoryview , bytearray ))
282+
283+
278284# As mentioned in the BaseType class, we correctly set the type here
279285MetaType .ArrayType = Array
0 commit comments