Exemplo n.º 1
0
    def _get_default_route_args(
            self,
            namespace,  # pylint: disable=unused-argument
            route,
            tag=False):
        """Returns a list of name / value string pairs representing the default arguments for
        a particular route."""
        data_type, _ = unwrap_nullable(route.arg_data_type)
        if is_struct_type(data_type):
            arg_list = []
            for field in data_type.all_fields:
                if not field.has_default and not is_nullable_type(
                        field.data_type):
                    arg_list.append((fmt_var(field.name), fmt_type(
                        field.data_type, tag=tag)))

            doc_list = ([(fmt_var(f.name), self.process_doc(f.doc, self._docf))
                         for f in data_type.fields
                         if f.doc and not f.has_default and
                         not is_nullable_type(f.data_type)])
        else:
            arg_list = []
            doc_list = []

        return arg_list, doc_list
Exemplo n.º 2
0
    def _get_default_route_args(
            self,
            namespace,  # pylint: disable=unused-argument
            route,
            tag=False):
        """Returns a list of name / value string pairs representing the default arguments for
        a particular route."""
        data_type, _ = unwrap_nullable(route.arg_data_type)
        if is_struct_type(data_type):
            arg_list = []
            for field in data_type.all_fields:
                if not field.has_default and not is_nullable_type(
                        field.data_type):
                    arg_list.append(
                        (fmt_var(field.name), fmt_type(field.data_type,
                                                       tag=tag)))

            doc_list = ([(fmt_var(f.name), self.process_doc(f.doc, self._docf))
                         for f in data_type.fields
                         if f.doc and not f.has_default
                         and not is_nullable_type(f.data_type)])
        else:
            arg_list = []
            doc_list = []

        return arg_list, doc_list
Exemplo n.º 3
0
 def _python_type_mapping(self, ns, data_type):
     """Map Stone data types to their most natural equivalent in Python
     for documentation purposes."""
     if is_string_type(data_type):
         return 'str'
     elif is_bytes_type(data_type):
         return 'bytes'
     elif is_boolean_type(data_type):
         return 'bool'
     elif is_float_type(data_type):
         return 'float'
     elif is_integer_type(data_type):
         return 'long'
     elif is_void_type(data_type):
         return 'None'
     elif is_timestamp_type(data_type):
         return 'datetime.datetime'
     elif is_alias(data_type):
         return self._python_type_mapping(ns, data_type.data_type)
     elif is_user_defined_type(data_type):
         class_name = class_name_for_data_type(data_type)
         if data_type.namespace.name != ns.name:
             return '%s.%s_validator' % (
                 data_type.namespace.name, class_name)
         else:
             return class_name
     elif is_list_type(data_type):
         # PyCharm understands this description format for a list
         return 'list of [{}]'.format(self._python_type_mapping(
             ns, data_type.data_type))
     elif is_nullable_type(data_type):
         return 'Optional[{}]'.format(
             self._python_type_mapping(ns, data_type.data_type))
     else:
         raise TypeError('Unknown data type %r' % data_type)
Exemplo n.º 4
0
 def _generate_union_class_variant_creators(self, ns, data_type):
     """
     Each non-symbol, non-any variant has a corresponding class method that
     can be used to construct a union with that variant selected.
     """
     for field in data_type.fields:
         if not is_void_type(field.data_type):
             field_name = fmt_func(field.name)
             field_name_reserved_check = fmt_func(field.name, True)
             if is_nullable_type(field.data_type):
                 field_dt = field.data_type.data_type
             else:
                 field_dt = field.data_type
             self.emit('@classmethod')
             self.emit('def {}(cls, val):'.format(field_name_reserved_check))
             with self.indent():
                 self.emit('"""')
                 self.emit_wrapped_text(
                     'Create an instance of this class set to the ``%s`` '
                     'tag with value ``val``.' % field_name)
                 self.emit()
                 self.emit(':param {} val:'.format(
                     self._python_type_mapping(ns, field_dt)))
                 self.emit(':rtype: {}'.format(
                     fmt_class(data_type.name)))
                 self.emit('"""')
                 self.emit("return cls('{}', val)".format(field_name))
             self.emit()
