예제 #1
0
 def test_no_args(self):
     self.expected["extra"] = "thing"
     with self.assertRaises(TypeError) as cm:
         deserialize_object(self.expected)
     assert str(
         cm.exception
     ) == "foo:1.0 raised error: __init__() got an unexpected keyword argument 'extra'"
예제 #2
0
def update_configure_model(
        configure_model: MethodMeta,
        part_configure_infos: List[ConfigureParamsInfo]) -> None:
    # These will not be inserted as they already exist

    ignored = list(ConfigureHook.call_types)

    # Re-calculate the following
    required = []
    metas = OrderedDict()
    defaults = OrderedDict()

    # First do the required arguments
    for k in configure_model.takes.required:
        required.append(k)
        metas[k] = configure_model.takes.elements[k]
    for info in part_configure_infos:
        for k in info.required:
            if k not in required + ignored:
                required.append(k)
                # TODO: moan about type changes, when != works...
                metas[k] = info.metas[k]

    # Now the default and optional
    for k in configure_model.takes.elements:
        if k not in required:
            metas[k] = configure_model.takes.elements[k]
    for info in part_configure_infos:
        for k, meta in info.metas.items():
            if k not in required + ignored:
                # TODO: moan about type changes, when != works...
                metas[k] = meta
                if k in info.defaults:
                    if isinstance(meta, TableMeta) and not min(
                            m.writeable for m in meta.elements.values()):
                        # This is a table with non-writeable rows, merge the
                        # defaults together row by row
                        rows = []
                        if k in defaults:
                            rows += defaults[k].rows()
                        rows += info.defaults[k].rows()
                        assert meta.table_cls, "No Meta table class"
                        defaults[k] = meta.table_cls.from_rows(rows)
                    else:
                        defaults[k] = info.defaults[k]

    # Copy and prepare values for takes and returns
    takes_metas = OrderedDict()
    returns_metas = OrderedDict()
    for k, v in metas.items():
        takes_metas[k] = deserialize_object(v.to_dict(), VMeta)
        returns_metas[k] = deserialize_object(v.to_dict(), VMeta)
        returns_metas[k].set_writeable(False)

    # Set them on the model
    configure_model.takes.set_elements(takes_metas)
    configure_model.takes.set_required(required)
    configure_model.returns.set_elements(returns_metas)
    configure_model.returns.set_required(required)
    configure_model.set_defaults(defaults)
예제 #3
0
    def __init__(self, generators, alternate=False):
        # type: (UGenerators, AAlternate) -> None
        self.generators = AGenerators([deserialize_object(g, Generator)
                                      for g in generators])

        assert len(self.generators), "At least one generator needed"

        units = []
        axes = []
        size = self.generators[0].size

        for generator in self.generators:
            assert generator.axes not in axes, "You cannot zip generators " \
                                               "on the same axes"
            assert generator.size == size, "You cannot zip generators " \
                                           "of different sizes"
            assert not generator.alternate, \
                "Alternate should not be set on the component generators of a" \
                "zip generator. Set it on the top level ZipGenerator only."

            axes += generator.axes
            units += generator.units

        super(ZipGenerator, self).__init__(axes=axes,
                                           size=size,
                                           units=units,
                                           alternate=alternate)
예제 #4
0
 def set_took(self, took: ATook = None) -> ATook:
     if took is None:
         took = MethodLog(self.meta.takes.validate(add_missing=True), [],
                          Alarm.ok, TimeStamp.zero)
     else:
         took = deserialize_object(took, MethodLog)
     return self.set_endpoint_data("took", took)
예제 #5
0
 def set_elements(self, elements: ATableElements) -> ATableElements:
     """Set the elements dict from a serialized dict"""
     deserialized = OrderedDict()
     for k, v in elements.items():
         if k != "typeid":
             deserialized[k] = deserialize_object(v, VArrayMeta)
     ret = self.set_endpoint_data("elements", deserialized)
     self.set_table_cls(self.table_cls)
     return ret
예제 #6
0
 def set_meta(self, meta: Union[VMeta, None]) -> VMeta:
     meta = deserialize_object(meta)
     # Check that the meta attribute_class is ourself
     assert isinstance(meta, VMeta), f"Expected meta object, got {type(meta)}"
     assert isinstance(self, meta.attribute_class), (
         f"Meta object needs to be attached to {meta.attribute_class}, "
         f"we are a {type(self)}"
     )
     return self.set_endpoint_data("meta", meta)
