Skip to content

Handle "nullable" array types  #121

@tal-franji

Description

@tal-franji

If given "nullable":true in schema - array value still fails on null value.
Suggested patch to schemas.py:

class Model:
    """
    A Model is a representation of a Schema as a request or response.  Models
    are generated from Schema objects by called :any:`Schema.model` with the
    contents of a response.
    """

    __slots__ = ["_raw_data", "_schema"]

    def __init__(self, data, schema):
        """
        Creates a new Model from data.  This should never be called directly,
        but instead should be called through :any:`Schema.model` to generate a
        Model from a defined Schema.

        :param data: The data to create this Model with
        :type data: dict
        """
        data = data or {}

        self._raw_data = data
        self._schema = schema

        for s in self.__slots__:
            # initialize all slots to None
            setattr(self, s, None)

        keys = set(data.keys()) - frozenset(self.__slots__)
        if keys:
            raise ModelError("Schema {} got unexpected attribute keys {}".format(self.__class__.__name__, keys))

        # collect the data into this model
        for k, v in data.items():
            prop = schema.properties[k]
            if prop.nullable and v is None:  #  added
                setattr(self, k, None)  # added
            elif prop.type == "array":  # change to elif
                # handle arrays
                item_schema = prop.items
                if v is None:   # added
                    raise ValueError(f"fiels '{k}' of type 'array' cannont be null (unless declared as nullable)")  # added
                setattr(self, k, [item_schema.model(c) for c in v])
            elif prop.type == "object":
                # handle nested objects
                object_schema = prop
                setattr(self, k, object_schema.model(v))
            else:
                setattr(self, k, v)

    def __repr__(self):
        """
        A generic representation of this model
        """
        return str(dict(self))

    def __iter__(self):
        for s in self.__slots__:
            if s.startswith("_"):
                continue
            yield s, getattr(self, s)
        return

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions