def print_type(gtype, nonnull=True, except_types=()): if isinstance(gtype, except_types): raise ValidationError(f'{gtype} is not a valid type') literal = None if is_union(gtype): if is_optional(gtype): return f'{print_type(gtype.__args__[0], nonnull=False, except_types=except_types)}' # noqa else: raise ValidationError( f'Native Union type is not supported except Optional') elif is_list(gtype): literal = f'[{print_type(gtype.__args__[0], except_types=except_types)}]' # noqa elif isinstance(gtype, types.ObjectType): literal = f'{gtype.__name__}' elif gtype in VALID_BASIC_TYPES: literal = VALID_BASIC_TYPES[gtype] elif gtype is None or gtype == type(None): # noqa return 'null' elif isinstance(gtype, types.UnionType): literal = f'{gtype.__name__}' elif isinstance(gtype, types.EnumType): literal = f'{gtype.__name__}' elif isinstance(gtype, types.InputType): literal = f'{gtype.__name__}' elif isinstance(gtype, types.InterfaceType): literal = f'{gtype.__name__}' else: raise ValidationError(f'Can not convert type {gtype} to GraphQL type') if nonnull: literal += '!' return literal
def validate(cls): if cls.__validated__: return cls.__validated__ = True for _, field in cls.__fields__.items(): if not isinstance(field, (Field, ResolverField)): raise ValidationError(f'{field} is an invalid field type') if field.ftype == _empty: raise ValidationError( f'The return type of resolver "{cls.__name__}.{field.name}" must not be empty' ) print_type(field.ftype, except_types=(types.InputType)) if isinstance(field, ResolverField): for gtype in field.params.values(): print_type(gtype) shelled = shelling_type(gtype) if isinstance(shelled, types.InputType): shelled.validate() if isinstance(field.ftype, ObjectType): field.ftype.validate() if is_union(field.ftype): shelled = shelling_type(field.ftype) if isinstance(shelled, ObjectType): shelled.validate()
def register_types(cls, types): for ptype in types: if ptype in cls.validated_type: continue cls.validated_type.append(ptype) if isinstance(ptype, ObjectType): cls.registered_type.append(ptype) cls.register_fields_type(ptype.__fields__.values()) elif is_union(ptype) or is_list(ptype): cls.register_types(ptype.__args__) elif isinstance(ptype, UnionType): cls.registered_type.append(ptype) cls.register_types(ptype.members) elif isinstance(ptype, InputType): cls.registered_type.append(ptype) cls.register_fields_type(ptype.__fields__.values()) elif isinstance(ptype, InterfaceType): cls.registered_type.append(ptype) cls.register_fields_type(ptype.__fields__.values()) cls.register_types(ptype.__subclasses__()) elif isinstance(ptype, EnumType): cls.registered_type.append(ptype) else: # Other basic types, do not need be handled pass
def replace_forwarded_type(self, ptype): if hasattr(ptype, '__args__'): args = [self.replace_forwarded_type(t) for t in ptype.__args__] if is_union(ptype): return PyUnion[tuple(args)] elif is_list(ptype): return List[tuple(args)] elif isinstance(ptype, (str, ForwardRef)): return self.get_type(ptype) return ptype
def test_is_union(): assert is_union(typing.Optional[str]) is True assert is_union(typing.Union[str, int, None]) is True assert is_union(str) is False