def test_LoadPersistentUpdateValueFlags(storage_populated, outgoing, is_server): storage = storage_populated fp = StringIO("[NetworkTables Storage 3.0]\ndouble \"foo2\"=1.0\n") assert storage.loadPersistent(fp=fp) is None entry = storage.m_entries.get("foo2") assert Value.makeDouble(1.0) == entry.value assert NT_PERSISTENT == entry.flags if is_server: assert 2 == len(outgoing) assert not outgoing[0].only assert not outgoing[0].conn msg = outgoing[0].msg assert kEntryUpdate == msg.type assert 1 == msg.id # assigned as server assert 2 == msg.seq_num_uid # incremented assert Value.makeDouble(1.0) == msg.value assert not outgoing[1].only assert not outgoing[1].conn msg = outgoing[1].msg assert kFlagsUpdate == msg.type assert 1 == msg.id # assigned as server assert NT_PERSISTENT == msg.flags else: # shouldn't send an update id not assigned yet (happens on client only) assert len(outgoing) == 0 assert 2 == storage.m_entries.get("foo2").seq_num # still should be incremented
def getGlobalAutoUpdateValue(cls, key, defaultValue, writeDefault): """Global version of getAutoUpdateValue. This function will not initialize NetworkTables. :param key: the full NT path of the value (must start with /) :type key: str :param defaultValue: The default value to return if the key doesn't exist :type defaultValue: any :param writeDefault: If True, force the value to the specified default :type writeDefault: bool .. versionadded:: 2015.3.0 .. seealso:: :func:`.ntproperty` is a read-write alternative to this """ assert key.startswith("/") # Use raw NT api to avoid having to initialize networktables value = None valuefn = None # optimization for ntproperty if not writeDefault: value = cls._api.getEntryValue(key) if value is None: valuefn = Value.getFactory(defaultValue) cls._api.setEntryValue(key, valuefn(defaultValue)) value = defaultValue else: valuefn = Value.getFactory(value) return cls._api.createAutoValue(key, AutoUpdateValue(key, value, valuefn))
def test_LoadPersistentAssign(storage_empty, outgoing, is_server): storage = storage_empty fp = StringIO("[NetworkTables Storage 3.0]\nboolean \"foo\"=true\n") assert storage.loadPersistent(fp=fp) is None entry = storage.m_entries.get("foo") assert Value.makeBoolean(True) == entry.value assert NT_PERSISTENT == entry.flags assert 1 == len(outgoing) assert not outgoing[0].only assert not outgoing[0].conn msg = outgoing[0].msg assert kEntryAssign == msg.type assert "foo" == msg.str if is_server: assert 0 == msg.id # assigned as server else: assert 0xffff == msg.id # not assigned as client assert 1 == msg.seq_num_uid assert Value.makeBoolean(True) == msg.value assert NT_PERSISTENT == msg.flags
def test_EntryNewRemote(nt_live, server_cb): nt_server, nt_client = nt_live nt_server_api = nt_server._api nt_client_api = nt_client._api nt_server_api.addEntryListenerById( nt_server_api.getEntryId("/foo"), server_cb, NT_NOTIFY_NEW ) # Trigger an event nt_client_api.setEntryValueById( nt_client_api.getEntryId("/foo/bar"), Value.makeDouble(2.0) ) nt_client_api.setEntryValueById( nt_client_api.getEntryId("/foo"), Value.makeDouble(1.0) ) nt_client_api.flush() assert nt_server_api.waitForEntryListenerQueue(1.0) # Check the event events = server_cb.wait(1) # assert events[0].listener == handle assert events[0].local_id == nt_server_api.getEntryId("/foo") assert events[0].name == "/foo" assert events[0].value == Value.makeDouble(1.0) assert events[0].flags == NT_NOTIFY_NEW
def test_Double(): v = Value.makeDouble(0.5) assert NT_DOUBLE == v.type assert 0.5 == v.value v = Value.makeDouble(0.25) assert NT_DOUBLE == v.type assert 0.25 == v.value
def test_StringComparison(): v1 = Value.makeString("hello") v2 = Value.makeString("hello") assert v1 == v2 v2 = Value.makeString("world"); # different contents assert v1 != v2 v2 = Value.makeString("goodbye"); # different size assert v1 != v2
def test_Raw(): v = Value.makeRaw(b"hello") assert NT_RAW == v.type assert b"hello" == v.value v = Value.makeRaw(b"goodbye") assert NT_RAW == v.type assert b"goodbye" == v.value
def test_String(): v = Value.makeString("hello") assert NT_STRING == v.type assert "hello" == v.value v = Value.makeString("goodbye") assert NT_STRING == v.type assert "goodbye" == v.value
def test_Boolean(): v = Value.makeBoolean(False) assert NT_BOOLEAN == v.type assert not v.value v = Value.makeBoolean(True) assert NT_BOOLEAN == v.type assert v.value
def storage_populated(storage_empty, outgoing): storage = storage_empty storage.setEntryTypeValue("foo", Value.makeBoolean(True)) storage.setEntryTypeValue("foo2", Value.makeDouble(0.0)) storage.setEntryTypeValue("bar", Value.makeDouble(1.0)) storage.setEntryTypeValue("bar2", Value.makeBoolean(False)) del outgoing[:] return storage
def test_DoubleArrayComparison(): v1 = Value.makeDoubleArray([0.5, 0.25, 0.5]) v2 = Value.makeDoubleArray((0.5, 0.25, 0.5)) assert v1 == v2 # different contents v2 = Value.makeDoubleArray([0.5, 0.5, 0.5]) assert v1 != v2 # different size v2 = Value.makeDoubleArray([0.5, 0.25]) assert v1 != v2
def test_BooleanArrayComparison(): v1 = Value.makeBooleanArray([1, 0, 1]) v2 = Value.makeBooleanArray((1, 0, 1)) assert v1 == v2 # different contents v2 = Value.makeBooleanArray([1, 1, 1]) assert v1 != v2 # different size v2 = Value.makeBooleanArray([True, False]) assert v1 != v2
def test_StringArrayComparison(): v1 = Value.makeStringArray(["hello", "goodbye", "string"]) v2 = Value.makeStringArray(("hello", "goodbye", "string")) assert v1 == v2 # different contents v2 = Value.makeStringArray(["hello", "goodby2", "string"]) assert v1 != v2 # different sized contents v2 = Value.makeStringArray(["hello", "goodbye2", "string"]) assert v1 != v2 # different size v2 = Value.makeStringArray(["hello", "goodbye"]) assert v1 != v2
def test_SetEntryTypeValueAssignNew( storage_empty, dispatcher, entry_notifier, is_server ): storage = storage_empty # brand new entry value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) assert value == storage.m_entries.get("foo").value dispatcher._queueOutgoing.assert_has_calls( [ call( Message.entryAssign("foo", 0 if is_server else 0xFFFF, 1, value, 0), None, None, ) ] ) entry_notifier.notifyEntry.assert_has_calls( [call(0, "foo", value, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)] ) if is_server: assert 1 == len(storage.m_idmap) assert value == storage.m_idmap[0].value else: assert len(storage.m_idmap) == 0
def forceSetStringArray(self, value): """Sets the entry's value. :param value: the value to set """ value = Value.makeStringArray(value) return self.__api.setEntryTypeValueById(self._local_id, value)
def putValue(self, key, value): """Put a value in the table, trying to autodetect the NT type of the value. Refer to this table to determine the type mapping: ======= ============================ ================================= PyType NT Type Notes ======= ============================ ================================= bool :attr:`.EntryTypes.BOOLEAN` int :attr:`.EntryTypes.DOUBLE` float :attr:`.EntryTypes.DOUBLE` str :attr:`.EntryTypes.STRING` bytes :attr:`.EntryTypes.RAW` Doesn't work in Python 2.7 list Error Use `putXXXArray` methods instead tuple Error Use `putXXXArray` methods instead ======= ============================ ================================= :param key: the key to be assigned to :type key: str :param value: the value that will be assigned :type value: bool, int, float, str, bytes :returns: False if the table key already exists with a different type :rtype: bool .. versionadded:: 2017.0.0 """ value = Value.getFactory(value)(value) path = self._path + key return self._api.setEntryValue(path, value)
def test_SetEntryTypeValueAssignNew(storage_empty, outgoing, is_server): storage = storage_empty # brand entry value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) assert value == storage.m_entries.get("foo").value if is_server: assert 1 == len(storage.m_idmap) assert value == storage.m_idmap[0].value else: assert len(storage.m_idmap) == 0 assert 1 == len(outgoing) assert not outgoing[0].only assert not outgoing[0].conn msg = outgoing[0].msg assert kEntryAssign == msg.type assert "foo" == msg.str if is_server: assert 0 == msg.id # assigned as server else: assert 0xffff == msg.id # not assigned as client assert 1 == msg.seq_num_uid assert value == msg.value assert 0 == msg.flags
def test_DeleteEntryExist(storage_populated, dispatcher, entry_notifier, is_server): storage = storage_populated storage.deleteEntry("foo2") entry = storage.m_entries.get("foo2") assert entry is not None assert entry.value is None assert entry.id == 0xFFFF assert entry.local_write == False # client shouldn't send an update as id not assigned yet if is_server: # id assigned as this is the server dispatcher._queueOutgoing.assert_has_calls( [call(Message.entryDelete(1), None, None)]) else: # shouldn't send an update id not assigned yet assert dispatcher._queueOutgoing.call_count == 0 entry_notifier.notifyEntry.assert_has_calls([ call(1, "foo2", Value.makeDouble(0.0), NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL) ]) if is_server: assert len(storage.m_idmap) >= 2 assert not storage.m_idmap[1]
def test_LoadPersistentUpdateValueFlags(storage_populated, dispatcher, entry_notifier, is_server): storage = storage_populated fp = StringIO('[NetworkTables Storage 3.0]\ndouble "foo2"=1.0\n') assert storage.loadPersistent(fp=fp) is None entry = storage.m_entries.get("foo2") assert Value.makeDouble(1.0) == entry.value assert NT_PERSISTENT == entry.flags # client shouldn't send an update as id not assigned yet if is_server: # id assigned as this is the server; seq_num incremented dispatcher._queueOutgoing.assert_has_calls([ call(Message.entryUpdate(1, 2, entry.value), None, None), call(Message.flagsUpdate(1, NT_PERSISTENT), None, None), ]) else: assert dispatcher._queueOutgoing.call_count == 0 entry_notifier.notifyEntry.assert_has_calls([ call( 1, "foo2", entry.value, NT_NOTIFY_FLAGS | NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL, ) ]) if not is_server: assert 2 == storage.m_entries.get( "foo2").seq_num # still should be incremented
def test_GetEntryValueExist(storage_empty, outgoing): storage = storage_empty value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) del outgoing[:] assert value == storage.getEntryValue("foo")
def storage_populate_one(storage_empty, outgoing): storage = storage_empty storage.setEntryTypeValue("foo", Value.makeBoolean(True)) del outgoing[:] return storage
def test_ProcessIncomingEntryAssignWithFlags( storage_populate_one, dispatcher, entry_notifier, is_server, conn ): storage = storage_populate_one value = Value.makeDouble(1.0) storage.processIncoming(Message.entryAssign("foo", 0, 1, value, 0x2), conn) # EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u)) if is_server: # server broadcasts new value/flags to all *other* connections dispatcher._queueOutgoing.assert_has_calls( [call(Message.entryAssign("foo", 0, 1, value, 0x2), None, conn)] ) entry_notifier.notifyEntry.assert_has_calls( [call(0, "foo", value, NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS)] ) else: # client forces flags back when an assign message is received for an # existing entry with different flags dispatcher._queueOutgoing.assert_has_calls( [call(Message.flagsUpdate(0, 0), None, None)] ) entry_notifier.notifyEntry.assert_has_calls( [call(0, "foo", value, NT_NOTIFY_UPDATE)] )
def storage_populated(storage_empty, dispatcher, entry_notifier): storage = storage_empty entry_notifier.m_local_notifiers = False entry_notifier.m_local_notifiers = False storage.setEntryTypeValue("foo", Value.makeBoolean(True)) storage.setEntryTypeValue("foo2", Value.makeDouble(0.0)) storage.setEntryTypeValue("bar", Value.makeDouble(1.0)) storage.setEntryTypeValue("bar2", Value.makeBoolean(False)) dispatcher.reset_mock() entry_notifier.reset_mock() entry_notifier.m_local_notifiers = True return storage
def test_DeleteEntryExist(storage_populated, dispatcher, entry_notifier, is_server): storage = storage_populated storage.deleteEntry("foo2") entry = storage.m_entries.get("foo2") assert entry is not None assert entry.value is None assert entry.id == 0xFFFF assert entry.local_write == False # client shouldn't send an update as id not assigned yet if is_server: # id assigned as this is the server dispatcher._queueOutgoing.assert_has_calls( [call(Message.entryDelete(1), None, None)] ) else: # shouldn't send an update id not assigned yet assert dispatcher._queueOutgoing.call_count == 0 entry_notifier.notifyEntry.assert_has_calls( [call(1, "foo2", Value.makeDouble(0.0), NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL)] ) if is_server: assert len(storage.m_idmap) >= 2 assert not storage.m_idmap[1]
def test_SetEntryValueDifferentValue( storage_populated, is_server, dispatcher, entry_notifier ): storage = storage_populated # update with same type and different value results in value update message value = Value.makeDouble(1.0) assert storage.setEntryValue("foo2", value) entry = storage.m_entries.get("foo2") assert value == entry.value # client shouldn't send an update as id not assigned yet if is_server: # id assigned if server; seq_num incremented dispatcher._queueOutgoing.assert_has_calls( [call(Message.entryUpdate(1, 2, value), None, None)] ) else: assert dispatcher._queueOutgoing.call_count == 0 entry_notifier.notifyEntry.assert_has_calls( [call(1, "foo2", value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)] ) if not is_server: assert 2 == storage.m_entries.get("foo2").seq_num # still should be incremented
def test_LoadPersistentAssign(storage_empty, dispatcher, entry_notifier, is_server): storage = storage_empty fp = StringIO('[NetworkTables Storage 3.0]\nboolean "foo"=true\n') assert storage.loadPersistent(fp=fp) is None entry = storage.m_entries.get("foo") assert Value.makeBoolean(True) == entry.value assert NT_PERSISTENT == entry.flags assert entry.isPersistent dispatcher._queueOutgoing.assert_has_calls( [ call( Message.entryAssign( "foo", 0 if is_server else 0xFFFF, 1, entry.value, NT_PERSISTENT ), None, None, ) ] ) entry_notifier.notifyEntry.assert_has_calls( [call(0, "foo", entry.value, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)] )
def test_SetEntryTypeValueAssignNew(storage_empty, dispatcher, entry_notifier, is_server): storage = storage_empty # brand new entry value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) assert value == storage.m_entries.get("foo").value dispatcher._queueOutgoing.assert_has_calls([ call( Message.entryAssign("foo", 0 if is_server else 0xFFFF, 1, value, 0), None, None, ) ]) entry_notifier.notifyEntry.assert_has_calls( [call(0, "foo", value, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)]) if is_server: assert 1 == len(storage.m_idmap) assert value == storage.m_idmap[0].value else: assert len(storage.m_idmap) == 0
def test_LoadPersistentUpdateValue( storage_populated, dispatcher, entry_notifier, is_server ): storage = storage_populated entry = storage.m_entries.get("foo2") entry.flags = NT_PERSISTENT entry.isPersistent = True fp = StringIO('[NetworkTables Storage 3.0]\ndouble "foo2"=1.0\n') assert storage.loadPersistent(fp=fp) is None entry = storage.m_entries.get("foo2") assert Value.makeDouble(1.0) == entry.value assert NT_PERSISTENT == entry.flags assert entry.isPersistent # client shouldn't send an update as id not assigned yet if is_server: # id assigned as this is the server; seq_num incremented dispatcher._queueOutgoing.assert_has_calls( [call(Message.entryUpdate(1, 2, entry.value), None, None)] ) else: assert dispatcher._queueOutgoing.call_count == 0 entry_notifier.notifyEntry.assert_has_calls( [call(1, "foo2", entry.value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)] ) if not is_server: assert 2 == storage.m_entries.get("foo2").seq_num # still should be incremented
def generateNotifications(notifier): # All flags combos that can be generated by Storage flags = [ # "normal" notifications NT_NOTIFY_NEW, NT_NOTIFY_DELETE, NT_NOTIFY_UPDATE, NT_NOTIFY_FLAGS, NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS, # immediate notifications are always "new" NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW, # local notifications can be of any flag combo NT_NOTIFY_LOCAL | NT_NOTIFY_NEW, NT_NOTIFY_LOCAL | NT_NOTIFY_DELETE, NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE, NT_NOTIFY_LOCAL | NT_NOTIFY_FLAGS, NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS, ] # Generate across keys keys = ["/foo/bar", "/baz", "/boo"] val = Value.makeDouble(1) # Provide unique key indexes for each key keyindex = 5 for key in keys: for flag in flags: notifier.notifyEntry(keyindex, key, val, flag) keyindex += 1
def setDefaultStringArray(self, defaultValue): """Sets the entry's value if it does not exist. :param defaultValue: the default value to set :returns: False if the entry exists with a different type """ value = Value.makeStringArray(defaultValue) return self.__api.setDefaultEntryValueById(self._local_id, value)
def setStringArray(self, value): """Sets the entry's value. :param value: the value to set :returns: False if the entry exists with a different type """ value = Value.makeStringArray(value) return self.__api.setEntryValueById(self._local_id, value)
def reset(self): self.ntvalue = NetworkTables.getGlobalAutoUpdateValue( self.key, self.defaultValue, self.writeDefault) if self.persistent: self.ntvalue.setPersistent() # this is an optimization, but presumes the value type never changes self.mkv = Value.getFactoryByType(self.ntvalue._value[0])
def test_SetEntryValueEmptyName(storage_empty, outgoing): storage = storage_empty value = Value.makeBoolean(True) assert storage.setEntryValue("", value) assert len(storage.m_entries) == 0 assert len(storage.m_idmap) == 0 assert len(outgoing) == 0
def test_GetEntryValueExist(storage_empty, dispatcher, entry_notifier): storage = storage_empty value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) assert dispatcher._queueOutgoing.call_count == 1 assert entry_notifier.notifyEntry.call_count == 1 assert value == storage.getEntryValue("foo")
def forceSetValue(self, value): """Sets the entry's value :param value: the value that will be assigned .. warning:: Empty lists will fail """ value = Value.getFactory(value)(value) return self.__api.setEntryTypeValueById(self._local_id, value)
def test_DeleteCheckHandle(storage_populate_one, dispatcher, entry_notifier, is_server): storage = storage_populate_one handle = storage.getEntryId("foo") storage.deleteEntry("foo") storage.setEntryTypeValue("foo", Value.makeBoolean(True)) handle2 = storage.getEntryId("foo") assert handle == handle2
def set(self, name: str, value: NT_TYPES) -> None: # Calculated using Python type (bool, str, float) try: create_value_func: Callable[..., Value] = Value.getFactory(value) except ValueError as e: # getFactory raises ValueError when it should be raising TypeError raise TypeError(*e.args) nt_value: Value = create_value_func(value) self.api.setEntryTypeValue(self._get_path(name), nt_value)
def setDefaultValue(self, defaultValue): """Sets the entry's value if it does not exist. :param defaultValue: the default value to set :returns: False if the entry exists with a different type .. warning:: Do not set an empty list, it will fail """ value = Value.getFactory(defaultValue)(defaultValue) return self.__api.setDefaultEntryValueById(self._local_id, value)
def setValue(self, value): """Sets the entry's value :param value: the value that will be assigned :returns: False if the table key already exists with a different type .. warning:: Empty lists will fail """ value = Value.getFactory(value)(value) return self.__api.setEntryValueById(self._local_id, value)
def test_SetEntryValueEmptyName(storage_empty, dispatcher, entry_notifier): storage = storage_empty value = Value.makeBoolean(True) assert storage.setEntryValue("", value) assert len(storage.m_entries) == 0 assert len(storage.m_idmap) == 0 assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def test_ProcessIncomingEntryAssignIgnore(storage_populate_one, dispatcher, entry_notifier, is_server, conn): storage = storage_populate_one value = Value.makeDouble(1.0) storage.processIncoming(Message.entryAssign("foo", 0xffff, 1, value, 0), conn) assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def test_SetEntryTypeValueEqualValue(storage_populate_one, dispatcher, entry_notifier): storage = storage_populate_one # update with same type and same value: change value contents but no update # message is issued (minimizing bandwidth usage) value = Value.makeBoolean(True) storage.setEntryTypeValue("foo", value) assert value == storage.m_entries.get("foo").value assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def test_SetDefaultEntryExistsSameType(storage_populate_one, dispatcher, entry_notifier): storage = storage_populate_one # existing entry value = Value.makeBoolean(False) ret_val = storage.setDefaultEntryValue("foo", value) assert ret_val assert value != storage.m_entries.get("foo").value assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def storage_populate_one(storage_empty, dispatcher, entry_notifier): storage = storage_empty entry_notifier.m_local_notifiers = False storage.setEntryTypeValue("foo", Value.makeBoolean(True)) dispatcher.reset_mock() entry_notifier.reset_mock() entry_notifier.m_local_notifiers = True return storage
def test_SetEntryValueAssignTypeChange(storage_populate_one, dispatcher, entry_notifier): storage = storage_populate_one # update with different type results in error and no message value = Value.makeDouble(0.0) assert not storage.setEntryValue("foo", value) entry = storage.m_entries.get("foo") assert value != entry.value assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def test_empty_SetDefaultEntryEmptyName(storage_empty, dispatcher, entry_notifier): storage = storage_empty value = Value.makeBoolean(True) ret_val = storage.setDefaultEntryValue("", value) assert not ret_val assert "foo" not in storage.m_entries assert len(storage.m_entries) == 0 assert len(storage.m_idmap) == 0 assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def test_PrefixNewLocal(nt_live, server_cb): nt_server, nt_client = nt_live nt_server_api = nt_server._api nt_server_api.addEntryListener("/foo", server_cb, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL) # Trigger an event nt_server_api.setEntryValueById(nt_server_api.getEntryId("/foo/bar"), Value.makeDouble(1.0)) nt_server_api.setEntryValueById(nt_server_api.getEntryId("/baz"), Value.makeDouble(1.0)) assert nt_server_api.waitForEntryListenerQueue(1.0) events = server_cb.wait(1) #assert events[0].listener == handle assert events[0].local_id == nt_server_api.getEntryId("/foo/bar") assert events[0].name == "/foo/bar" assert events[0].value == Value.makeDouble(1.0) assert events[0].flags == NT_NOTIFY_NEW | NT_NOTIFY_LOCAL
def test_SetDefaultEntryExistsDifferentType(storage_populate_one, dispatcher, entry_notifier): storage = storage_populate_one # existing entry is boolean value = Value.makeDouble(2.0) ret_val = storage.setDefaultEntryValue("foo", value) assert not ret_val # should not have updated value in table if it already existed. assert value != storage.m_entries.get("foo").value assert dispatcher._queueOutgoing.call_count == 0 assert entry_notifier.notifyEntry.call_count == 0
def putBoolean(self, key, value): """Put a boolean in the table :param key: the key to be assigned to :type key: str :param value: the value that will be assigned :type value: bool :returns: False if the table key already exists with a different type :rtype: bool """ path = self._path + key return self._api.setEntryValue(path, Value.makeBoolean(value))
def putRaw(self, key, value): """Put a raw value (byte array) in the table :param key: the key to be assigned to :type key: str :param value: the value that will be assigned :type value: bytes :returns: False if the table key already exists with a different type :rtype: bool .. versionadded:: 2017.0.0 """ path = self._path + key return self._api.setEntryValue(path, Value.makeRaw(value))
def putStringArray(self, key, value): """Put a string array in the table :param key: the key to be assigned to :type key: str :param value: the value that will be assigned :type value: iterable(str) :returns: False if the table key already exists with a different type :rtype: bool .. versionadded:: 2017.0.0 """ path = self._path + key return self._api.setEntryValue(path, Value.makeStringArray(value))
def setDefaultBoolean(self, key, defaultValue): """If the key doesn't currently exist, then the specified value will be assigned to the key. :param key: the key to be assigned to :type key: str :param defaultValue: the default value to set if key doesn't exist. :type defaultValue: bool :returns: False if the table key exists with a different type .. versionadded:: 2017.0.0 """ path = self._path + key return self._api.setDefaultEntryValue(path, Value.makeBoolean(defaultValue))
def getGlobalAutoUpdateValue(cls, key, defaultValue, writeDefault): '''Global version of getAutoUpdateValue. This function will not initialize NetworkTables. :param key: the full NT path of the value (must start with /) :type key: str :param defaultValue: The default value to return if the key doesn't exist :type defaultValue: any :param writeDefault: If True, force the value to the specified default :type writeDefault: bool .. versionadded:: 2015.3.0 .. seealso:: :func:`.ntproperty` is a read-write alternative to this ''' assert key.startswith('/') # Use raw NT api to avoid having to initialize networktables value = None valuefn = None # optimization for ntproperty if not writeDefault: value = cls._api.getEntryValue(key) if value is None: valuefn = Value.getFactory(defaultValue) cls._api.setEntryValue(key, valuefn(defaultValue)) value = defaultValue elif not writeDefault: value = value.value valuefn = Value.getFactory(value) else: valuefn = Value.getFactory(value) return cls._api.createAutoValue(key, AutoUpdateValue(key, value, valuefn))
def test_PollPrefixBasic(notifier): poller = notifier.createPoller() g1 = notifier.addPolled(poller, "/foo", NT_NOTIFY_NEW) g2 = notifier.addPolled(poller, "/foo", NT_NOTIFY_DELETE) g3 = notifier.addPolled(poller, "/foo", NT_NOTIFY_UPDATE) g4 = notifier.addPolled(poller, "/foo", NT_NOTIFY_FLAGS) notifier.addPolled(poller, "/bar", NT_NOTIFY_NEW) notifier.addPolled(poller, "/bar", NT_NOTIFY_DELETE) notifier.addPolled(poller, "/bar", NT_NOTIFY_UPDATE) notifier.addPolled(poller, "/bar", NT_NOTIFY_FLAGS) assert not notifier.m_local_notifiers generateNotifications(notifier) assert notifier.waitForQueue(1.0) results, timed_out = notifier.poll(poller, 0) assert not timed_out g1count = 0 g2count = 0 g3count = 0 g4count = 0 for h, result in results: print(result) assert result.name.startswith("/foo") assert result.value == Value.makeDouble(1) if h == g1: g1count += 1 assert (result.flags & NT_NOTIFY_NEW) != 0 elif h == g2: g2count += 1 assert (result.flags & NT_NOTIFY_DELETE) != 0 elif h == g3: g3count += 1 assert (result.flags & NT_NOTIFY_UPDATE) != 0 elif h == g4: g4count += 1 assert (result.flags & NT_NOTIFY_FLAGS) != 0 else: assert False, "unknown listener index" assert g1count == 2 assert g2count == 1 # NT_NOTIFY_DELETE assert g3count == 2 assert g4count == 2