예제 #7
0
 def set_elements(self, elements: AElements) -> AElements:
     deserialized = OrderedDict()
     for k, v in elements.items():
         if k != "typeid":
             v = deserialize_object(v, VMeta)
             if not v.label:
                 v.set_label(camel_to_title(k))
             deserialized[k] = v
     return self.set_endpoint_data("elements", deserialized)
예제 #8
0
 def _regenerate_block(self, block, d):
     for field in list(block):
         if field not in ("health", "meta"):
             block.remove_endpoint(field)
     for field, value in d.items():
         if field == "health":
             # Update health attribute
             value: NTScalar = deserialize_object(value)
             block.health.set_value(value=value.value,
                                    alarm=value.alarm,
                                    ts=value.timeStamp)
         elif field == "meta":
             value: BlockMeta = deserialize_object(value)
             meta: BlockMeta = block.meta
             for k in meta.call_types:
                 meta.apply_change([k], value[k])
         elif field != "typeid":
             # No need to set writeable_functions as the server will do it
             block.set_endpoint_data(field, value)
예제 #9
0
    def __init__(
            self,
            generators,  # type: UGenerators
            excluders=(),  # type: UExcluders
            mutators=(),  # type: UMutators
            duration=-1,  # type: ADuration
            continuous=True,  # type: AContinuous
            delay_after=0  # type: ADelay
    ):
        # type: (...) -> None
        self.size = 0
        """int: Final number of points to be generated -
        valid only after calling prepare"""
        self.shape = None
        """tuple(int): Final shape of the scan -
        valid only after calling prepare"""
        self.dimensions = []
        """list(Dimension): Dimension instances -
        valid only after calling prepare"""

        self.generators = AGenerators(
            [deserialize_object(g, Generator) for g in generators])
        self.excluders = AExcluders(
            [deserialize_object(e, Excluder) for e in excluders])
        self.mutators = AMutators(
            [deserialize_object(m, Mutator) for m in mutators])
        self.duration = ADuration(duration)
        self.continuous = AContinuous(continuous)
        self.axes = []
        self.units = {}
        self._dim_meta = {}
        self._prepared = False
        self.delay_after = ADelay(delay_after)
        if self.delay_after < 0.0:
            self.delay_after = 0.0

        for generator in self.generators:
            logging.debug("Generator passed to Compound init")
            logging.debug(generator.to_dict())
            self.axes += generator.axes
            self.units.update(generator.axis_units())
        if len(self.axes) != len(set(self.axes)):
            raise ValueError("Axis names cannot be duplicated")
예제 #10
0
 def set_returned(self, returned: AReturned = None) -> AReturned:
     if returned is None:
         returned = MethodLog(
             self.meta.returns.validate(add_missing=True),
             [],
             Alarm.ok,
             TimeStamp.zero,
         )
     else:
         returned = deserialize_object(returned, MethodLog)
     return self.set_endpoint_data("returned", returned)
예제 #11
0
 def set_meta(self, meta: Union[VMeta, None]) -> VMeta:
     meta = deserialize_object(meta)
     # Check that the meta attribute_class is ourself
     assert isinstance(meta,
                       VMeta), "Expected meta object, got %s" % type(meta)
     assert isinstance(
         self, meta.attribute_class
     ), "Meta object needs to be attached to %s, we are a %s" % (
         meta.attribute_class,
         type(self),
     )
     return self.set_endpoint_data("meta", meta)
예제 #12
0
 def __init__(
     self,
     value: AMVValue = None,
     present: UPresent = (),
     alarm: AAlarm = None,
     timeStamp: ATimeStamp = None,
 ) -> None:
     self.value: Union[Dict, AMVValue]
     if value is None:
         self.value = {}
     else:
         self.value = value
     self.present = APresent(present)
     if alarm is None:
         self.alarm = Alarm.ok
     else:
         self.alarm = deserialize_object(alarm, Alarm)
     if timeStamp is None:
         self.timeStamp = TimeStamp()
     else:
         self.timeStamp = deserialize_object(timeStamp, TimeStamp)