Exemplo n.º 5
0
 def _python_type_mapping(self, ns, data_type):
     """Map Stone data types to their most natural equivalent in Python
     for documentation purposes."""
     if is_string_type(data_type):
         return 'str'
     elif is_bytes_type(data_type):
         return 'bytes'
     elif is_boolean_type(data_type):
         return 'bool'
     elif is_float_type(data_type):
         return 'float'
     elif is_integer_type(data_type):
         return 'long'
     elif is_void_type(data_type):
         return 'None'
     elif is_timestamp_type(data_type):
         return 'datetime.datetime'
     elif is_alias(data_type):
         return self._python_type_mapping(ns, data_type.data_type)
     elif is_user_defined_type(data_type):
         class_name = class_name_for_data_type(data_type)
         if data_type.namespace.name != ns.name:
             return '%s.%s_validator' % (
                 data_type.namespace.name, class_name)
         else:
             return class_name
     elif is_list_type(data_type):
         # PyCharm understands this description format for a list
         return 'list of [{}]'.format(self._python_type_mapping(
             ns, data_type.data_type))
     elif is_nullable_type(data_type):
         return 'Optional[{}]'.format(
             self._python_type_mapping(ns, data_type.data_type))
     else:
         raise TypeError('Unknown data type %r' % data_type)
Exemplo n.º 6
0
 def _generate_union_class_variant_creators(self, ns, data_type):
     """
     Each non-symbol, non-any variant has a corresponding class method that
     can be used to construct a union with that variant selected.
     """
     for field in data_type.fields:
         if not is_void_type(field.data_type):
             field_name = fmt_func(field.name)
             field_name_reserved_check = fmt_func(field.name, True)
             if is_nullable_type(field.data_type):
                 field_dt = field.data_type.data_type
             else:
                 field_dt = field.data_type
             self.emit('@classmethod')
             self.emit('def {}(cls, val):'.format(field_name_reserved_check))
             with self.indent():
                 self.emit('"""')
                 self.emit_wrapped_text(
                     'Create an instance of this class set to the ``%s`` '
                     'tag with value ``val``.' % field_name)
                 self.emit()
                 self.emit(':param {} val:'.format(
                     self._python_type_mapping(ns, field_dt)))
                 self.emit(':rtype: {}'.format(
                     fmt_class(data_type.name)))
                 self.emit('"""')
                 self.emit("return cls('{}', val)".format(field_name))
             self.emit()
