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'"
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)
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)
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)
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
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)
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)
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)
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")
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)
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)
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)
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)
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
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
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))
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)
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)
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)
def set_takes(self, takes: ATakes) -> ATakes: takes = deserialize_object(takes, MapMeta) return self.set_endpoint_data("takes", takes)
def set_display(self, display: ADisplay) -> ADisplay: display = deserialize_object(display, Display) return self.set_endpoint_data("display", display)
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)
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)
def _update_remote_blocks(self, response): response = deserialize_object(response, Update) cothread.Callback(self.remote_blocks.set_value, response.value)
def set_meta(self, meta: AMethodMeta) -> AMethodMeta: meta = deserialize_object(meta, MethodMeta) return self.set_endpoint_data("meta", meta)
def set_returns(self, returns: AReturns) -> AReturns: returns = deserialize_object(returns, MapMeta) return self.set_endpoint_data("returns", returns)
def test_deserialize(self): a = EmptySerializable() d = a.to_dict() b = deserialize_object(d, EmptySerializable) assert a.to_dict() == b.to_dict()
def set_bar(self, bar): d = OrderedDict() for k, v in bar.items(): if k != "typeid": d[k] = deserialize_object(v) self.bar = d
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])
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"