@@ -244,9 +244,9 @@ def typeddict_rule(info: StructTypeInfo) -> StructConstructorSpec | None:
244
244
245
245
if typ_origin in (Required , NotRequired ):
246
246
args = get_args (typ )
247
- assert (
248
- len ( args ) == 1
249
- ), "typing.Required[] and typing.NotRequired[T] require a concrete type T."
247
+ assert len ( args ) == 1 , (
248
+ "typing.Required[] and typing.NotRequired[T] require a concrete type T."
249
+ )
250
250
typ = args [0 ]
251
251
del args
252
252
@@ -377,7 +377,9 @@ def namedtuple_rule(info: StructTypeInfo) -> StructConstructorSpec | None:
377
377
return StructConstructorSpec (instantiate = info .type , fields = tuple (field_list ))
378
378
379
379
@registry .struct_rule
380
- def sequence_rule (info : StructTypeInfo ) -> StructConstructorSpec | None :
380
+ def variable_length_sequence_rule (
381
+ info : StructTypeInfo ,
382
+ ) -> StructConstructorSpec | None :
381
383
if get_origin (info .type ) not in (
382
384
list ,
383
385
set ,
@@ -387,13 +389,34 @@ def sequence_rule(info: StructTypeInfo) -> StructConstructorSpec | None:
387
389
) or not isinstance (info .default , Iterable ):
388
390
return None
389
391
390
- contained_type = get_args (info .type )[0 ] if get_args (info .type ) else Any
392
+ # Cast is for mypy.
393
+ contained_type = cast (
394
+ type , get_args (info .type )[0 ] if get_args (info .type ) else Any
395
+ )
391
396
392
397
# If the inner type is a primitive, we'll just treat the whole type as
393
398
# a primitive.
394
- from ._registry import ConstructorRegistry
399
+ from ._registry import (
400
+ ConstructorRegistry ,
401
+ PrimitiveConstructorSpec ,
402
+ PrimitiveTypeInfo ,
403
+ )
395
404
396
- if ConstructorRegistry ._is_primitive_type (contained_type , set (info .markers )):
405
+ contained_primitive_spec = ConstructorRegistry .get_primitive_spec (
406
+ PrimitiveTypeInfo .make (contained_type , set (info .markers ))
407
+ )
408
+ if (
409
+ isinstance (contained_primitive_spec , PrimitiveConstructorSpec )
410
+ # Why do we check nargs?
411
+ # Because for primitives, we can't nest variable-length collections.
412
+ #
413
+ # For example, list[list[str]] can't be parsed as a single primitive.
414
+ #
415
+ # However, list[list[str]] can be parsed if the outer type is
416
+ # handled as a struct (and a default value is provided, which we
417
+ # check above).
418
+ and contained_primitive_spec .nargs != "*"
419
+ ):
397
420
return None
398
421
399
422
field_list = []
0 commit comments