Exemplo n.º 7
0
def map_stone_type_to_python_type(ns, data_type, override_dict=None):
    # type: (ApiNamespace, DataType, typing.Optional[OverrideDefaultTypesDict]) -> str
    """
    Args:
        override_dict: lets you override the default behavior for a given type by hooking into
            a callback. (Currently only hooked up for stone's List and Nullable)
    """
    override_dict = override_dict or {}

    if is_string_type(data_type):
        return 'str'
    elif is_bytes_type(data_type):
        return 'bytes'
    elif is_boolean_type(data_type):
        return 'bool'
    elif is_float_type(data_type):
        return 'float'
    elif is_integer_type(data_type):
        return 'long'
    elif is_void_type(data_type):
        return 'None'
    elif is_timestamp_type(data_type):
        timestamp_override = override_dict.get(Timestamp, None)
        if timestamp_override:
            return timestamp_override(ns, data_type, override_dict)
        return 'datetime.datetime'
    elif is_alias(data_type):
        alias_type = cast(Alias, data_type)
        return map_stone_type_to_python_type(ns, alias_type.data_type,
                                             override_dict)
    elif is_user_defined_type(data_type):
        user_defined_type = cast(UserDefined, data_type)
        class_name = class_name_for_data_type(user_defined_type)
        if user_defined_type.namespace.name != ns.name:
            return '%s.%s_validator' % (user_defined_type.namespace.name,
                                        class_name)
        else:
            return class_name
    elif is_list_type(data_type):
        list_type = cast(List, data_type)
        if List in override_dict:
            return override_dict[List](ns, list_type.data_type, override_dict)

        # PyCharm understands this description format for a list
        return 'list of [{}]'.format(
            map_stone_type_to_python_type(ns, list_type.data_type,
                                          override_dict))
    elif is_nullable_type(data_type):
        nullable_type = cast(Nullable, data_type)
        if Nullable in override_dict:
            return override_dict[Nullable](ns, nullable_type.data_type,
                                           override_dict)

        return 'Optional[{}]'.format(
            map_stone_type_to_python_type(ns, nullable_type.data_type,
                                          override_dict))
    else:
        raise TypeError('Unknown data type %r' % data_type)
 def _generate_field(self, field, union_field=False, namespace=None, raw=False):
     generate_doc(self, field)
     field_name = fmt_var(field.name)
     type_name = fmt_type(field.data_type, namespace, use_interface=True)
     json_tag = '`json:"%s"`' % field.name
     if is_nullable_type(field.data_type) or union_field:
         json_tag = '`json:"%s,omitempty"`' % field.name
     if raw:
         self.emit('%s json.RawMessage %s' % (field_name, json_tag))
     else:
         self.emit('%s %s %s' % (field_name, type_name, json_tag))
 def _generate_field(self,
                     field,
                     union_field=False,
                     namespace=None,
                     raw=False):
     generate_doc(self, field)
     field_name = fmt_var(field.name)
     type_name = fmt_type(field.data_type, namespace, use_interface=True)
     json_tag = '`json:"%s"`' % field.name
     if is_nullable_type(field.data_type) or union_field:
         json_tag = '`json:"%s,omitempty"`' % field.name
     if raw:
         self.emit('%s json.RawMessage %s' % (field_name, json_tag))
     else:
         self.emit('%s %s %s' % (field_name, type_name, json_tag))
Exemplo n.º 10
0
    def _swift_type_mapping(self, data_type, serializer=False):
        suffix = 'Serializer' if serializer else ''
        if is_nullable_type(data_type):
            data_type = data_type.data_type
            nullable = True
        else:
            nullable = False
        if is_list_type(data_type):
            ret = 'Array{}<{}>'.format(
                suffix,
                self._swift_type_mapping(data_type.data_type, serializer)
            )
            suffix = ''
        elif is_string_type(data_type):
            ret = 'String'
        elif is_timestamp_type(data_type):
            ret = 'NSDate'
        elif is_boolean_type(data_type):
            ret = 'Bool'
        elif is_bytes_type(data_type):
            ret = 'NSData'
        elif is_void_type(data_type):
            ret = 'Void'
        elif isinstance(data_type, Int32):
            ret = 'Int32'
        elif isinstance(data_type, Int64):
            ret = 'Int64'
        elif isinstance(data_type, UInt32):
            ret = 'UInt32'
        elif isinstance(data_type, UInt64):
            ret = 'UInt64'
        elif isinstance(data_type, Float32):
            ret = 'Float'
        elif isinstance(data_type, Float64):
            ret = 'Double'
        elif is_user_defined_type(data_type):
            ret = '{}.{}'.format(fmt_class(data_type.namespace.name),
                                 self.class_data_type(data_type))
        ret += suffix
        if nullable:
            if serializer:
                ret = 'NullableSerializer<{}>'.format(ret)
            else:
                ret += '?'

        return ret
Exemplo n.º 11
0
Arquivo: api.py Projeto: scobbe/stone
    def get_route_io_data_types(self):
        """
        Returns a list of all user-defined data types that are referenced as
        either an argument, result, or error of a route. If a List or Nullable
        data type is referenced, then the contained data type is returned
        assuming it's a user-defined type.
        """
        data_types = set()
        for route in self.routes:
            for dtype in (route.arg_data_type, route.result_data_type,
                          route.error_data_type):
                while is_list_type(dtype) or is_nullable_type(dtype):
                    dtype = dtype.data_type
                if is_composite_type(dtype) or is_alias(dtype):
                    data_types.add(dtype)

        return sorted(data_types, key=lambda dt: dt.name)
