Exemplo n.º 1
0
 def __init__(self) -> None:
     # note: this is a regular dict, but ordered on Python 3.6
     # we use this alias to signify it must be ordered.
     self._buffers = OrderedDict()
     # getmany calls next(_TopicBuffer), and does not call iter(),
     # so the first call to next caches an iterator.
     self._it = None
Exemplo n.º 2
0
 def __init__(self, app: AppT, **kwargs: Any) -> None:
     self.app = app
     self.data = OrderedDict()
     self._by_topic = defaultdict(WeakSet)
     self._agents_started = Event()
     Service.__init__(self, **kwargs)
Exemplo n.º 3
0
    def _BUILD_init(cls) -> Callable[[], None]:
        # generate init function that set field values from arguments,
        # and that load data from serialized form.
        #
        #
        # The general template that we will be generating is
        #
        #    def __outer__(Model):   # create __init__ closure
        #       __defaults__ = Model._options.defaults
        #       __descr__ = Model._options.descriptors
        #       {% for field in fields_with_defaults %}
        #       _default_{{ field }}_ = __defaults__["{{ field }}"]
        #       {% endfor %}
        #       {% for field in fields_with_init %}
        #       _init_{{ field }}_ = __descr__["{{ field }}"].to_python
        #
        #       def __init__(self, {{ sig }}, *, __strict__=True, **kwargs):
        #          self.__evaluated_fields__ = set()
        #          if __strict__:  # creating model from Python
        #              {% for field in fields %}
        #              self.{{ field }} = {{ field }}
        #              {% endfor %}
        #              if kwargs:
        #                 # raise error for additional arguments
        #          else:
        #              {% for field in fields %}
        #              {% if OPTIONAL_FIELD(field) %}
        #              if {{ field }} is not None:
        #                  self.{{ field }} = _init_{{ field }}({{ field }})
        #              else:
        #                  self.{{ field }} = _default_{{ field }}
        #              {% else %}
        #                  self.{{ field }} = _init_{{ field }}({{ field }}
        #              # any additional kwargs are added as fields
        #              # when loading from serialized data.
        #              self.__dict__.update(kwargs)
        #         self.__post_init__()
        #     return __init__
        #
        options = cls._options
        field_positions = options.fieldpos
        optional = options.optionalset
        needs_validation = options.validation
        descriptors = options.descriptors
        has_post_init = hasattr(cls, '__post_init__')

        closures: Dict[str, str] = {
            '__defaults__': 'Model._options.defaults',
            '__descr__': 'Model._options.descriptors',
        }

        kwonlyargs = ['*', '__strict__=True', '__faust=None', '**kwargs']
        # these are sets, but we care about order as we will
        # be generating signature arguments in the correct order.
        #
        # The order is decided by the order of fields in the class):
        #
        #  class Foo(Record):
        #      c: int
        #      a: int
        #
        # becomes:
        #
        #   def __init__(self, c, a):
        #       self.c = c
        #       self.a = a
        optional_fields: Dict[str, bool] = OrderedDict()
        required_fields: Dict[str, bool] = OrderedDict()

        def generate_setter(field: str, getval: str) -> str:
            """Generate code that sets attribute for field in class.

            Arguments:
                field: Name of field.
                getval: Source code that initializes value for field,
                    can be the field name itself for no initialization
                    or for example: ``f"self._prepare_value({field})"``.
                out: Destination list where new source code lines are added.
                """
            if field in optional:
                optional_fields[field] = True
                default_var = f'_default_{field}_'
                closures[default_var] = f'__defaults__["{field}"]'
                return (f'    self.{field} = {getval} '
                        f'if {field} is not None else {default_var}')
            else:
                required_fields[field] = True
                return f'    self.{field} = {getval}'

        def generate_prepare_value(field: str) -> str:
            descriptor = descriptors[field]
            if descriptor.lazy_coercion:
                return field  # no initialization
            else:
                # call descriptor.to_python
                init_field_var = f'_init_{field}_'
                closures[init_field_var] = f'__descr__["{field}"].to_python'
                return f'{init_field_var}({field})'

        preamble = [
            'self.__evaluated_fields__ = set()',
        ]

        data_setters = ['if __strict__:'] + [
            generate_setter(field, field)
            for field in field_positions.values()
        ]

        data_rest = [
            '    if kwargs:',
            '        from mode.utils.text import pluralize',
            '        message = "{} got unexpected {}: {}".format(',
            '            self.__class__.__name__,',
            '            pluralize(kwargs.__len__(), "argument"),',
            '            ", ".join(map(str, sorted(kwargs))))',
            '        raise TypeError(message)',
        ]

        init_setters = ['else:']
        if field_positions:
            init_setters.extend(
                generate_setter(field, generate_prepare_value(field))
                for field in field_positions.values()
            )
        init_setters.append('    self.__dict__.update(kwargs)')

        postamble = []
        if has_post_init:
            postamble.append('self.__post_init__()')
        if needs_validation:
            postamble.append('self.validate_or_raise()')

        signature = list(chain(
            ['self'],
            [f'{field}' for field in required_fields],
            [f'{field}=None' for field in optional_fields],
            kwonlyargs,
        ))

        sourcecode = codegen.build_closure_source(
            name='__init__',
            args=signature,
            body=list(chain(
                preamble,
                data_setters,
                data_rest,
                init_setters,
                postamble,
            )),
            closures=closures,
            outer_args=['Model'],
        )

        # TIP final sourcecode also available
        # as .__sourcecode__ on returned method
        # (print(Model.__init__.__sourcecode__)
        return codegen.build_closure(
            '__outer__', sourcecode, cls,
            globals={},
            locals={},
        )
Exemplo n.º 4
0
 def __init__(self, app: AppT, **kwargs: Any) -> None:
     self.app = app
     self.data = OrderedDict()
     self._by_topic = defaultdict(WeakSet)