예제 #13
0
 def __init__(
     self,
     severity: AAlarmSeverity = AlarmSeverity.NO_ALARM,
     status: AAlarmStatus = AlarmStatus.NO_STATUS,
     message: AMessage = "",
 ) -> None:
     if not isinstance(severity, AlarmSeverity):
         severity = AlarmSeverity(severity)
     self.severity = severity
     if not isinstance(status, AlarmStatus):
         status = AlarmStatus(status)
     self.status = status
     self.message = deserialize_object(message, str)
예제 #14
0
 def set_value(
     self,
     value: Any,
     set_alarm_ts: bool = True,
     alarm: Alarm = None,
     ts: TimeStamp = None,
 ) -> Any:
     """Set value, calculating alarm and ts if requested"""
     value = self.meta.validate(value)
     if set_alarm_ts:
         if alarm is None:
             alarm = Alarm.ok
         else:
             alarm = cast(Alarm, deserialize_object(alarm, Alarm))
         if ts is None:
             ts = cast(TimeStamp, TimeStamp())
         else:
             ts = cast(TimeStamp, deserialize_object(ts, TimeStamp))
         self.set_value_alarm_ts(value, alarm, ts)
     else:
         self.set_endpoint_data("value", value)
     return self.value
예제 #15
0
 def set_endpoint_data(
     self,
     name: str,
     value: Union[AttributeModel, MethodModel, BlockMeta],
 ) -> Any:
     name = deserialize_object(name, str)
     if name == "meta":
         value = deserialize_object(value, BlockMeta)
     else:
         value = deserialize_object(value, (AttributeModel, MethodModel))
     with self.notifier.changes_squashed:
         if name in self.call_types:
             # Stop the old Model notifying
             getattr(self, name).set_notifier_path(Model.notifier, [])
         else:
             anno = Anno("Field").set_typ(type(value))
             self.call_types[name] = anno
         value.set_notifier_path(self.notifier, self.path + [name])
         setattr(self, name, value)
         # Tell the notifier what changed
         self.notifier.add_squashed_change(self.path + [name], value)
         self._update_fields()
         return value
예제 #16
0
    def on_message(self, message):
        # called in tornado's thread
        if self._writeable is None:
            ipv4_ip = self.request.remote_ip
            if ipv4_ip == "::1":
                # Special case IPV6 loopback
                ipv4_ip = "127.0.0.1"
            remoteaddr = struct.unpack("!I", socket.inet_aton(ipv4_ip))[0]
            if self._validators:
                # Work out if the remote ip is within the netmask of any of our
                # interfaces. If not, Put and Post are forbidden
                self._writeable = max(v(remoteaddr) for v in self._validators)
            else:
                self._writeable = True
            log.info(
                "Puts and Posts are %s from %s",
                "allowed" if self._writeable else "forbidden",
                self.request.remote_ip,
            )

        msg_id = -1
        try:
            d = json_decode(message)
            try:
                msg_id = d["id"]
            except KeyError:
                raise FieldError("id field not present in JSON message")
            request = deserialize_object(d, Request)
            request.set_callback(self.on_response)
            if isinstance(request, Subscribe):
                assert msg_id not in self._id_to_mri, (
                    "Duplicate subscription ID %d" % msg_id
                )
                self._id_to_mri[msg_id] = request.path[0]
            if isinstance(request, Unsubscribe):
                mri = self._id_to_mri[msg_id]
            else:
                mri = request.path[0]
            if isinstance(request, (Put, Post)) and not self._writeable:
                raise ValueError(
                    "Put/Post is forbidden from %s" % self.request.remote_ip
                )
            self._registrar.report(builtin.infos.RequestInfo(request, mri))
        except Exception as e:
            log.exception("Error handling message:\n%s", message)
            error = Error(msg_id, e)
            error_message = error.to_dict()
            self.write_message(json_encode(error_message))
예제 #17
0
    def __init__(self, generators, alternate=False):
        # type: (AGenerator, AAlternate) -> None
        self.generators = AGenerator(
            [deserialize_object(g, Generator) for g in generators])

        assert len(self.generators) > 0, "At least one generator needed"

        units = self.generators[0].units
        axes = self.generators[0].axes
        size = sum(generator.size for generator in self.generators)
        for generator in self.generators:
            assert generator.axes == axes, "You cannot Concat generators " \
                                                "on different axes"
            assert generator.units == units, "You cannot Concat " \
                                             "generators with different units"
            assert not generator.alternate, \
                "Alternate should not be set on the component generators of a" \
                "ConcatGenerator. Set it on the top level ConcatGenerator only."
        super(ConcatGenerator, self).__init__(axes=axes,
                                              size=size,
                                              units=units,
                                              alternate=alternate)
