def test_no_duplicates_list_anon_dict(): nd = NotDuplicated(failure=u'%(container_label)s %(position)s') schema = (List.named('test'). of(Dict.of(Integer.named('x'), Integer.named('y')). using(validators=[nd]))) _test_no_duplicates(schema, {'x': 1, 'y': 2}, {'x': 3, 'y': 4})
def test_sparsedict_set_default(): schema = SparseDict.of(Integer.named(u'x').using(default=123), Integer.named(u'y')) el = schema() el.set_default() assert el.value == {}
def test_dict_el(): # stub schema = Dict.named(u's').of(Integer.named(u'x'), Integer.named(u'y')) element = schema() assert element.el(u'x').name == u'x' assert_raises(KeyError, element.el, u'not_x')
def test_access(): pairs = ((u'l_0_i', u'10'), (u'l_1_i', u'11'), (u'l_2_i', u'12'),) schema = List.named(u'l').of(Integer.named(u'i')) el = schema.from_flat(pairs) elements = list(Integer.named(u'i')(val) for val in (u'10', u'11', u'12')) assert len(el) == 3 assert el[0] == elements[0] assert el[1] == elements[1] assert el[2] == elements[2] assert el[0].value == 10 assert el[:0] == elements[:0] assert el[:1] == elements[:1] assert el[0:5] == elements[0:5] assert el[-2:-1] == elements[-2:-1] assert el[0] in el assert elements[0] in el assert u'10' in el assert 10 in el assert el.count(elements[0]) == 1 assert el.count(u'10') == 1 assert el.count(10) == 1 assert el.index(elements[0]) == 0 assert el.index(u'10') == 0 assert el.index(10) == 0
def test_dsl_of(): assert_raises(TypeError, Sequence.of) t1 = Sequence.of(Integer) assert t1.member_schema is Integer t2 = Sequence.of(Integer.named(u'x'), Integer.named(u'y')) assert issubclass(t2.member_schema, Dict) assert sorted(t2.member_schema().keys()) == [u'x', u'y']
def test_sparsedict_required_set_default(): schema = SparseDict.using(minimum_fields='required').\ of(Integer.named(u'x').using(default=123), Integer.named(u'y').using(default=456, optional=True), Integer.named(u'z').using(optional=True)) el = schema() el.set_default() assert el.value == {u'x': 123}
def test_dict_strict(): # a mini test, this policy thing may get whacked schema = Dict.using(policy='strict').of(Integer.named(u'x'), Integer.named(u'y')) el = schema({u'x': 123, u'y': 456}) el = schema() assert_raises(TypeError, el.set, {u'x': 123}) el = schema() assert_raises(KeyError, el.set, {u'x': 123, u'y': 456, u'z': 7})
def new_schema(self): dictkw, x_kw, y_kw = {}, {}, {} if self.policy is not Unspecified: dictkw['policy'] = self.policy if self.x_default is not Unspecified: x_kw['default'] = self.x_default if self.y_default is not Unspecified: y_kw['default'] = self.y_default return self.schema.named(u's').using(**dictkw).of( Integer.named(u'x').using(**x_kw), Integer.named(u'y').using(**y_kw))
def test_sparsedict_from_flat(): schema = SparseDict.of(Integer.named(u'x'), Integer.named(u'y')) el = schema.from_flat([]) assert el.items() == [] el = schema.from_flat([(u'x', u'123')]) assert el.value == {u'x': 123} el = schema.from_flat([(u'x', u'123'), (u'z', u'456')]) assert el.value == {u'x': 123}
def test_mutation(): schema = List.named(u'l').of(Integer.named(u'i')) el = schema() new_element = Integer.named(u'i') def order_ok(): slot_names = list(_.name for _ in el._slots) for idx, name in enumerate(slot_names): assert name == str(idx).decode('ascii') assert not el order_ok() # FIXME:? seems to want parsable data, not elements el.append(new_element(u'0')) assert el.value == [0] order_ok() el.append(u'123') assert el.value == [0, 123] order_ok() el.extend([u'4', u'5']) assert el.value == [0, 123, 4, 5] order_ok() el[0] = u'3' assert el.value == [3, 123, 4, 5] order_ok() el.insert(0, u'2') assert el.value == [2, 3, 123, 4, 5] order_ok() v = el.pop() assert v.value == 5 assert not v.parent order_ok() v = el.pop(0) assert v.value == 2 assert el.value == [3, 123, 4] order_ok() el.remove(u'3') assert el.value == [123, 4] order_ok() del el[:] assert el.value == [] order_ok()
def test_sparsedict_required_from_flat(): schema = SparseDict.of(Integer.named(u'x'), Integer.named(u'y').using(optional=True)).\ using(minimum_fields='required') el = schema.from_flat([]) assert el.value == {u'x': None} el = schema.from_flat([(u'x', u'123')]) assert el.value == {u'x': 123} el = schema.from_flat([(u'y', u'456'), (u'z', u'789')]) assert el.value == {u'x': None, u'y': 456}
def test_sparsedict_required_validation(): schema = SparseDict.of(Integer.named(u'x'), Integer.named(u'y').using(optional=True)).\ using(minimum_fields='required') el = schema() assert not el.validate() el = schema({u'y': 456}) assert not el.validate() el = schema({u'x': 123, u'y': 456}) assert el.validate()
def test_dict_immutable_keys(): schema = Dict.of(Integer.named(u'x'), Integer.named(u'y')) el = schema() assert_raises(TypeError, el.__setitem__, u'z', 123) assert_raises(TypeError, el.__delitem__, u'x') assert_raises(KeyError, el.__delitem__, u'z') assert_raises(TypeError, el.setdefault, u'x', 123) assert_raises(TypeError, el.setdefault, u'z', 123) assert_raises(TypeError, el.pop, u'x') assert_raises(KeyError, el.pop, u'z') assert_raises(TypeError, el.popitem) assert_raises(TypeError, el.clear)
def test_simple_validation_shortcircuit(): Regular = Dict.of(Integer.using(optional=False)) el = Regular() assert not el.validate() def boom(element, state): assert False all_ok = lambda element, state: SkipAll Boom = Integer.named(u'i').using(validators=[boom]) ShortCircuited = Dict.of(Boom).using(descent_validators=[all_ok]) el = ShortCircuited() assert el.validate()
def test_scalar_set_default(): el = Integer() el.set_default() assert el.value is None el = Integer(default=10) el.set_default() assert el.value == 10 el = Integer(default_factory=lambda e: 20) el.set_default() assert el.value == 20
def test_nested_dict_as_unicode(): schema = Dict.of(Dict.named(u'd').of( Integer.named(u'x').using(default=10))) el = schema.from_defaults() eq_(el.value, {u'd': {u'x': 10}}) eq_(el.u, u"{u'd': {u'x': u'10'}}")
def _populate_app_fields(self): with WindowServiceProxy(59000) as w: self.video_mode_map = w.get_video_mode_map() if self.video_mode_map: self._video_available = True else: self._video_available = False self.video_mode_keys = sorted(self.video_mode_map.keys()) if self._video_available: self.device_key, self.devices = w.get_video_source_configs() field_list = [ Integer.named('overlay_opacity').using(default=50, optional=True), Directory.named('device_directory').using(default='', optional=True), String.named('transform_matrix').using(default='', optional=True, properties={'show_in_gui': False}), ] if self._video_available: video_mode_enum = Enum.named('video_mode').valued( *self.video_mode_keys).using(default=self.video_mode_keys[0], optional=True) video_enabled_boolean = Boolean.named('video_enabled').using( default=False, optional=True, properties={'show_in_gui': True}) recording_enabled_boolean = Boolean.named('recording_enabled').using( default=False, optional=True, properties={'show_in_gui': False}) field_list.append(video_mode_enum) field_list.append(video_enabled_boolean) field_list.append(recording_enabled_boolean) return Form.of(*field_list)
def test_reverse(): schema = List.named(u'l').of(Integer.named(u'i')) el = schema([2, 1]) assert el.flatten() == [(u'l_0_i', u'2'), (u'l_1_i', u'1')] el.reverse() assert el.value == [1, 2] assert el.flatten() == [(u'l_0_i', u'1'), (u'l_1_i', u'2')]
def test_set_flat_miss(): pairs = [(u'l_galump', u'3'), (u'l_snorgle', u'4')] schema = List.named(u'l').of(Integer.named(u'i')) el = schema.from_flat(pairs) eq_(len(el), 0) eq_(el.value, [])
def test_set_flat_linear(): pairs = [(u'l_0_i', 1), (u'l_1_i', 2), (u'l_2_i', 3)] schema = List.named(u'l').of(Integer.named(u'i')) el = schema.from_flat(pairs) eq_(len(el), len(pairs)) eq_(el.value, list(pair[1] for pair in pairs))
def test_not_writable(): schema = Dict.of(Integer.named(u'main'), Ref.named(u'aux').to(u'main').using(writable=False)) el = schema() with pytest.raises(TypeError): el[u'aux'].set(6)
def test_writable(): schema = Dict.of(Integer.named(u'main'), Ref.named(u'aux').to(u'main').using(writable=True)) el = schema() el[u'aux'] = 6 assert el[u'main'].value == 6 assert el[u'aux'].value == 6
def test_slots(): schema = List.named(u'l').of(Integer.named(u'i')) el = schema([1, 2]) assert len(list(el._slots)) == 2 for slot in el._slots: # don't really care what it says, just no crashy. assert repr(slot) assert [slot.value for slot in el._slots] == [1, 2]
def test_sparsedict_operations(): schema = SparseDict.of(Integer.named(u'x'), Integer.named(u'y')) el = schema() el[u'x'] = 123 del el[u'x'] assert_raises(KeyError, el.__delitem__, u'x') assert el.setdefault(u'x', 123) == 123 assert el.setdefault(u'x', 456) == 123 assert el.setdefault(u'y', 123) == 123 assert el.setdefault(u'y', 456) == 123 assert schema().is_empty assert not schema().validate() opt_schema = schema.using(optional=True) assert opt_schema().validate()
def test_dict_update(): schema = Dict.of(Integer.named(u'x'), Integer.named(u'y')) el = schema() def value_dict(element): return dict((k, v.value) for k, v in element.iteritems()) try: el.update(x=20, y=30) except UnicodeError: assert not unicode_coercion_available() el.update(udict(x=20, y=30)) assert udict(x=20, y=30) == el.value el.update({u'y': 40}) assert udict(x=20, y=40) == el.value el.update() assert udict(x=20, y=40) == el.value el.update((_, 100) for _ in u'xy') assert udict(x=100, y=100) == el.value try: el.update([(u'x', 1)], y=2) assert udict(x=1, y=2) == el.value except UnicodeError: assert not unicode_coercion_available() try: el.update([(u'x', 10), (u'y', 10)], x=20, y=20) assert udict(x=20, y=20) == el.value except UnicodeError: assert not unicode_coercion_available() if unicode_coercion_available(): assert_raises(TypeError, el.update, z=1) assert_raises(TypeError, el.update, x=1, z=1) assert_raises(TypeError, el.update, {u'z': 1}) assert_raises(TypeError, el.update, {u'x': 1, u'z': 1}) assert_raises(TypeError, el.update, ((u'z', 1),)) assert_raises(TypeError, el.update, ((u'x', 1), (u'z', 1)))
def test_sparsedict_required_operations(): schema = SparseDict.using(minimum_fields='required').\ of(Integer.named(u'opt').using(optional=True), Integer.named(u'req')) el = schema({u'opt': 123, u'req': 456}) del el[u'opt'] assert_raises(KeyError, el.__delitem__, u'opt') assert_raises(TypeError, el.__delitem__, u'req') el = schema() assert el.setdefault(u'opt', 123) == 123 assert el.setdefault(u'opt', 456) == 123 assert el.setdefault(u'req', 123) == 123 assert el.setdefault(u'req', 456) == 123 assert not schema().is_empty assert not schema().validate()
def test_sparsedict_flattening(): schema = SparseDict.named(u'top').\ of(Integer.named(u'x'), Integer.named(u'y')) els = [ schema({'x': 123, 'y': 456}), schema(), schema(), schema(), ] els[1].set({'x': 123, 'y': 456}) els[2]['x'] = 123 els[2]['y'] = 456 els[3]['x'] = Integer(123) els[3]['y'] = Integer(456) wanted = [(u'top_x', u'123'), (u'top_y', u'456')] for el in els: got = sorted(el.flatten()) assert wanted == got
def test_sort(): schema = List.named(u'l').of(Integer.named(u'i')) el = schema([2, 1]) el.sort(key=lambda el: el.value) assert el.value == [1, 2] assert el.flatten() == [(u'l_0_i', u'1'), (u'l_1_i', u'2')] el.sort(key=lambda el: el.value, reverse=True) assert el.value == [2, 1] assert el.flatten() == [(u'l_0_i', u'2'), (u'l_1_i', u'1')]
def test_shortcircuit_up(self): schema = ( Dict.of( Integer.using(validators=[self.validator('2', True)])). using( descent_validators=[self.validator('1', True)], validators=[self.validator('3', SkipAll)])) el = schema() assert el.validate() eq_(self.canary, ['1', '2', '3']) assert el.valid assert el.all_valid
def test_paired3(self): schema = ( Dict.of( Integer.using(validators=[self.validator('2', True)])). using( descent_validators=[self.validator('1', True)], validators=[self.validator('3', True)])) el = schema() assert el.validate() eq_(self.canary, ['1', '2', '3']) assert el.valid assert el.all_valid
class BA4(B, A): field_schema = [Integer.named('ab_member')] ab_member = String
def element(writable): ref = Ref.named(u'aux').to(u'main') if writable: ref = ref.using(writable=writable) return Dict.of(Integer.named(u'main'), ref)()
def test_not_writable(): schema = Dict.of(Integer.named(u'main'), Ref.named(u'aux').to(u'main').using(writable=False)) el = schema() assert_raises(TypeError, el[u'aux'].set, 6)
except re.error: valid = False if not valid: element.add_error("Subscription has invalid value.") return valid common_meta = ( String.named(keys.ITEMID).validated_by(itemid_validator), String.named(keys.REVID).validated_by(revid_validator), String.named(keys.PARENTID).validated_by(uuid_validator).using(optional=True), String.named(keys.WIKINAME).using(strip=False).validated_by(wikiname_validator), String.named(keys.NAMESPACE).using(strip=False).validated_by(namespace_validator), List.named(keys.NAME).of(String.using(strip=False).validated_by(name_validator)).using(optional=True), List.named(keys.NAME_OLD).of(String.using(strip=False).validated_by(name_validator)).using(optional=True), Integer.named(keys.MTIME).validated_by(mtime_validator), String.named(keys.ACTION).validated_by(action_validator), String.named(keys.ACL).validated_by(acl_validator), String.named(keys.COMMENT).validated_by(comment_validator), String.named(keys.ADDRESS).validated_by(address_validator), String.named(keys.HOSTNAME).validated_by(hostname_validator).using(optional=True), List.named(keys.TAGS).of(String.named('tag').validated_by(tag_validator)).using(optional=True), ) ContentMetaSchema = DuckDict.named('ContentMetaSchema').of( String.named(keys.CONTENTTYPE).validated_by(contenttype_validator), String.named(keys.USERID).validated_by(userid_validator), Integer.named(keys.SIZE).validated_by(size_validator), String.named(keys.HASH_ALGORITHM).validated_by(hash_validator), String.named(keys.DATAID).validated_by(uuid_validator).using(optional=True), # markup items may have this:
class DropletPlanningPlugin(Plugin, StepOptionsController, pmh.BaseMqttReactor): """ This class is automatically registered with the PluginManager. """ implements(IPlugin) version = get_plugin_info(path(__file__).parent).version plugin_name = get_plugin_info(path(__file__).parent).plugin_name ''' StepFields --------- A flatland Form specifying the per step options for the current plugin. Note that nested Form objects are not supported. Since we subclassed StepOptionsController, an API is available to access and modify these attributes. This API also provides some nice features automatically: -all fields listed here will be included in the protocol grid view (unless properties=dict(show_in_gui=False) is used) -the values of these fields will be stored persistently for each step ''' StepFields = Form.of( Integer.named('trail_length').using(default=1, optional=True, validators= [ValueAtLeast(minimum=1)]), Integer.named('route_repeats').using(default=1, optional=True, validators= [ValueAtLeast(minimum=1)]), Integer.named('repeat_duration_s').using(default=0, optional=True), Integer.named('transition_duration_ms') .using(optional=True, default=750, validators=[ValueAtLeast(minimum=0)])) def __init__(self,*args, **kwargs): self.name = self.plugin_name self.step_start_time = None self.route_controller = None pmh.BaseMqttReactor.__init__(self) self.start() def get_schedule_requests(self, function_name): """ Returns a list of scheduling requests (i.e., ScheduleRequest instances) for the function specified by function_name. """ if function_name in ['on_step_run']: # Execute `on_step_run` before control board. return [ScheduleRequest(self.name, 'dmf_control_board_plugin')] return [] def on_connect(self, client, userdata, flags, rc): self.mqtt_client.subscribe("microdrop/dmf-device-ui/add-route") self.mqtt_client.subscribe("microdrop/dmf-device-ui/get-routes") self.mqtt_client.subscribe("microdrop/dmf-device-ui/clear-routes") self.mqtt_client.subscribe('microdrop/dmf-device-ui/execute-routes') self.mqtt_client.subscribe('microdrop/dmf-device-ui/update-protocol') self.mqtt_client.subscribe("microdrop/mqtt-plugin/step-inserted") def on_message(self, client, userdata, msg): ''' Callback for when a ``PUBLISH`` message is received from the broker. ''' logger.info('[on_message] %s: "%s"', msg.topic, msg.payload) if msg.topic == 'microdrop/dmf-device-ui/add-route': self.add_route(json.loads(msg.payload)) self.get_routes() if msg.topic == 'microdrop/dmf-device-ui/get-routes': self.get_routes() if msg.topic == 'microdrop/dmf-device-ui/clear-routes': data = json.loads(msg.payload) if data: self.clear_routes(electrode_id=data['electrode_id']) else: self.clear_routes() if msg.topic == 'microdrop/dmf-device-ui/execute-routes': self.execute_routes(json.loads(msg.payload)) if msg.topic == 'microdrop/dmf-device-ui/update-protocol': self.update_protocol(json.loads(msg.payload)) if msg.topic == "microdrop/mqtt-plugin/step-inserted": self.step_inserted(json.loads(msg.payload)) def on_plugin_enable(self): self.route_controller = RouteController(self) form = flatlandToDict(self.StepFields) self.mqtt_client.publish('microdrop/droplet-planning-plugin/schema', json.dumps(form), retain=True) defaults = {} for k,v in form.iteritems(): defaults[k] = v['default'] self.mqtt_client.publish('microdrop/droplet-planning-plugin/step-options', json.dumps([defaults], cls=PandasJsonEncoder), retain=True) def on_plugin_disable(self): """ Handler called once the plugin instance is disabled. """ pass def on_app_exit(self): """ Handler called just before the Microdrop application exits. """ pass ########################################################################### # Step event handler methods def on_error(self, *args): logger.error('Error executing routes.', exc_info=True) # An error occurred while initializing Analyst remote control. emit_signal('on_step_complete', [self.name, 'Fail']) def on_protocol_pause(self): self.kill_running_step() def kill_running_step(self): # Stop execution of any routes that are currently running. if self.route_controller is not None: self.route_controller.reset() def on_step_run(self): """ Handler called whenever a step is executed. Note that this signal is only emitted in realtime mode or if a protocol is running. Plugins that handle this signal must emit the on_step_complete signal once they have completed the step. The protocol controller will wait until all plugins have completed the current step before proceeding. return_value can be one of: None 'Repeat' - repeat the step or 'Fail' - unrecoverable error (stop the protocol) """ app = get_app() if not app.running: return self.kill_running_step() step_options = self.get_step_options() try: self.repeat_i = 0 self.step_start_time = datetime.now() df_routes = self.get_routes() self.route_controller.execute_routes( df_routes, step_options['transition_duration_ms'], trail_length=step_options['trail_length'], on_complete=self.on_step_routes_complete, on_error=self.on_error) except: self.on_error() def on_step_routes_complete(self, start_time, electrode_ids): ''' Callback function executed when all concurrent routes for a step have completed a single run. If repeats are requested, either through repeat counts or a repeat duration, *cycle* routes (i.e., routes that terminate at the start electrode) will repeat as necessary. ''' step_options = self.get_step_options() step_duration_s = (datetime.now() - self.step_start_time).total_seconds() if ((step_options['repeat_duration_s'] > 0 and step_duration_s < step_options['repeat_duration_s']) or (self.repeat_i + 1 < step_options['route_repeats'])): # Either repeat duration has not been met, or the specified number # of repetitions has not been met. Execute another iteration of # the routes. self.repeat_i += 1 df_routes = self.get_routes() self.route_controller.execute_routes( df_routes, step_options['transition_duration_ms'], trail_length=step_options['trail_length'], cyclic=True, acyclic=False, on_complete=self.on_step_routes_complete, on_error=self.on_error) else: logger.info('Completed routes (%s repeats in %ss)', self.repeat_i + 1, si_format(step_duration_s)) # Transitions along all droplet routes have been processed. # Signal step has completed and reset plugin step state. emit_signal('on_step_complete', [self.name, None]) def on_step_options_swapped(self, plugin, old_step_number, step_number): """ Handler called when the step options are changed for a particular plugin. This will, for example, allow for GUI elements to be updated based on step specified. Parameters: plugin : plugin instance for which the step options changed step_number : step number that the options changed for """ logger.info('[on_step_swapped] old step=%s, step=%s', old_step_number, step_number) self.kill_running_step() def on_step_removed(self, step_number, step): self.update_steps() def on_step_options_changed(self, plugin, step_number): self.update_steps() def on_step_swapped(self, old_step_number, step_number): """ Handler called when the current step is swapped. """ logger.info('[on_step_swapped] old step=%s, step=%s', old_step_number, step_number) self.kill_running_step() self.get_routes() def on_step_inserted(self, step_number, *args): self.step_inserted(step_number) def step_inserted(self, step_number): app = get_app() logger.info('[on_step_inserted] current step=%s, created step=%s', app.protocol.current_step_number, step_number) self.clear_routes(step_number=step_number) ########################################################################### # Step options dependent methods def update_protocol(self, protocol): app = get_app() for i, s in enumerate(protocol): step = app.protocol.steps[i] prevData = step.get_data(self.plugin_name) values = {} for k,v in prevData.iteritems(): if k in s: values[k] = s[k] step.set_data(self.plugin_name, values) emit_signal('on_step_options_changed', [self.plugin_name, i], interface=IPlugin) def add_route(self, electrode_ids): ''' Add droplet route. Args: electrode_ids (list) : Ordered list of identifiers of electrodes on route. ''' drop_routes = self.get_routes() route_i = (drop_routes.route_i.max() + 1 if drop_routes.shape[0] > 0 else 0) drop_route = (pd.DataFrame(electrode_ids, columns=['electrode_i']) .reset_index().rename(columns={'index': 'transition_i'})) drop_route.insert(0, 'route_i', route_i) drop_routes = drop_routes.append(drop_route, ignore_index=True) self.set_routes(drop_routes) return {'route_i': route_i, 'drop_routes': drop_routes} def clear_routes(self, electrode_id=None, step_number=None): ''' Clear all drop routes for protocol step that include the specified electrode (identified by string identifier). ''' step_options = self.get_step_options(step_number) if electrode_id is None: # No electrode identifier specified. Clear all step routes. df_routes = RouteController.default_routes() else: df_routes = step_options['drop_routes'] # Find indexes of all routes that include electrode. routes_to_clear = df_routes.loc[df_routes.electrode_i == electrode_id, 'route_i'] # Remove all routes that include electrode. df_routes = df_routes.loc[~df_routes.route_i .isin(routes_to_clear.tolist())].copy() step_options['drop_routes'] = df_routes self.set_step_values(step_options, step_number=step_number) self.get_routes() def get_routes(self, step_number=None): step_options = self.get_step_options(step_number=step_number) x = step_options.get('drop_routes', RouteController.default_routes()) msg = json.dumps(x, cls=PandasJsonEncoder) self.mqtt_client.publish('microdrop/droplet-planning-plugin/routes-set', msg, retain=True) return x def execute_routes(self, data): # TODO allow for passing of both electrode_id and route_i # Currently electrode_id only try: df_routes = self.get_routes() step_options = self.get_step_options() if 'transition_duration_ms' in data: transition_duration_ms = data['transition_duration_ms'] else: transition_duration_ms = step_options['transition_duration_ms'] if 'trail_length' in data: trail_length = data['trail_length'] else: trail_length = step_options['trail_length'] if 'route_i' in data: df_routes = df_routes.loc[df_routes.route_i == data['route_i']] elif 'electrode_i' in data: if data['electrode_i'] is not None: routes_to_execute = df_routes.loc[df_routes.electrode_i == data['electrode_i'], 'route_i'] df_routes = df_routes.loc[df_routes.route_i .isin(routes_to_execute .tolist())].copy() route_controller = RouteController(self) route_controller.execute_routes(df_routes, transition_duration_ms, trail_length=trail_length) except: logger.error(str(data), exc_info=True) def update_steps(self): app = get_app() num_steps = len(app.protocol.steps) protocol = [] for i in range(num_steps): protocol.append(self.get_step_options(i)) self.mqtt_client.publish('microdrop/droplet-planning-plugin/step-options', json.dumps(protocol, cls=PandasJsonEncoder), retain=True) def set_routes(self, df_routes, step_number=None): step_options = self.get_step_options(step_number=step_number) step_options['drop_routes'] = df_routes self.set_step_values(step_options, step_number=step_number)
cols=COLS).using(label=L_('Subscriptions'), optional=True, separator='\n', separator_regex=re.compile(r'[\r\n]+')) Quicklinks = MyJoinedString.of(String).with_properties( widget=WIDGET_MULTILINE_TEXT, rows=ROWS, cols=COLS).using(label=L_('Quick Links'), optional=True, separator='\n', separator_regex=re.compile(r'[\r\n]+')) Search = Text.using(default=u'', optional=True).with_properties( widget=WIDGET_SEARCH, placeholder=L_("Search Query")) _Integer = Integer.validated_by(Converted()) AnyInteger = _Integer.with_properties(widget=WIDGET_ANY_INTEGER) Natural = AnyInteger.validated_by(ValueAtLeast(0)) SmallNatural = _Integer.with_properties(widget=WIDGET_SMALL_NATURAL) class DateTimeUNIX(_DateTime): """ A DateTime that uses a UNIX timestamp instead of datetime as internal representation of DateTime. """ def serialize(self, value): """Serializes value to string."""
#! -*- coding: utf-8 -*- from flatland import Array, Boolean, Integer from flatland.out import generic from flatland.out.generic import Context Unspecified = object() Unique = object() schema = Integer.named(u'number') boolean_schema = Boolean.named(u'bool') partial_anon_schema = Array.named(u'array').of(Integer) full_anon_schema = Array.of(Integer) def assert_bound_transform(fn, tagname, given, expected, **kw): return assert_transform(fn, tagname, given, expected, **kw) def assert_unbound_transform(fn, tagname, given, expected, **kw): kw['bind'] = None return assert_transform(fn, tagname, given, expected, **kw) def assert_transform(fn, tagname, given, expected, context=Unspecified, bind=Unspecified, contents=Unspecified, expected_contents=Unspecified): if context is Unspecified:
def test_dict_as_unicode(): schema = Dict.of(Integer.named(u'x'), Integer.named(u'y')) el = schema({u'x': 1, u'y': 2}) assert el.u in (u"{u'x': u'1', u'y': u'2'}", u"{u'y': u'2', u'x': u'1'}")
def test_sparsedict_bogus_set_default(): schema = SparseDict.using(minimum_fields='bogus').\ of(Integer.named(u'x')) el = schema() assert_raises(RuntimeError, el.set_default)
def adapt(self, value): try: return Integer.adapt(self, value) except: return None
def __init__(self, forms, enabled_attrs, show_ids=True, **kwargs): self.first_selected = True self._forms = forms.copy() row_id_properties = dict(editable=False) if not show_ids: row_id_properties['show_in_gui'] = False self._forms['__DefaultFields'] = \ Form.of(Integer.named('id').using(default=0, properties=row_id_properties)) self.uuid_mapping = dict([(name, uuid4().get_hex()[:10]) for name in self._forms]) self.uuid_reverse_mapping = dict([ (v, k) for k, v in self.uuid_mapping.items() ]) self._columns = [] self._full_field_to_field_def = {} if not enabled_attrs: def enabled(form_name, field): return True else: def enabled(form_name, field): return field.name in enabled_attrs.get(form_name, {}) # Make __DefaultFields.id the first column form_names = ['__DefaultFields'] + sorted(forms.keys()) for form_name in form_names: form = self._forms[form_name] for field_name in form.field_schema: if all([ not form_name == '__DefaultFields', not enabled(form_name, field_name) ]): continue default_title = re.sub(r'_', ' ', field_name.name).capitalize() # Use custom column heading/title, if available. title = field_name.properties.get('title', default_title) prefix = self.field_set_prefix % self.uuid_mapping[form_name] name = '%s%s' % (prefix, field_name.name) val_type = get_type_from_schema(field_name) d = dict(attr=name, type=val_type, title=title, resizable=True, editable=True, sorted=False) if field_name.properties.get('mappers', None): d['mappers'] = deepcopy(field_name.properties['mappers']) for m in d['mappers']: m.attr = '%s%s' % (prefix, m.attr) if 'editable' in field_name.properties: d['editable'] = field_name.properties['editable'] if 'show_in_gui' in field_name.properties: d['visible'] = field_name.properties['show_in_gui'] if val_type == bool: # Use checkbox for boolean cells d['use_checkbox'] = True elif val_type == int: # Use spinner for integer cells d['use_spin'] = True d['step'] = field_name.properties.get('step', 1) elif val_type == float: # Use spinner for integer cells d['use_spin'] = True d['digits'] = field_name.properties.get('digits', 2) d['step'] = field_name.properties.get('step', 0.1) self._columns.append(Column(**d)) self._full_field_to_field_def[name] = field_name super(CombinedFields, self).__init__(self._columns, **kwargs) s = self.get_selection() # Enable multiple row selection s.set_mode(Gtk.SelectionMode.MULTIPLE) self.connect('item-changed', self._on_item_changed) self.connect('item-right-clicked', self._on_right_clicked) self.enabled_fields_by_form_name = enabled_attrs self.connect('item-added', lambda x, y: self.reset_row_ids()) self.connect('item-inserted', lambda x, y, z: self.reset_row_ids()) self.connect('item-removed', lambda x, y: self.reset_row_ids())
class BA3(B, A): field_schema = [Integer.named('b_member')] a_member = Integer