コード例 #1
0
    def _generate_struct_class_repr(self, data_type):
        """
        Generates something like:

            def __repr__(self):
                return 'Employee(first_name={!r}, last_name={!r}, age={!r})'.format(
                    self._first_name_value,
                    self._last_name_value,
                    self._age_value,
                )
        """
        self.emit('def __repr__(self):')
        with self.indent():
            if data_type.all_fields:
                constructor_kwargs_fmt = ', '.join(
                    '{}={{!r}}'.format(fmt_var(f.name, True))
                    for f in data_type.all_fields)
                self.emit("return '{}({})'.format(".format(
                    class_name_for_data_type(data_type),
                    constructor_kwargs_fmt,
                ))
                with self.indent():
                    for f in data_type.all_fields:
                        self.emit("self._{}_value,".format(fmt_var(f.name)))
                self.emit(")")
            else:
                self.emit("return '%s()'" %
                          class_name_for_data_type(data_type))
        self.emit()
コード例 #2
0
    def _generate_struct_class_repr(self, data_type):
        """
        Generates something like:

            def __repr__(self):
                return 'Employee(first_name={!r}, last_name={!r}, age={!r})'.format(
                    self._first_name_value,
                    self._last_name_value,
                    self._age_value,
                )
        """
        self.emit('def __repr__(self):')
        with self.indent():
            if data_type.all_fields:
                constructor_kwargs_fmt = ', '.join(
                    '{}={{!r}}'.format(fmt_var(f.name, True))
                    for f in data_type.all_fields)
                self.emit("return '{}({})'.format(".format(
                    class_name_for_data_type(data_type),
                    constructor_kwargs_fmt,
                ))
                with self.indent():
                    for f in data_type.all_fields:
                        self.emit("self._{}_value,".format(fmt_var(f.name)))
                self.emit(")")
            else:
                self.emit("return '%s()'" %
                          class_name_for_data_type(data_type))
        self.emit()
コード例 #3
0
 def _class_declaration_for_type(self, ns, data_type):
     assert is_user_defined_type(data_type), \
         'Expected struct, got %r' % type(data_type)
     if data_type.parent_type:
         extends = class_name_for_data_type(data_type.parent_type, ns)
     else:
         if is_union_type(data_type):
             # Use a handwritten base class
             extends = 'bb.Union'
         else:
             extends = 'object'
     return 'class {}({}):'.format(
         class_name_for_data_type(data_type), extends)
コード例 #4
0
 def _class_declaration_for_type(self, ns, data_type):
     assert is_user_defined_type(data_type), \
         'Expected struct, got %r' % type(data_type)
     if data_type.parent_type:
         extends = class_name_for_data_type(data_type.parent_type, ns)
     else:
         if is_union_type(data_type):
             # Use a handwritten base class
             extends = 'bb.Union'
         else:
             extends = 'object'
     return 'class {}({}):'.format(class_name_for_data_type(data_type),
                                   extends)
