diff --git a/src/graphql/type/definition.py b/src/graphql/type/definition.py index da312c89..61d1e6b9 100644 --- a/src/graphql/type/definition.py +++ b/src/graphql/type/definition.py @@ -1091,6 +1091,7 @@ def assert_union_type(type_: Any) -> GraphQLUnionType: class GraphQLEnumTypeKwargs(GraphQLNamedTypeKwargs, total=False): values: GraphQLEnumValueMap + names_as_values: Optional[bool] class GraphQLEnumType(GraphQLNamedType): @@ -1098,7 +1099,10 @@ class GraphQLEnumType(GraphQLNamedType): Some leaf values of requests and input values are Enums. GraphQL serializes Enum values as strings, however internally Enums can be represented by any kind of type, - often integers. They can also be provided as a Python Enum. + often integers. They can also be provided as a Python Enum. In this case, the flag + `names_as_values` determines what will be used as internal representation. The + default value of `False` will use the enum values, the value `True` will use the + enum names, and the value `None` will use the members themselves. Example:: @@ -1132,6 +1136,7 @@ def __init__( self, name: str, values: Union[GraphQLEnumValueMap, Mapping[str, Any], Type[Enum]], + names_as_values: Optional[bool] = False, description: Optional[str] = None, extensions: Optional[Dict[str, Any]] = None, ast_node: Optional[EnumTypeDefinitionNode] = None, @@ -1158,10 +1163,13 @@ def __init__( f"{name} values must be an Enum or a mapping" " with value names as keys." ) - values = cast(Dict, values) + values = cast(Dict[str, Any], values) else: - values = cast(Dict, values) - values = {key: value.value for key, value in values.items()} + values = cast(Dict[str, Enum], values) + if names_as_values is False: + values = {key: value.value for key, value in values.items()} + elif names_as_values is True: + values = {key: key for key in values} values = { assert_enum_value_name(key): value if isinstance(value, GraphQLEnumValue) diff --git a/tests/type/test_definition.py b/tests/type/test_definition.py index 38691e4b..1c5b5bfc 100644 --- a/tests/type/test_definition.py +++ b/tests/type/test_definition.py @@ -1,3 +1,4 @@ +from enum import Enum from math import isnan, nan from typing import cast, Dict @@ -1057,6 +1058,50 @@ def rejects_a_union_type_with_incorrect_extension_ast_nodes(): def describe_type_system_enums(): + def defines_an_enum_using_a_dict(): + enum_type = GraphQLEnumType("SomeEnum", {"RED": 1, "BLUE": 2}) + assert enum_type.values == { + "RED": GraphQLEnumValue(1), + "BLUE": GraphQLEnumValue(2), + } + + def defines_an_enum_using_an_enum_value_map(): + red, blue = GraphQLEnumValue(1), GraphQLEnumValue(2) + enum_type = GraphQLEnumType("SomeEnum", {"RED": red, "BLUE": blue}) + assert enum_type.values == {"RED": red, "BLUE": blue} + + def defines_an_enum_using_a_python_enum(): + colors = Enum("Colors", "RED BLUE") + enum_type = GraphQLEnumType("SomeEnum", colors) + assert enum_type.values == { + "RED": GraphQLEnumValue(1), + "BLUE": GraphQLEnumValue(2), + } + + def defines_an_enum_using_values_of_a_python_enum(): + colors = Enum("Colors", "RED BLUE") + enum_type = GraphQLEnumType("SomeEnum", colors, names_as_values=False) + assert enum_type.values == { + "RED": GraphQLEnumValue(1), + "BLUE": GraphQLEnumValue(2), + } + + def defines_an_enum_using_names_of_a_python_enum(): + colors = Enum("Colors", "RED BLUE") + enum_type = GraphQLEnumType("SomeEnum", colors, names_as_values=True) + assert enum_type.values == { + "RED": GraphQLEnumValue("RED"), + "BLUE": GraphQLEnumValue("BLUE"), + } + + def defines_an_enum_using_members_of_a_python_enum(): + colors = Enum("Colors", "RED BLUE") + enum_type = GraphQLEnumType("SomeEnum", colors, names_as_values=None) + assert enum_type.values == { + "RED": GraphQLEnumValue(colors.RED), + "BLUE": GraphQLEnumValue(colors.BLUE), + } + def defines_an_enum_type_with_a_description(): description = "nice enum" enum_type = GraphQLEnumType(