def _safe_match_argument(expected_type, argument_value):
    """Return a MATCH (SQL) string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_match_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, basestring):
            argument_value = unicode(argument_value)
        return _safe_match_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(
                u'Attempting to represent a non-int as an int: '
                u'{}'.format(argument_value))
        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_match_date_and_datetime(expected_type, (datetime.date, ),
                                             argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_match_date_and_datetime(expected_type,
                                             (datetime.datetime, arrow.Arrow),
                                             argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_match_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(
            u'Could not safely represent the requested GraphQL type: '
            u'{} {}'.format(expected_type, argument_value))
def _safe_gremlin_argument(expected_type, argument_value):
    """Return a Gremlin string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_gremlin_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, six.string_types):
            if isinstance(argument_value,
                          bytes):  # likely to only happen in py2
                argument_value = argument_value.decode("utf-8")
            else:
                argument_value = six.text_type(argument_value)
        return _safe_gremlin_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(
                u"Attempting to represent a non-int as an int: "
                u"{}".format(argument_value))

        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDecimal.is_same_type(expected_type):
        return _safe_gremlin_decimal(argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type,
                                               (datetime.date, ),
                                               argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(
            expected_type, (datetime.datetime, arrow.Arrow), argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_gremlin_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(
            u"Could not safely represent the requested GraphQL type: "
            u"{} {}".format(expected_type, argument_value))
def _safe_gremlin_argument(expected_type, argument_value):
    """Return a Gremlin string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_gremlin_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, six.string_types):
            if isinstance(argument_value, bytes):  # should only happen in py3
                argument_value = argument_value.decode('utf-8')
            else:
                argument_value = six.text_type(argument_value)
        return _safe_gremlin_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(u'Attempting to represent a non-int as an int: '
                                              u'{}'.format(argument_value))

        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDecimal.is_same_type(expected_type):
        return _safe_gremlin_decimal(argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type, (datetime.date,), argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type,
                                               (datetime.datetime, arrow.Arrow), argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_gremlin_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(u'Could not safely represent the requested GraphQL type: '
                             u'{} {}'.format(expected_type, argument_value))
Example #4
0
def validate_argument_type(name, expected_type, value):
    """Ensure the value has the expected type and is usable in any of our backends, or raise errors.

    Backends are the database languages we have the ability to compile to, like OrientDB MATCH,
    Gremlin, or SQLAlchemy. This function should be stricter than the validation done by any
    specific backend. That way code that passes validation can be compiled to any backend.

    Args:
        name: string, the name of the argument. It will be used to provide a more descriptive error
              message if an error is raised.
        expected_type: GraphQLType we expect. All GraphQLNonNull type wrappers are stripped.
        value: object that can be interpreted as being of that type
    """
    stripped_type = strip_non_null_from_type(expected_type)
    if GraphQLString.is_same_type(stripped_type):
        if not isinstance(value, six.string_types):
            _raise_invalid_type_error(name, "string", value)
    elif GraphQLID.is_same_type(stripped_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(value, six.string_types):
            _raise_invalid_type_error(name, "string", value)
    elif GraphQLFloat.is_same_type(stripped_type):
        if not isinstance(value, float):
            _raise_invalid_type_error(name, "float", value)
    elif GraphQLInt.is_same_type(stripped_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(value, bool) or not isinstance(value, six.integer_types):
            _raise_invalid_type_error(name, "int", value)
    elif GraphQLBoolean.is_same_type(stripped_type):
        if not isinstance(value, bool):
            _raise_invalid_type_error(name, "bool", value)
    elif GraphQLDecimal.is_same_type(stripped_type):
        # Types we support are int, float, and Decimal, but not bool.
        # isinstance(True, int) returns True, so we explicitly forbid bool.
        if isinstance(value, bool):
            _raise_invalid_type_error(name, "decimal", value)
        if not isinstance(value, decimal.Decimal):
            try:
                decimal.Decimal(value)
            except decimal.InvalidOperation as e:
                raise GraphQLInvalidArgumentError(e)
    elif GraphQLDate.is_same_type(stripped_type):
        # Datetimes pass as instances of date. We want to explicitly only allow dates.
        if isinstance(
                value,
                datetime.datetime) or not isinstance(value, datetime.date):
            _raise_invalid_type_error(name, "date", value)
        try:
            stripped_type.serialize(value)
        except ValueError as e:
            raise GraphQLInvalidArgumentError(e)
    elif GraphQLDateTime.is_same_type(stripped_type):
        if not isinstance(value, (datetime.date, arrow.Arrow)):
            _raise_invalid_type_error(name, "datetime", value)
        try:
            stripped_type.serialize(value)
        except ValueError as e:
            raise GraphQLInvalidArgumentError(e)
    elif isinstance(stripped_type, GraphQLList):
        if not isinstance(value, list):
            _raise_invalid_type_error(name, "list", value)
        inner_type = strip_non_null_from_type(stripped_type.of_type)
        for element in value:
            validate_argument_type(name, inner_type, element)
    else:
        raise AssertionError(
            u"Could not safely represent the requested GraphQLType: "
            u"{} {}".format(stripped_type, value))