예제 #18
0
        def update_field(response):
            if not isinstance(response, Delta):
                # Return or Error is the end of our subscription, log and ignore
                self.log.debug("Export got response %r", response)
                return
            if not ret:
                # First call, create the initial object
                export = deserialize_object(response.changes[0][1])
                if isinstance(export, AttributeModel):

                    def setter(v):
                        context = Context(self.process)
                        context.put(path, v)

                    # Strip out tags that we shouldn't export
                    # TODO: need to strip out port tags too...
                    export.meta.set_tags(
                        without_config_tags(
                            without_group_tags(export.meta.tags)))

                    ret["setter"] = setter
                else:

                    def setter_star_args(*args):
                        context = Context(self.process)
                        context.post(path, *args)

                    ret["setter"] = setter_star_args

                # Regenerate label
                export.meta.set_label(label)
                ret["export"] = export
            else:
                # Subsequent calls, update it
                with self.changes_squashed:
                    for change in response.changes:
                        ret["export"].apply_change(*change)
예제 #19
0
    def on_message(self, message):
        """Pass response from server to process receive queue

        Args:
            message(str): Received message
        """
        # Called in tornado loop
        try:
            self.log.debug("Got message %s", message)
            d = json_decode(message)
            response = deserialize_object(d, Response)
            if isinstance(response, (Return, Error)):
                request = self._request_lookup.pop(response.id)
                if isinstance(response, Error):
                    # Make the message an exception so it can be raised
                    response.message = ResponseError(response.message)
            else:
                request = self._request_lookup[response.id]
            # Transfer the work of the callback to cothread
            cothread.Callback(request.callback, response)
        except Exception:
            # If we don't catch the exception here, tornado will spew odd
            # error messages about 'HTTPRequest' object has no attribute 'path'
            self.log.exception("on_message(%r) failed", message)
예제 #20
0
 def set_takes(self, takes: ATakes) -> ATakes:
     takes = deserialize_object(takes, MapMeta)
     return self.set_endpoint_data("takes", takes)
예제 #21
0
 def set_display(self, display: ADisplay) -> ADisplay:
     display = deserialize_object(display, Display)
     return self.set_endpoint_data("display", display)
예제 #22
0
 def set_timeStamp(self, ts: TimeStamp = None) -> TimeStamp:
     if ts is None:
         ts = TimeStamp()
     else:
         ts = deserialize_object(ts, TimeStamp)
     return self.set_endpoint_data("timeStamp", ts)
예제 #23
0
 def set_alarm(self, alarm: Alarm = None) -> Alarm:
     if alarm is None:
         alarm = Alarm.ok
     else:
         alarm = deserialize_object(alarm, Alarm)
     return self.set_endpoint_data("alarm", alarm)
예제 #24
0
 def _update_remote_blocks(self, response):
     response = deserialize_object(response, Update)
     cothread.Callback(self.remote_blocks.set_value, response.value)
예제 #25
0
 def set_meta(self, meta: AMethodMeta) -> AMethodMeta:
     meta = deserialize_object(meta, MethodMeta)
     return self.set_endpoint_data("meta", meta)
예제 #26
0
 def set_returns(self, returns: AReturns) -> AReturns:
     returns = deserialize_object(returns, MapMeta)
     return self.set_endpoint_data("returns", returns)
예제 #27
0
 def test_deserialize(self):
     a = EmptySerializable()
     d = a.to_dict()
     b = deserialize_object(d, EmptySerializable)
     assert a.to_dict() == b.to_dict()
예제 #28
0
 def set_bar(self, bar):
     d = OrderedDict()
     for k, v in bar.items():
         if k != "typeid":
             d[k] = deserialize_object(v)
     self.bar = d
예제 #29
0
 def __init__(self, rois, axes):
     # type: (URois, UExcluderAxes) -> None
     super(ROIExcluder, self).__init__(axes)
     self.rois = ARois([deserialize_object(r, ROI) for r in rois])
예제 #30
0
 def test_bad_typeid(self):
     with self.assertRaises(TypeError) as cm:
         deserialize_object(dict(typeid="something_bad"))
     assert str(cm.exception) == "'something_bad' not a valid typeid"