Exemplo n.º 12
0
    def get_route_io_data_types(self):
        # type: () -> List[UserDefined]
        """
        Returns a list of all user-defined data types that are referenced as
        either an argument, result, or error of a route. If a List or Nullable
        data type is referenced, then the contained data type is returned
        assuming it's a user-defined type.
        """
        data_types = set()  # type: Set[UserDefined]
        for route in self.routes:
            for dtype in (route.arg_data_type, route.result_data_type,
                          route.error_data_type):
                while is_list_type(dtype) or is_nullable_type(dtype):
                    dtype_as_list = cast(Union[DataTypeList, Nullable], dtype)
                    dtype = dtype_as_list.data_type
                if is_composite_type(dtype) or is_alias(dtype):
                    data_types.add(dtype)

        return sorted(data_types, key=lambda dt: dt.name)
Exemplo n.º 13
0
 def _generate_route_method_decl(self,
                                 namespace,
                                 route,
                                 arg_data_type,
                                 request_binary_body,
                                 method_name_suffix=None,
                                 extra_args=None):
     """Generates the method prototype for a route."""
     method_name = fmt_func(route.name)
     namespace_name = fmt_func(namespace.name)
     if method_name_suffix:
         method_name += method_name_suffix
     args = ['self']
     if extra_args:
         args += extra_args
     if request_binary_body:
         args.append('f')
     if is_struct_type(arg_data_type):
         for field in arg_data_type.all_fields:
             if is_nullable_type(field.data_type):
                 args.append('{}=None'.format(field.name))
             elif field.has_default:
                 # TODO(kelkabany): Decide whether we really want to set the
                 # default in the argument list. This will send the default
                 # over the wire even if it isn't overridden. The benefit is
                 # it locks in a default even if it is changed server-side.
                 if is_user_defined_type(field.data_type):
                     ns = field.data_type.namespace
                 else:
                     ns = None
                 arg = '{}={}'.format(
                     field.name,
                     self._generate_python_value(ns, field.default))
                 args.append(arg)
             else:
                 args.append(field.name)
     elif is_union_type(arg_data_type):
         args.append('arg')
     elif not is_void_type(arg_data_type):
         raise AssertionError('Unhandled request type: %r' % arg_data_type)
     self.generate_multiline_list(
         args, 'def {}_{}'.format(namespace_name, method_name), ':')
Exemplo n.º 14
0
    def _determine_validator_type(self, data_type):
        if is_nullable_type(data_type):
            data_type = data_type.data_type
            nullable = True
        else:
            nullable = False
        if is_list_type(data_type):
            item_validator = self._determine_validator_type(data_type.data_type)
            if item_validator:
                v = "arrayValidator({})".format(
                    self._func_args([
                        ("minItems", data_type.min_items),
                        ("maxItems", data_type.max_items),
                        ("itemValidator", item_validator),
                    ])
                )
            else:
                return None
        elif is_numeric_type(data_type):
            v = "comparableValidator({})".format(
                self._func_args([
                    ("minValue", data_type.min_value),
                    ("maxValue", data_type.max_value),
                ])
            )
        elif is_string_type(data_type):
            pat = data_type.pattern if data_type.pattern else None
            if isinstance(pat, six.text_type):
                pat = pat.encode('unicode_escape')
            v = "stringValidator({})".format(
                self._func_args([
                    ("minLength", data_type.min_length),
                    ("maxLength", data_type.max_length),
                    ("pattern", '"{}"'.format(pat) if pat else None),
                ])
            )
        else:
            return None

        if nullable:
            v = "nullableValidator({})".format(v)
        return v
Exemplo n.º 15
0
def format_type(typ):
    """Format a Stone data type as a TypeScript type"""

    # TODO - Where the type is an alias, emit the alias name and then emit
    # `type $alias = $wrapped;`
    """Return a TypeScript representation of a stone DataType"""
    if data_type.is_nullable_type(typ):
        wrapped_type, _ = data_type.unwrap_nullable(typ)

        # If the type is nullable, assume that it has been marked as an
        # optional member of the containing struct, ie. "field?: type", so we
        # don't need to represent the fact that it might be null in the
        # formatted type. ie. There is no need to generate "field?: type |
        # null"
        return '{}'.format(format_type(wrapped_type))

    if data_type.is_primitive_type(typ):
        return _primitive_type_map.get(typ.name)
    elif data_type.is_list_type(typ):
        return '{}[]'.format(format_type(typ.data_type))
    else:
        return typ.name
