@@ -52,6 +52,7 @@ class GraphQLStrategy:
5252 """Strategy for generating various GraphQL nodes."""
5353
5454 schema : graphql .GraphQLSchema
55+ alphabet : st .SearchStrategy [str ]
5556 custom_scalars : CustomScalarStrategies = dataclasses .field (default_factory = dict )
5657 # As the schema is assumed to be immutable, there are a few strategy caches possible for internal components
5758 # This is a per-method cache without limits as they are proportionate to the schema size
@@ -79,7 +80,7 @@ def values(
7980 type_name = type_ .name
8081 if type_name in self .custom_scalars :
8182 return primitives .custom (self .custom_scalars [type_name ], nullable , default = default )
82- return primitives .scalar (type_name , nullable , default = default )
83+ return primitives .scalar (alphabet = self . alphabet , type_name = type_name , nullable = nullable , default = default )
8384 if isinstance (type_ , graphql .GraphQLEnumType ):
8485 values = tuple (type_ .values )
8586 return primitives .enum (values , nullable , default = default )
@@ -372,13 +373,22 @@ def _make_strategy(
372373 type_ : graphql .GraphQLObjectType ,
373374 fields : Optional [Iterable [str ]] = None ,
374375 custom_scalars : Optional [CustomScalarStrategies ] = None ,
376+ alphabet : st .SearchStrategy [str ],
375377) -> st .SearchStrategy [List [graphql .FieldNode ]]:
376378 if fields is not None :
377379 fields = tuple (fields )
378380 validation .validate_fields (fields , list (type_ .fields ))
379381 if custom_scalars :
380382 validation .validate_custom_scalars (custom_scalars )
381- return GraphQLStrategy (schema , custom_scalars or {}).selections (type_ , fields = fields )
383+ return GraphQLStrategy (schema = schema , alphabet = alphabet , custom_scalars = custom_scalars or {}).selections (
384+ type_ , fields = fields
385+ )
386+
387+
388+ def _build_alphabet (allow_x00 : bool = True , codec : Optional [str ] = "utf-8" ) -> st .SearchStrategy [str ]:
389+ return st .characters (
390+ codec = codec , min_codepoint = 0 if allow_x00 else 1 , max_codepoint = 0xFFFF , blacklist_categories = ["Cs" ]
391+ )
382392
383393
384394@cacheable # type: ignore
@@ -388,25 +398,31 @@ def queries(
388398 fields : Optional [Iterable [str ]] = None ,
389399 custom_scalars : Optional [CustomScalarStrategies ] = None ,
390400 print_ast : AstPrinter = graphql .print_ast ,
401+ allow_x00 : bool = True ,
402+ codec : Optional [str ] = "utf-8" ,
391403) -> st .SearchStrategy [str ]:
392- """A strategy for generating valid queries for the given GraphQL schema.
404+ r """A strategy for generating valid queries for the given GraphQL schema.
393405
394406 The output query will contain a subset of fields defined in the `Query` type.
395407
396408 :param schema: GraphQL schema as a string or `graphql.GraphQLSchema`.
397409 :param fields: Restrict generated fields to ones in this list.
398410 :param custom_scalars: Strategies for generating custom scalars.
399411 :param print_ast: A function to convert the generated AST to a string.
412+ :param allow_x00: Determines whether to allow the generation of `\x00` bytes within strings.
413+ :param codec: Specifies the codec used for generating strings.
400414 """
401415 parsed_schema = validation .maybe_parse_schema (schema )
402416 if parsed_schema .query_type is None :
403417 raise InvalidArgument ("Query type is not defined in the schema" )
418+ alphabet = _build_alphabet (allow_x00 = allow_x00 , codec = codec )
404419 return (
405420 _make_strategy (
406421 parsed_schema ,
407422 type_ = parsed_schema .query_type ,
408423 fields = fields ,
409424 custom_scalars = custom_scalars ,
425+ alphabet = alphabet ,
410426 )
411427 .map (make_query )
412428 .map (print_ast )
@@ -420,25 +436,31 @@ def mutations(
420436 fields : Optional [Iterable [str ]] = None ,
421437 custom_scalars : Optional [CustomScalarStrategies ] = None ,
422438 print_ast : AstPrinter = graphql .print_ast ,
439+ allow_x00 : bool = True ,
440+ codec : Optional [str ] = "utf-8" ,
423441) -> st .SearchStrategy [str ]:
424- """A strategy for generating valid mutations for the given GraphQL schema.
442+ r """A strategy for generating valid mutations for the given GraphQL schema.
425443
426444 The output mutation will contain a subset of fields defined in the `Mutation` type.
427445
428446 :param schema: GraphQL schema as a string or `graphql.GraphQLSchema`.
429447 :param fields: Restrict generated fields to ones in this list.
430448 :param custom_scalars: Strategies for generating custom scalars.
431449 :param print_ast: A function to convert the generated AST to a string.
450+ :param allow_x00: Determines whether to allow the generation of `\x00` bytes within strings.
451+ :param codec: Specifies the codec used for generating strings.
432452 """
433453 parsed_schema = validation .maybe_parse_schema (schema )
434454 if parsed_schema .mutation_type is None :
435455 raise InvalidArgument ("Mutation type is not defined in the schema" )
456+ alphabet = _build_alphabet (allow_x00 = allow_x00 , codec = codec )
436457 return (
437458 _make_strategy (
438459 parsed_schema ,
439460 type_ = parsed_schema .mutation_type ,
440461 fields = fields ,
441462 custom_scalars = custom_scalars ,
463+ alphabet = alphabet ,
442464 )
443465 .map (make_mutation )
444466 .map (print_ast )
@@ -452,13 +474,17 @@ def from_schema(
452474 fields : Optional [Iterable [str ]] = None ,
453475 custom_scalars : Optional [CustomScalarStrategies ] = None ,
454476 print_ast : AstPrinter = graphql .print_ast ,
477+ allow_x00 : bool = True ,
478+ codec : Optional [str ] = "utf-8" ,
455479) -> st .SearchStrategy [str ]:
456- """A strategy for generating valid queries and mutations for the given GraphQL schema.
480+ r """A strategy for generating valid queries and mutations for the given GraphQL schema.
457481
458482 :param schema: GraphQL schema as a string or `graphql.GraphQLSchema`.
459483 :param fields: Restrict generated fields to ones in this list.
460484 :param custom_scalars: Strategies for generating custom scalars.
461485 :param print_ast: A function to convert the generated AST to a string.
486+ :param allow_x00: Determines whether to allow the generation of `\x00` bytes within strings.
487+ :param codec: Specifies the codec used for generating strings.
462488 """
463489 parsed_schema = validation .maybe_parse_schema (schema )
464490 if custom_scalars :
@@ -479,7 +505,8 @@ def from_schema(
479505 available_fields .extend (mutation .fields )
480506 validation .validate_fields (fields , available_fields )
481507
482- strategy = GraphQLStrategy (parsed_schema , custom_scalars or {})
508+ alphabet = _build_alphabet (allow_x00 = allow_x00 , codec = codec )
509+ strategy = GraphQLStrategy (parsed_schema , alphabet = alphabet , custom_scalars = custom_scalars or {})
483510 strategies = [
484511 strategy .selections (type_ , fields = type_fields ).map (node_factory ).map (print_ast )
485512 for (type_ , type_fields , node_factory ) in (
0 commit comments