コード例 #5
0
ファイル: python_type_stubs.py プロジェクト: stomakun/stone
    def _generate_union_class_variant_creators(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        """
        Generate the following section in the 'union Shape' example:
        @classmethod
        def circle(cls, val: float) -> Shape: ...
        """
        union_type = class_name_for_data_type(data_type)

        for field in data_type.fields:
            if not is_void_type(field.data_type):
                field_name_reserved_check = fmt_func(field.name,
                                                     check_reserved=True)
                val_type = self.map_stone_type_to_pep484_type(
                    ns, field.data_type)

                self.emit('@classmethod')
                self.emit(
                    'def {field_name}(cls, val: {val_type}) -> {union_type}: ...'
                    .format(
                        field_name=field_name_reserved_check,
                        val_type=val_type,
                        union_type=union_type,
                    ))
                self.emit()
コード例 #6
0
    def _generate_struct_class_custom_annotations(self, ns, data_type):
        """
        The _process_custom_annotations function allows client code to access
        custom annotations defined in the spec.
        """
        self.emit(
            'def _process_custom_annotations(self, annotation_type, field_path, processor):'
        )

        with self.indent(), emit_pass_if_nothing_emitted(self):
            self.emit((
                'super({}, self)._process_custom_annotations(annotation_type, field_path, '
                'processor)').format(class_name_for_data_type(data_type)))
            self.emit()

            for field in data_type.fields:
                field_name = fmt_var(field.name, check_reserved=True)
                for annotation_type, processor in self._generate_custom_annotation_processors(
                        ns, field.data_type, field.custom_annotations):
                    annotation_class = class_name_for_annotation_type(
                        annotation_type, ns)
                    self.emit(
                        'if annotation_type is {}:'.format(annotation_class))
                    with self.indent():
                        self.emit('self.{} = {}'.format(
                            field_name,
                            generate_func_call(
                                processor,
                                args=[
                                    "'{{}}.{}'.format(field_path)".format(
                                        field_name),
                                    'self.{}'.format(field_name),
                                ])))
                    self.emit()
コード例 #7
0
    def _generate_union_class_reflection_attributes(self, ns, data_type):
        """
        Adds a class attribute for each union member assigned to a validator.
        Also adds an attribute that is a map from tag names to validators.
        """
        class_name = fmt_class(data_type.name)

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            self.emit('{}._{}_validator = {}'.format(
                class_name, field_name, validator_name))

        with self.block('{}._tagmap ='.format(class_name)):
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(
                    class_name, var_name)
                self.emit("'{}': {},".format(var_name, validator_name))

        if data_type.parent_type:
            self.emit('{0}._tagmap.update({1}._tagmap)'.format(
                class_name,
                class_name_for_data_type(data_type.parent_type, ns)))

        self.emit()
コード例 #8
0
ファイル: python_types.py プロジェクト: ThiagoJunior/stone
    def _generate_union_class_reflection_attributes(self, ns, data_type):
        """
        Adds a class attribute for each union member assigned to a validator.
        Also adds an attribute that is a map from tag names to validators.
        """
        class_name = fmt_class(data_type.name)

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            self.emit('{}._{}_validator = {}'.format(class_name, field_name,
                                                     validator_name))

        with self.block('{}._tagmap ='.format(class_name)):
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(
                    class_name, var_name)
                self.emit("'{}': {},".format(var_name, validator_name))

        if data_type.parent_type:
            self.emit('{0}._tagmap.update({1}._tagmap)'.format(
                class_name, class_name_for_data_type(data_type.parent_type,
                                                     ns)))

        self.emit()
コード例 #9
0
 def _generate_struct_attributes_defaults(self, ns, data_type):
     # Default values can cross-reference, so we also set them after classes.
     class_name = class_name_for_data_type(data_type)
     for field in data_type.fields:
         if field.has_default:
             self.emit("{}.{}.default = {}".format(
                 class_name, fmt_var(field.name),
                 self._generate_python_value(ns, field.default)))
コード例 #10
0
 def _generate_alias_definition(self, namespace, alias):
     # type: (ApiNamespace, Alias) -> None
     unwrapped_dt, _ = unwrap_aliases(alias)
     if is_user_defined_type(unwrapped_dt):
         # If the alias is to a composite type, we want to alias the
         # generated class as well.
         self.emit('{} = {}'.format(
             alias.name,
             class_name_for_data_type(alias.data_type, namespace)))
コード例 #11
0
 def _generate_alias_definition(self, namespace, alias):
     # type: (ApiNamespace, Alias) -> None
     unwrapped_dt, _ = unwrap_aliases(alias)
     if is_user_defined_type(unwrapped_dt):
         # If the alias is to a composite type, we want to alias the
         # generated class as well.
         self.emit('{} = {}'.format(
             alias.name,
             class_name_for_data_type(alias.data_type, namespace)))
コード例 #12
0
 def _generate_union_class_repr(self, data_type):
     """
     The __repr__() function will return a string of the class name, and
     the selected tag.
     """
     self.emit('def __repr__(self):')
     with self.indent():
         self.emit("return '{}(%r, %r)' % (self._tag, self._value)".format(
             class_name_for_data_type(data_type), ))
     self.emit()
コード例 #13
0
 def _generate_python_value(self, ns, value):
     if is_tag_ref(value):
         ref = '{}.{}'.format(
             class_name_for_data_type(value.union_data_type),
             fmt_var(value.tag_name))
         if ns != value.union_data_type.namespace:
             ref = '%s.%s' % (value.union_data_type.namespace.name, ref)
         return ref
     else:
         return fmt_obj(value)
コード例 #14
0
 def _generate_python_value(self, ns, value):
     if is_tag_ref(value):
         ref = '{}.{}'.format(
             class_name_for_data_type(value.union_data_type),
             fmt_var(value.tag_name))
         if ns != value.union_data_type.namespace:
             ref = '%s.%s' % (value.union_data_type.namespace.name, ref)
         return ref
     else:
         return fmt_obj(value)
コード例 #15
0
 def _generate_union_class_repr(self, data_type):
     """
     The __repr__() function will return a string of the class name, and
     the selected tag.
     """
     self.emit('def __repr__(self):')
     with self.indent():
         self.emit("return '{}(%r, %r)' % (self._tag, self._value)".format(
             class_name_for_data_type(data_type),
         ))
     self.emit()
コード例 #16
0
    def _generate_union_class(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        """Defines a Python class that represents a union in Stone."""
        self.emit(self._class_declaration_for_type(ns, data_type))
        with self.indent():
            self.emit('"""')
            if data_type.doc:
                self.emit_wrapped_text(
                    self.process_doc(data_type.doc, self._docf))
                self.emit()

            self.emit_wrapped_text(
                'This class acts as a tagged union. Only one of the ``is_*`` '
                'methods will return true. To get the associated value of a '
                'tag (if one exists), use the corresponding ``get_*`` method.')

            if data_type.has_documented_fields():
                self.emit()

            for field in data_type.fields:
                if not field.doc:
                    continue
                if is_void_type(field.data_type):
                    ivar_doc = ':ivar {}: {}'.format(
                        fmt_namespaced_var(ns.name, data_type.name,
                                           field.name),
                        self.process_doc(field.doc, self._docf))
                elif is_user_defined_type(field.data_type):
                    if data_type.namespace.name != ns.name:
                        formatted_var = fmt_namespaced_var(
                            ns.name, data_type.name, field.name)
                    else:
                        formatted_var = '{}.{}'.format(data_type.name,
                                                       fmt_var(field.name))
                    ivar_doc = ':ivar {} {}: {}'.format(
                        fmt_class(field.data_type.name), formatted_var,
                        self.process_doc(field.doc, self._docf))
                else:
                    ivar_doc = ':ivar {} {}: {}'.format(
                        self._python_type_mapping(ns, field.data_type),
                        fmt_namespaced_var(ns.name, data_type.name,
                                           field.name), field.doc)
                self.emit_wrapped_text(ivar_doc, subsequent_prefix='    ')
            self.emit('"""')
            self.emit()

            self._generate_union_class_vars(data_type)
            self._generate_union_class_variant_creators(ns, data_type)
            self._generate_union_class_is_set(data_type)
            self._generate_union_class_get_helpers(ns, data_type)
            self._generate_union_class_custom_annotations(ns, data_type)
        self.emit('{0}_validator = bv.Union({0})'.format(
            class_name_for_data_type(data_type)))
        self.emit()
コード例 #17
0
ファイル: python_types.py プロジェクト: ThiagoJunior/stone
 def _generate_alias_definition(self, namespace, alias):
     v = generate_validator_constructor(namespace, alias.data_type)
     if alias.doc:
         self.emit_wrapped_text(self.process_doc(alias.doc, self._docf),
                                prefix='# ')
     self.emit('{}_validator = {}'.format(alias.name, v))
     unwrapped_dt, _ = unwrap_aliases(alias)
     if is_user_defined_type(unwrapped_dt):
         # If the alias is to a composite type, we want to alias the
         # generated class as well.
         self.emit('{} = {}'.format(
             alias.name, class_name_for_data_type(alias.data_type,
                                                  namespace)))
コード例 #18
0
 def _generate_alias_definition(self, namespace, alias):
     v = generate_validator_constructor(namespace, alias.data_type)
     if alias.doc:
         self.emit_wrapped_text(
             self.process_doc(alias.doc, self._docf), prefix='# ')
     self.emit('{}_validator = {}'.format(alias.name, v))
     unwrapped_dt, _ = unwrap_aliases(alias)
     if is_user_defined_type(unwrapped_dt):
         # If the alias is to a composite type, we want to alias the
         # generated class as well.
         self.emit('{} = {}'.format(
             alias.name,
             class_name_for_data_type(alias.data_type, namespace)))
コード例 #19
0
    def _generate_union_class_reflection_attributes(self, ns, data_type):
        """
        Adds a class attribute for each union member assigned to a validator.
        Also adds an attribute that is a map from tag names to validators.
        """
        class_name = fmt_class(data_type.name)

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            full_validator_name = '{}._{}_validator'.format(
                class_name, field_name)
            self.emit('{} = {}'.format(full_validator_name, validator_name))

            if field.redactor:
                self._generate_redactor(full_validator_name, field.redactor)

        # generate _all_fields_ for each omitted caller (and public)
        child_omitted_callers = data_type.get_all_omitted_callers()
        parent_omitted_callers = data_type.parent_type.get_all_omitted_callers() if \
            data_type.parent_type else set([])

        all_omitted_callers = child_omitted_callers | parent_omitted_callers
        if len(all_omitted_callers) != 0:
            self.emit('{}._permissioned_tagmaps = {}'.format(
                class_name, all_omitted_callers))
        for omitted_caller in all_omitted_callers | {None}:
            is_public = omitted_caller is None
            tagmap_name = '_tagmap' if is_public else '_{}_tagmap'.format(
                omitted_caller)
            caller_in_parent = data_type.parent_type and (
                is_public or omitted_caller in parent_omitted_callers)

            with self.block('{}.{} ='.format(class_name, tagmap_name)):
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue
                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(
                        class_name, var_name)
                    self.emit("'{}': {},".format(var_name, validator_name))

            if caller_in_parent:
                self.emit('{0}.{1}.update({2}.{1})'.format(
                    class_name, tagmap_name,
                    class_name_for_data_type(data_type.parent_type, ns)))

        self.emit()
コード例 #20
0
    def _generate_union_class(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        """Defines a Python class that represents a union in Stone."""
        self.emit(self._class_declaration_for_type(ns, data_type))
        with self.indent():
            self.emit('"""')
            if data_type.doc:
                self.emit_wrapped_text(
                    self.process_doc(data_type.doc, self._docf))
                self.emit()

            self.emit_wrapped_text(
                'This class acts as a tagged union. Only one of the ``is_*`` '
                'methods will return true. To get the associated value of a '
                'tag (if one exists), use the corresponding ``get_*`` method.')

            if data_type.has_documented_fields():
                self.emit()

            for field in data_type.fields:
                if not field.doc:
                    continue
                if is_void_type(field.data_type):
                    ivar_doc = ':ivar {}: {}'.format(
                        fmt_var(field.name),
                        self.process_doc(field.doc, self._docf))
                elif is_user_defined_type(field.data_type):
                    ivar_doc = ':ivar {} {}: {}'.format(
                        fmt_class(field.data_type.name),
                        fmt_var(field.name),
                        self.process_doc(field.doc, self._docf))
                else:
                    ivar_doc = ':ivar {} {}: {}'.format(
                        self._python_type_mapping(ns, field.data_type),
                        fmt_var(field.name), field.doc)
                self.emit_wrapped_text(ivar_doc, subsequent_prefix='    ')
            self.emit('"""')
            self.emit()

            self._generate_union_class_vars(data_type)
            self._generate_union_class_variant_creators(ns, data_type)
            self._generate_union_class_is_set(data_type)
            self._generate_union_class_get_helpers(ns, data_type)
            self._generate_union_class_repr(data_type)
        self.emit('{0}_validator = bv.Union({0})'.format(
            class_name_for_data_type(data_type)
        ))
        self.emit()
コード例 #21
0
ファイル: python_type_stubs.py プロジェクト: stomakun/stone
    def _generate_union_class_vars(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        lineno = self.lineno

        # Generate stubs for class variables so that IDEs like PyCharms have an
        # easier time detecting their existence.
        for field in data_type.fields:
            if is_void_type(field.data_type):
                field_name = fmt_var(field.name)
                field_type = class_name_for_data_type(data_type, ns)
                self.emit('{field_name} = ...  # type: {field_type}'.format(
                    field_name=field_name,
                    field_type=field_type,
                ))

        if lineno != self.lineno:
            self.emit()
コード例 #22
0
ファイル: python_type_stubs.py プロジェクト: dropbox/stone
    def _generate_union_class_vars(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        lineno = self.lineno

        # Generate stubs for class variables so that IDEs like PyCharms have an
        # easier time detecting their existence.
        for field in data_type.fields:
            if is_void_type(field.data_type):
                field_name = fmt_var(field.name)
                field_type = class_name_for_data_type(data_type, ns)
                self.emit('{field_name} = ...  # type: {field_type}'.format(
                    field_name=field_name,
                    field_type=field_type,
                ))

        if lineno != self.lineno:
            self.emit()
コード例 #23
0
    def _generate_union_class_reflection_attributes(self, ns, data_type):
        """
        Adds a class attribute for each union member assigned to a validator.
        Also adds an attribute that is a map from tag names to validators.
        """
        class_name = fmt_class(data_type.name)

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            full_validator_name = '{}._{}_validator'.format(class_name, field_name)
            self.emit('{} = {}'.format(full_validator_name, validator_name))

            if field.redactor:
                self._generate_redactor(full_validator_name, field.redactor)

        # generate _all_fields_ for each omitted caller (and public)
        child_omitted_callers = data_type.get_all_omitted_callers()
        parent_omitted_callers = data_type.parent_type.get_all_omitted_callers() if \
            data_type.parent_type else set([])

        all_omitted_callers = child_omitted_callers | parent_omitted_callers
        if len(all_omitted_callers) != 0:
            self.emit('{}._permissioned_tagmaps = {}'.format(class_name, all_omitted_callers))
        for omitted_caller in all_omitted_callers | {None}:
            is_public = omitted_caller is None
            tagmap_name = '_tagmap' if is_public else '_{}_tagmap'.format(omitted_caller)
            caller_in_parent = data_type.parent_type and (is_public or omitted_caller
                                                         in parent_omitted_callers)

            with self.block('{}.{} ='.format(class_name, tagmap_name)):
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue
                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(class_name, var_name)
                    self.emit("'{}': {},".format(var_name, validator_name))

            if caller_in_parent:
                self.emit('{0}.{1}.update({2}.{1})'.format(
                    class_name, tagmap_name,
                    class_name_for_data_type(data_type.parent_type, ns))
                )

        self.emit()
コード例 #24
0
    def _generate_struct_class_init(self, data_type):
        """
        Generates constructor. The constructor takes all possible fields as
        optional arguments. Any argument that is set on construction sets the
        corresponding field for the instance.
        """

        args = ['self']
        for field in data_type.all_fields:
            field_name_reserved_check = fmt_var(field.name, True)
            args.append('%s=None' % field_name_reserved_check)
        self.generate_multiline_list(args, before='def __init__', after=':')

        with self.indent():
            lineno = self.lineno

            # Call the parent constructor if a super type exists
            if data_type.parent_type:
                class_name = class_name_for_data_type(data_type)
                all_parent_fields = [
                    fmt_func(f.name, True)
                    for f in data_type.parent_type.all_fields
                ]
                self.generate_multiline_list(
                    all_parent_fields,
                    before='super({}, self).__init__'.format(class_name))

            # initialize each field
            for field in data_type.fields:
                field_var_name = fmt_var(field.name)
                self.emit('self._{}_value = None'.format(field_var_name))
                self.emit('self._{}_present = False'.format(field_var_name))

            # handle arguments that were set
            for field in data_type.fields:
                field_var_name = fmt_var(field.name, True)
                self.emit('if {} is not None:'.format(field_var_name))
                with self.indent():
                    self.emit('self.{0} = {0}'.format(field_var_name))

            if lineno == self.lineno:
                self.emit('pass')
            self.emit()
コード例 #25
0
    def _generate_union_class_custom_annotations(self, ns, data_type):
        """
        The _process_custom_annotations function allows client code to access
        custom annotations defined in the spec.
        """
        self.emit(
            'def _process_custom_annotations(self, annotation_type, field_path, processor):'
        )
        with self.indent(), emit_pass_if_nothing_emitted(self):
            self.emit((
                'super({}, self)._process_custom_annotations(annotation_type, field_path, '
                'processor)').format(class_name_for_data_type(data_type)))
            self.emit()

            for field in data_type.fields:
                recursive_processors = list(
                    self._generate_custom_annotation_processors(
                        ns, field.data_type, field.custom_annotations))

                # check if we have any annotations that apply to this field at all
                if len(recursive_processors) == 0:
                    continue

                field_name = fmt_func(field.name)
                self.emit('if self.is_{}():'.format(field_name))

                with self.indent():
                    for annotation_type, processor in recursive_processors:
                        annotation_class = class_name_for_annotation_type(
                            annotation_type, ns)
                        self.emit('if annotation_type is {}:'.format(
                            annotation_class))
                        with self.indent():
                            self.emit('self._value = {}'.format(
                                generate_func_call(
                                    processor,
                                    args=[
                                        "'{{}}.{}'.format(field_path)".format(
                                            field_name),
                                        'self._value',
                                    ])))
                        self.emit()
コード例 #26
0
    def _generate_struct_class_init(self, data_type):
        """
        Generates constructor. The constructor takes all possible fields as
        optional arguments. Any argument that is set on construction sets the
        corresponding field for the instance.
        """

        args = ['self']
        for field in data_type.all_fields:
            field_name_reserved_check = fmt_var(field.name, True)
            args.append('%s=None' % field_name_reserved_check)
        self.generate_multiline_list(args, before='def __init__', after=':')

        with self.indent():
            lineno = self.lineno

            # Call the parent constructor if a super type exists
            if data_type.parent_type:
                class_name = class_name_for_data_type(data_type)
                all_parent_fields = [fmt_func(f.name, True)
                              for f in data_type.parent_type.all_fields]
                self.generate_multiline_list(
                    all_parent_fields,
                    before='super({}, self).__init__'.format(class_name))

            # initialize each field
            for field in data_type.fields:
                field_var_name = fmt_var(field.name)
                self.emit('self._{}_value = None'.format(field_var_name))
                self.emit('self._{}_present = False'.format(field_var_name))

            # handle arguments that were set
            for field in data_type.fields:
                field_var_name = fmt_var(field.name, True)
                self.emit('if {} is not None:'.format(field_var_name))
                with self.indent():
                    self.emit('self.{0} = {0}'.format(field_var_name))

            if lineno == self.lineno:
                self.emit('pass')
            self.emit()
コード例 #27
0
ファイル: python_type_stubs.py プロジェクト: dropbox/stone
    def _generate_union_class_variant_creators(self, ns, data_type):
        # type: (ApiNamespace, Union) -> None
        """
        Generate the following section in the 'union Shape' example:
        @classmethod
        def circle(cls, val: float) -> Shape: ...
        """
        union_type = class_name_for_data_type(data_type)

        for field in data_type.fields:
            if not is_void_type(field.data_type):
                field_name_reserved_check = fmt_func(field.name, check_reserved=True)
                val_type = self.map_stone_type_to_pep484_type(ns, field.data_type)

                self.emit('@classmethod')
                self.emit('def {field_name}(cls, val: {val_type}) -> {union_type}: ...'.format(
                    field_name=field_name_reserved_check,
                    val_type=val_type,
                    union_type=union_type,
                ))
                self.emit()
コード例 #28
0
    def _generate_struct_class(self, ns, data_type):
        # type: (ApiNamespace, Struct) -> None
        """Defines a Python class that represents a struct in Stone."""
        self.emit(self._class_declaration_for_type(ns, data_type))
        with self.indent():
            if data_type.has_documented_type_or_fields():
                self.emit('"""')
                if data_type.doc:
                    self.emit_wrapped_text(
                        self.process_doc(data_type.doc, self._docf))
                    if data_type.has_documented_fields():
                        self.emit()
                for field in data_type.fields:
                    if not field.doc:
                        continue
                    self.emit_wrapped_text(':ivar {}: {}'.format(
                        fmt_namespaced_var(ns.name, data_type.name,
                                           field.name),
                        self.process_doc(field.doc, self._docf)),
                                           subsequent_prefix='    ')
                self.emit('"""')
            self.emit()

            self._generate_struct_class_slots(data_type)
            self._generate_struct_class_has_required_fields(data_type)
            self._generate_struct_class_init(data_type)
            self._generate_struct_class_properties(ns, data_type)
            self._generate_struct_class_custom_annotations(ns, data_type)
        if data_type.has_enumerated_subtypes():
            validator = 'StructTree'
        else:
            validator = 'Struct'
        self.emit('{0}_validator = bv.{1}({0})'.format(
            class_name_for_data_type(data_type),
            validator,
        ))
        self.emit()
コード例 #29
0
    def _generate_struct_class(self, ns, data_type):
        # type: (ApiNamespace, Struct) -> None
        """Defines a Python class that represents a struct in Stone."""
        self.emit(self._class_declaration_for_type(ns, data_type))
        with self.indent():
            if data_type.has_documented_type_or_fields():
                self.emit('"""')
                if data_type.doc:
                    self.emit_wrapped_text(
                        self.process_doc(data_type.doc, self._docf))
                    if data_type.has_documented_fields():
                        self.emit()
                for field in data_type.fields:
                    if not field.doc:
                        continue
                    self.emit_wrapped_text(':ivar {}: {}'.format(
                        fmt_var(field.name),
                        self.process_doc(field.doc, self._docf)),
                        subsequent_prefix='    ')
                self.emit('"""')
            self.emit()

            self._generate_struct_class_slots(data_type)
            self._generate_struct_class_has_required_fields(data_type)
            self._generate_struct_class_init(data_type)
            self._generate_struct_class_properties(ns, data_type)
            self._generate_struct_class_repr(data_type)
        if data_type.has_enumerated_subtypes():
            validator = 'StructTree'
        else:
            validator = 'Struct'
        self.emit('{0}_validator = bv.{1}({0})'.format(
            class_name_for_data_type(data_type),
            validator,
        ))
        self.emit()
コード例 #30
0
ファイル: python_types.py プロジェクト: ThiagoJunior/stone
    def _generate_struct_class_reflection_attributes(self, ns, data_type):
        """
        Generates two class attributes:
          * _all_field_names_: Set of all field names including inherited fields.
          * _all_fields_: List of tuples, where each tuple is (name, validator).

        If a struct has enumerated subtypes, then two additional attributes are
        generated:
          * _field_names_: Set of all field names excluding inherited fields.
          * _fields: List of tuples, where each tuple is (name, validator), and
            excludes inherited fields.

        These are needed because serializing a struct with enumerated subtypes
        requires knowing the fields defined in each level of the hierarchy.
        """

        class_name = class_name_for_data_type(data_type)
        if data_type.parent_type:
            parent_type_class_name = class_name_for_data_type(
                data_type.parent_type, ns)
        else:
            parent_type_class_name = None

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            self.emit('{}._{}_validator = {}'.format(class_name, field_name,
                                                     validator_name))

        if data_type.is_member_of_enumerated_subtypes_tree():
            self.generate_multiline_list(
                ["'%s'" % field.name for field in data_type.fields],
                before='{}._field_names_ = set('.format(class_name),
                after=')',
                delim=('[', ']'),
                compact=False)
            if parent_type_class_name:
                self.emit(
                    '{0}._all_field_names_ = '
                    '{1}._all_field_names_.union({0}._field_names_)'.format(
                        class_name, parent_type_class_name))
            else:
                self.emit('{0}._all_field_names_ = {0}._field_names_'.format(
                    class_name))
        else:
            if parent_type_class_name:
                before = ('{}._all_field_names_ = '
                          '{}._all_field_names_.union(set(').format(
                              class_name, parent_type_class_name)
                after = '))'
            else:
                before = '{}._all_field_names_ = set('.format(class_name)
                after = ')'
            self.generate_multiline_list(
                ["'%s'" % field.name for field in data_type.fields],
                before=before,
                after=after,
                delim=('[', ']'),
                compact=False)

        if data_type.is_member_of_enumerated_subtypes_tree():
            items = []
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(
                    class_name, var_name)
                items.append("('{}', {})".format(var_name, validator_name))
            self.generate_multiline_list(
                items,
                before='{}._fields_ = '.format(class_name),
                delim=('[', ']'),
                compact=False,
            )
            if parent_type_class_name:
                self.emit('{0}._all_fields_ = '
                          '{1}._all_fields_ + {0}._fields_'.format(
                              class_name, parent_type_class_name))
            else:
                self.emit('{0}._all_fields_ = {0}._fields_'.format(class_name))
        else:
            if parent_type_class_name:
                before = '{}._all_fields_ = {}._all_fields_ + '.format(
                    class_name, parent_type_class_name)
            else:
                before = '{}._all_fields_ = '.format(class_name)
            items = []
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(
                    class_name, var_name)
                items.append("('{}', {})".format(var_name, validator_name))
            self.generate_multiline_list(items,
                                         before=before,
                                         delim=('[', ']'),
                                         compact=False)

        self.emit()
コード例 #31
0
ファイル: python_type_stubs.py プロジェクト: dropbox/stone
 def _generate_validator_for(self, data_type):
     # type: (DataType) -> None
     cls_name = class_name_for_data_type(data_type)
     self.emit("{}_validator: bv.Validator = ...".format(
         cls_name
     ))
コード例 #32
0
ファイル: python_type_stubs.py プロジェクト: stomakun/stone
 def _generate_validator_for(self, data_type):
     # type: (DataType) -> None
     cls_name = class_name_for_data_type(data_type)
     self.emit("{}_validator: bv.Validator = ...".format(cls_name))
コード例 #33
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_map_type(data_type):
        map_type = cast(Map, data_type)
        if Map in override_dict:
            return override_dict[Map](
                ns,
                data_type,
                override_dict
            )

        return 'dict of [{}:{}]'.format(
            map_stone_type_to_python_type(ns, map_type.key_data_type, override_dict),
            map_stone_type_to_python_type(ns, map_type.value_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)
コード例 #34
0
def map_stone_type_to_python_type(ns, data_type, override_dict=None):
    # type: (ApiNamespace, DataType, typing.Optional[OverrideDefaultTypesDict]) -> typing.Text
    """
    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):
        string_override = override_dict.get(String, None)
        if string_override:
            return string_override(ns, data_type, override_dict)
        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_map_type(data_type):
        map_type = cast(Map, data_type)
        if Map in override_dict:
            return override_dict[Map](ns, data_type, override_dict)

        return 'dict of [{}:{}]'.format(
            map_stone_type_to_python_type(ns, map_type.key_data_type,
                                          override_dict),
            map_stone_type_to_python_type(ns, map_type.value_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)
コード例 #35
0
    def _generate_struct_class_reflection_attributes(self, ns, data_type):
        """
        Generates two class attributes:
          * _all_field_names_: Set of all field names including inherited fields.
          * _all_fields_: List of tuples, where each tuple is (name, validator).

        If a struct has enumerated subtypes, then two additional attributes are
        generated:
          * _field_names_: Set of all field names excluding inherited fields.
          * _fields: List of tuples, where each tuple is (name, validator), and
            excludes inherited fields.

        These are needed because serializing a struct with enumerated subtypes
        requires knowing the fields defined in each level of the hierarchy.
        """

        class_name = class_name_for_data_type(data_type)
        if data_type.parent_type:
            parent_type_class_name = class_name_for_data_type(
                data_type.parent_type, ns)
        else:
            parent_type_class_name = None

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(
                ns, field.data_type)
            full_validator_name = '{}._{}_validator'.format(
                class_name, field_name)
            self.emit('{} = {}'.format(full_validator_name, validator_name))
            if field.redactor:
                self._generate_redactor(full_validator_name, field.redactor)

        # Generate `_all_field_names_` and `_all_fields_` for every omitted caller (and public).
        # As an edge case, we union omitted callers with None in the case when the object has no
        # public fields, as we still need to generate public attributes (`_field_names_` etc)
        child_omitted_callers = data_type.get_all_omitted_callers() | {None}
        parent_omitted_callers = data_type.parent_type.get_all_omitted_callers() if \
            data_type.parent_type else set([])

        for omitted_caller in child_omitted_callers | parent_omitted_callers:
            is_public = omitted_caller is None
            map_name_prefix = '' if is_public else '_{}'.format(omitted_caller)
            caller_in_parent = data_type.parent_type and (
                is_public or omitted_caller in parent_omitted_callers)

            # generate `_all_field_names_`
            names_map_name = '{}_field_names_'.format(map_name_prefix)
            all_names_map_name = '_all{}_field_names_'.format(map_name_prefix)
            if data_type.is_member_of_enumerated_subtypes_tree():
                if is_public or omitted_caller in child_omitted_callers:
                    self.generate_multiline_list([
                        "'%s'" % field.name for field in data_type.fields
                        if field.omitted_caller == omitted_caller
                    ],
                                                 before='{}.{} = set('.format(
                                                     class_name,
                                                     names_map_name),
                                                 after=')',
                                                 delim=('[', ']'),
                                                 compact=False)
                if caller_in_parent:
                    self.emit('{0}.{3} = {1}.{3}.union({0}.{2})'.format(
                        class_name, parent_type_class_name, names_map_name,
                        all_names_map_name))
                else:
                    self.emit('{0}.{2} = {0}.{1}'.format(
                        class_name, names_map_name, all_names_map_name))
            else:
                if caller_in_parent:
                    before = '{0}.{1} = {2}.{1}.union(set('.format(
                        class_name, all_names_map_name, parent_type_class_name)
                    after = '))'
                else:
                    before = '{}.{} = set('.format(class_name,
                                                   all_names_map_name)
                    after = ')'
                items = [
                    "'%s'" % field.name for field in data_type.fields
                    if field.omitted_caller == omitted_caller
                ]
                self.generate_multiline_list(items,
                                             before=before,
                                             after=after,
                                             delim=('[', ']'),
                                             compact=False)

            # generate `_all_fields_`
            fields_map_name = '{}_fields_'.format(map_name_prefix)
            all_fields_map_name = '_all{}_fields_'.format(map_name_prefix)
            if data_type.is_member_of_enumerated_subtypes_tree():
                items = []
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue

                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(
                        class_name, var_name)
                    items.append("('{}', {})".format(var_name, validator_name))
                self.generate_multiline_list(
                    items,
                    before='{}.{} = '.format(class_name, fields_map_name),
                    delim=('[', ']'),
                    compact=False,
                )
                if caller_in_parent:
                    self.emit('{0}.{3} = {1}.{3} + {0}.{2}'.format(
                        class_name, parent_type_class_name, fields_map_name,
                        all_fields_map_name))
                else:
                    self.emit('{0}.{2} = {0}.{1}'.format(
                        class_name, fields_map_name, all_fields_map_name))
            else:
                if caller_in_parent:
                    before = '{0}.{2} = {1}.{2} + '.format(
                        class_name, parent_type_class_name,
                        all_fields_map_name)
                else:
                    before = '{}.{} = '.format(class_name, all_fields_map_name)

                items = []
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue

                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(
                        class_name, var_name)
                    items.append("('{}', {})".format(var_name, validator_name))
                self.generate_multiline_list(items,
                                             before=before,
                                             delim=('[', ']'),
                                             compact=False)

        self.emit()
コード例 #36
0
    def _generate_struct_class_reflection_attributes(self, ns, data_type):
        """
        Generates two class attributes:
          * _all_field_names_: Set of all field names including inherited fields.
          * _all_fields_: List of tuples, where each tuple is (name, validator).

        If a struct has enumerated subtypes, then two additional attributes are
        generated:
          * _field_names_: Set of all field names excluding inherited fields.
          * _fields: List of tuples, where each tuple is (name, validator), and
            excludes inherited fields.

        These are needed because serializing a struct with enumerated subtypes
        requires knowing the fields defined in each level of the hierarchy.
        """

        class_name = class_name_for_data_type(data_type)
        if data_type.parent_type:
            parent_type_class_name = class_name_for_data_type(
                data_type.parent_type, ns)
        else:
            parent_type_class_name = None

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(ns, field.data_type)
            self.emit('{}._{}_validator = {}'.format(
                class_name, field_name, validator_name))

        if data_type.is_member_of_enumerated_subtypes_tree():
            self.generate_multiline_list(
                ["'%s'" % field.name for field in data_type.fields],
                before='{}._field_names_ = set('.format(class_name),
                after=')',
                delim=('[', ']'),
                compact=False)
            if parent_type_class_name:
                self.emit(
                    '{0}._all_field_names_ = '
                    '{1}._all_field_names_.union({0}._field_names_)'
                    .format(class_name, parent_type_class_name))
            else:
                self.emit('{0}._all_field_names_ = {0}._field_names_'.format(
                    class_name))
        else:
            if parent_type_class_name:
                before = (
                    '{}._all_field_names_ = '
                    '{}._all_field_names_.union(set(').format(
                    class_name, parent_type_class_name)
                after = '))'
            else:
                before = '{}._all_field_names_ = set('.format(class_name)
                after = ')'
            self.generate_multiline_list(
                ["'%s'" % field.name for field in data_type.fields],
                before=before,
                after=after,
                delim=('[', ']'),
                compact=False)

        if data_type.is_member_of_enumerated_subtypes_tree():
            items = []
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(class_name,
                                                           var_name)
                items.append("('{}', {})".format(var_name, validator_name))
            self.generate_multiline_list(
                items,
                before='{}._fields_ = '.format(class_name),
                delim=('[', ']'),
                compact=False,
            )
            if parent_type_class_name:
                self.emit(
                    '{0}._all_fields_ = '
                    '{1}._all_fields_ + {0}._fields_'.format(
                        class_name, parent_type_class_name))
            else:
                self.emit('{0}._all_fields_ = {0}._fields_'.format(class_name))
        else:
            if parent_type_class_name:
                before = '{}._all_fields_ = {}._all_fields_ + '.format(
                    class_name, parent_type_class_name)
            else:
                before = '{}._all_fields_ = '.format(class_name)
            items = []
            for field in data_type.fields:
                var_name = fmt_var(field.name)
                validator_name = '{}._{}_validator'.format(
                    class_name, var_name)
                items.append("('{}', {})".format(var_name, validator_name))
            self.generate_multiline_list(
                items, before=before, delim=('[', ']'), compact=False)

        self.emit()
コード例 #37
0
    def _generate_struct_class_reflection_attributes(self, ns, data_type):
        """
        Generates two class attributes:
          * _all_field_names_: Set of all field names including inherited fields.
          * _all_fields_: List of tuples, where each tuple is (name, validator).

        If a struct has enumerated subtypes, then two additional attributes are
        generated:
          * _field_names_: Set of all field names excluding inherited fields.
          * _fields: List of tuples, where each tuple is (name, validator), and
            excludes inherited fields.

        These are needed because serializing a struct with enumerated subtypes
        requires knowing the fields defined in each level of the hierarchy.
        """

        class_name = class_name_for_data_type(data_type)
        if data_type.parent_type:
            parent_type_class_name = class_name_for_data_type(
                data_type.parent_type, ns)
        else:
            parent_type_class_name = None

        for field in data_type.fields:
            field_name = fmt_var(field.name)
            validator_name = generate_validator_constructor(ns, field.data_type)
            full_validator_name = '{}._{}_validator'.format(class_name, field_name)
            self.emit('{} = {}'.format(full_validator_name, validator_name))
            if field.redactor:
                self._generate_redactor(full_validator_name, field.redactor)

        # Generate `_all_field_names_` and `_all_fields_` for every omitted caller (and public).
        # As an edge case, we union omitted callers with None in the case when the object has no
        # public fields, as we still need to generate public attributes (`_field_names_` etc)
        child_omitted_callers = data_type.get_all_omitted_callers() | {None}
        parent_omitted_callers = data_type.parent_type.get_all_omitted_callers() if \
            data_type.parent_type else set([])

        for omitted_caller in child_omitted_callers | parent_omitted_callers:
            is_public = omitted_caller is None
            map_name_prefix = '' if is_public else '_{}'.format(omitted_caller)
            caller_in_parent = data_type.parent_type and (is_public or omitted_caller
                                                         in parent_omitted_callers)

            # generate `_all_field_names_`
            names_map_name = '{}_field_names_'.format(map_name_prefix)
            all_names_map_name = '_all{}_field_names_'.format(map_name_prefix)
            if data_type.is_member_of_enumerated_subtypes_tree():
                if is_public or omitted_caller in child_omitted_callers:
                    self.generate_multiline_list(
                        [
                            "'%s'" % field.name
                            for field in data_type.fields
                            if field.omitted_caller == omitted_caller
                        ],
                        before='{}.{} = set('.format(class_name, names_map_name),
                        after=')',
                        delim=('[', ']'),
                        compact=False)
                if caller_in_parent:
                    self.emit('{0}.{3} = {1}.{3}.union({0}.{2})'
                              .format(class_name, parent_type_class_name, names_map_name,
                                      all_names_map_name))
                else:
                    self.emit('{0}.{2} = {0}.{1}'.format(class_name, names_map_name,
                                                         all_names_map_name))
            else:
                if caller_in_parent:
                    before = '{0}.{1} = {2}.{1}.union(set('.format(class_name, all_names_map_name,
                                                                   parent_type_class_name)
                    after = '))'
                else:
                    before = '{}.{} = set('.format(class_name, all_names_map_name)
                    after = ')'
                items = [
                    "'%s'" % field.name
                    for field in data_type.fields
                    if field.omitted_caller == omitted_caller
                ]
                self.generate_multiline_list(
                    items,
                    before=before,
                    after=after,
                    delim=('[', ']'),
                    compact=False)

            # generate `_all_fields_`
            fields_map_name = '{}_fields_'.format(map_name_prefix)
            all_fields_map_name = '_all{}_fields_'.format(map_name_prefix)
            if data_type.is_member_of_enumerated_subtypes_tree():
                items = []
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue

                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(class_name,
                                                               var_name)
                    items.append("('{}', {})".format(var_name, validator_name))
                self.generate_multiline_list(
                    items,
                    before='{}.{} = '.format(class_name, fields_map_name),
                    delim=('[', ']'),
                    compact=False,
                )
                if caller_in_parent:
                    self.emit('{0}.{3} = {1}.{3} + {0}.{2}'.format(
                        class_name, parent_type_class_name, fields_map_name, all_fields_map_name))
                else:
                    self.emit('{0}.{2} = {0}.{1}'.format(
                        class_name, fields_map_name, all_fields_map_name))
            else:
                if caller_in_parent:
                    before = '{0}.{2} = {1}.{2} + '.format(
                        class_name, parent_type_class_name, all_fields_map_name)
                else:
                    before = '{}.{} = '.format(class_name, all_fields_map_name)

                items = []
                for field in data_type.fields:
                    if field.omitted_caller != omitted_caller:
                        continue

                    var_name = fmt_var(field.name)
                    validator_name = '{}._{}_validator'.format(
                        class_name, var_name)
                    items.append("('{}', {})".format(var_name, validator_name))
                self.generate_multiline_list(
                    items, before=before, delim=('[', ']'), compact=False)

        self.emit()