Exemplo n.º 16
0
    def _serializer_obj(self, data_type):
        if is_nullable_type(data_type):
            data_type = data_type.data_type
            nullable = True
        else:
            nullable = False
        if is_list_type(data_type):
            ret = 'ArraySerializer({})'.format(
                self._serializer_obj(data_type.data_type))
        elif is_string_type(data_type):
            ret = 'Serialization._StringSerializer'
        elif is_timestamp_type(data_type):
            ret = 'NSDateSerializer("{}")'.format(data_type.format)
        elif is_boolean_type(data_type):
            ret = 'Serialization._BoolSerializer'
        elif is_bytes_type(data_type):
            ret = 'Serialization._NSDataSerializer'
        elif is_void_type(data_type):
            ret = 'Serialization._VoidSerializer'
        elif isinstance(data_type, Int32):
            ret = 'Serialization._Int32Serializer'
        elif isinstance(data_type, Int64):
            ret = 'Serialization._Int64Serializer'
        elif isinstance(data_type, UInt32):
            ret = 'Serialization._UInt32Serializer'
        elif isinstance(data_type, UInt64):
            ret = 'Serialization._UInt64Serializer'
        elif isinstance(data_type, Float32):
            ret = 'Serialization._FloatSerializer'
        elif isinstance(data_type, Float64):
            ret = 'Serialization._DoubleSerializer'
        elif is_user_defined_type(data_type):
            ret = "{}.{}Serializer()".format(fmt_class(data_type.namespace.name),
                                             self.class_data_type(data_type))

        if nullable:
            ret = 'NullableSerializer({})'.format(ret)

        return ret
Exemplo n.º 17
0
 def _generate_route_method_decl(
         self, namespace, route, arg_data_type, request_binary_body,
         method_name_suffix=None, extra_args=None):
     """Generates the method prototype for a route."""
     method_name = fmt_func(route.name)
     namespace_name = fmt_func(namespace.name)
     if method_name_suffix:
         method_name += method_name_suffix
     args = ['self']
     if extra_args:
         args += extra_args
     if request_binary_body:
         args.append('f')
     if is_struct_type(arg_data_type):
         for field in arg_data_type.all_fields:
             if is_nullable_type(field.data_type):
                 args.append('{}=None'.format(field.name))
             elif field.has_default:
                 # TODO(kelkabany): Decide whether we really want to set the
                 # default in the argument list. This will send the default
                 # over the wire even if it isn't overridden. The benefit is
                 # it locks in a default even if it is changed server-side.
                 if is_user_defined_type(field.data_type):
                     ns = field.data_type.namespace
                 else:
                     ns = None
                 arg = '{}={}'.format(
                     field.name,
                     self._generate_python_value(ns, field.default))
                 args.append(arg)
             else:
                 args.append(field.name)
     elif is_union_type(arg_data_type):
         args.append('arg')
     elif not is_void_type(arg_data_type):
         raise AssertionError('Unhandled request type: %r' %
                              arg_data_type)
     self.generate_multiline_list(
         args, 'def {}_{}'.format(namespace_name, method_name), ':')
Exemplo n.º 18
0
    def _struct_init_args(self, data_type, namespace=None):
        args = []
        for field in data_type.all_fields:
            name = fmt_var(field.name)
            value = self._swift_type_mapping(field.data_type)
            field_type = field.data_type
            if is_nullable_type(field_type):
                field_type = field_type.data_type
                nullable = True
            else:
                nullable = False

            if field.has_default:
                if is_union_type(field_type):
                    default = '.{}'.format(fmt_class(field.default.tag_name))
                else:
                    default = fmt_obj(field.default)
                value += ' = {}'.format(default)
            elif nullable:
                value += ' = nil'
            arg = (name, value)
            args.append(arg)
        return args
Exemplo n.º 19
0
    def _generate_union_class_get_helpers(self, ns, data_type):
        """
        These are the getters used to access the value of a variant, once
        the tag has been switched on.
        """
        for field in data_type.fields:
            field_name = fmt_func(field.name)

            if not is_void_type(field.data_type):
                # generate getter for field
                self.emit('def get_{}(self):'.format(field_name))
                with self.indent():
                    if is_nullable_type(field.data_type):
                        field_dt = field.data_type.data_type
                    else:
                        field_dt = field.data_type
                    self.emit('"""')
                    if field.doc:
                        self.emit_wrapped_text(
                            self.process_doc(field.doc, self._docf))
                        self.emit()
                    self.emit("Only call this if :meth:`is_%s` is true." %
                              field_name)
                    # Sphinx wants an extra line between the text and the
                    # rtype declaration.
                    self.emit()
                    self.emit(':rtype: {}'.format(
                        self._python_type_mapping(ns, field_dt)))
                    self.emit('"""')

                    self.emit('if not self.is_{}():'.format(field_name))
                    with self.indent():
                        self.emit(
                            'raise AttributeError("tag \'{}\' not set")'.format(
                                field_name))
                    self.emit('return self._value')
                self.emit()
Exemplo n.º 20
0
    def _generate_union_class_get_helpers(self, ns, data_type):
        """
        These are the getters used to access the value of a variant, once
        the tag has been switched on.
        """
        for field in data_type.fields:
            field_name = fmt_func(field.name)

            if not is_void_type(field.data_type):
                # generate getter for field
                self.emit('def get_{}(self):'.format(field_name))
                with self.indent():
                    if is_nullable_type(field.data_type):
                        field_dt = field.data_type.data_type
                    else:
                        field_dt = field.data_type
                    self.emit('"""')
                    if field.doc:
                        self.emit_wrapped_text(
                            self.process_doc(field.doc, self._docf))
                        self.emit()
                    self.emit("Only call this if :meth:`is_%s` is true." %
                              field_name)
                    # Sphinx wants an extra line between the text and the
                    # rtype declaration.
                    self.emit()
                    self.emit(':rtype: {}'.format(
                        self._python_type_mapping(ns, field_dt)))
                    self.emit('"""')

                    self.emit('if not self.is_{}():'.format(field_name))
                    with self.indent():
                        self.emit(
                            'raise AttributeError("tag \'{}\' not set")'.format(
                                field_name))
                    self.emit('return self._value')
                self.emit()
Exemplo n.º 21
0
    def _generate_struct_class_properties(self, ns, data_type):
        """
        Each field of the struct has a corresponding setter and getter.
        The setter validates the value being set.
        """
        for field in data_type.fields:
            field_name = fmt_func(field.name)
            field_name_reserved_check = fmt_func(field.name, True)
            if is_nullable_type(field.data_type):
                field_dt = field.data_type.data_type
                dt_nullable = True
            else:
                field_dt = field.data_type
                dt_nullable = False

            # generate getter for field
            self.emit('@property')
            self.emit('def {}(self):'.format(field_name_reserved_check))
            with self.indent():
                self.emit('"""')
                if field.doc:
                    self.emit_wrapped_text(
                        self.process_doc(field.doc, self._docf))
                    # Sphinx wants an extra line between the text and the
                    # rtype declaration.
                    self.emit()
                self.emit(':rtype: {}'.format(
                    self._python_type_mapping(ns, field_dt)))
                self.emit('"""')
                self.emit('if self._{}_present:'.format(field_name))
                with self.indent():
                    self.emit('return self._{}_value'.format(field_name))

                self.emit('else:')
                with self.indent():
                    if dt_nullable:
                        self.emit('return None')
                    elif field.has_default:
                        self.emit('return {}'.format(
                            self._generate_python_value(ns, field.default)))
                    else:
                        self.emit(
                            "raise AttributeError(\"missing required field '%s'\")"
                            % field_name
                        )
            self.emit()

            # generate setter for field
            self.emit('@{}.setter'.format(field_name_reserved_check))
            self.emit('def {}(self, val):'.format(field_name_reserved_check))
            with self.indent():
                if dt_nullable:
                    self.emit('if val is None:')
                    with self.indent():
                        self.emit('del self.{}'.format(field_name_reserved_check))
                        self.emit('return')
                if is_user_defined_type(field_dt):
                    self.emit('self._%s_validator.validate_type_only(val)' %
                              field_name)
                else:
                    self.emit('val = self._{}_validator.validate(val)'.format(field_name))
                self.emit('self._{}_value = val'.format(field_name))
                self.emit('self._{}_present = True'.format(field_name))
            self.emit()

            # generate deleter for field
            self.emit('@{}.deleter'.format(field_name_reserved_check))
            self.emit('def {}(self):'.format(field_name_reserved_check))
            with self.indent():
                self.emit('self._{}_value = None'.format(field_name))
                self.emit('self._{}_present = False'.format(field_name))
            self.emit()
Exemplo n.º 22
0
    def _generate_struct_class_properties(self, ns, data_type):
        """
        Each field of the struct has a corresponding setter and getter.
        The setter validates the value being set.
        """
        for field in data_type.fields:
            field_name = fmt_func(field.name)
            field_name_reserved_check = fmt_func(field.name, True)
            if is_nullable_type(field.data_type):
                field_dt = field.data_type.data_type
                dt_nullable = True
            else:
                field_dt = field.data_type
                dt_nullable = False

            # generate getter for field
            self.emit('@property')
            self.emit('def {}(self):'.format(field_name_reserved_check))
            with self.indent():
                self.emit('"""')
                if field.doc:
                    self.emit_wrapped_text(
                        self.process_doc(field.doc, self._docf))
                    # Sphinx wants an extra line between the text and the
                    # rtype declaration.
                    self.emit()
                self.emit(':rtype: {}'.format(
                    self._python_type_mapping(ns, field_dt)))
                self.emit('"""')
                self.emit('if self._{}_present:'.format(field_name))
                with self.indent():
                    self.emit('return self._{}_value'.format(field_name))

                self.emit('else:')
                with self.indent():
                    if dt_nullable:
                        self.emit('return None')
                    elif field.has_default:
                        self.emit('return {}'.format(
                            self._generate_python_value(ns, field.default)))
                    else:
                        self.emit(
                            "raise AttributeError(\"missing required field '%s'\")"
                            % field_name
                        )
            self.emit()

            # generate setter for field
            self.emit('@{}.setter'.format(field_name_reserved_check))
            self.emit('def {}(self, val):'.format(field_name_reserved_check))
            with self.indent():
                if dt_nullable:
                    self.emit('if val is None:')
                    with self.indent():
                        self.emit('del self.{}'.format(field_name_reserved_check))
                        self.emit('return')
                if is_user_defined_type(field_dt):
                    self.emit('self._%s_validator.validate_type_only(val)' %
                              field_name)
                else:
                    self.emit('val = self._{}_validator.validate(val)'.format(field_name))
                self.emit('self._{}_value = val'.format(field_name))
                self.emit('self._{}_present = True'.format(field_name))
            self.emit()

            # generate deleter for field
            self.emit('@{}.deleter'.format(field_name_reserved_check))
            self.emit('def {}(self):'.format(field_name_reserved_check))
            with self.indent():
                self.emit('self._{}_value = None'.format(field_name))
                self.emit('self._{}_present = False'.format(field_name))
            self.emit()
Exemplo n.º 23
0
 def _struct_has_defaults(self, struct):
     """Returns whether the given struct has any default values."""
     return [
         f for f in struct.all_fields
         if f.has_default or is_nullable_type(f.data_type)
     ]
Exemplo n.º 24
0
 def _struct_has_defaults(self, struct):
     """Returns whether the given struct has any default values."""
     return [f for f in struct.all_fields if f.has_default or is_nullable_type(f.data_type)]