class UnpairedException(Exception):
pass
class PairedConnections(dict):
def __init__(self, *args, **kwargs):
self.waiting = set() # сдесь хранятся соединения "в состоянии ожидания"
super().__init__(*args, **kwargs)
def __delitem__(self, key):
paired_key = self[key]
if paired_key is not None:
try:
super().__delitem__(paired_key)
except KeyError as e:
raise UnpairedException(f"Paired key {paired_key} not found")
else:
self.waiting.remove(key)
super().__delitem__(key)
def __setitem__(self, key, value):
if value is not None:
try:
self[value]
except KeyError as e:
raise UnpairedException(f"Connection {key}-{value} not paired")
super().__setitem__(value, key)
self.waiting.remove(key)
self.waiting.remove(value)
else:
self.waiting.add(key)
super().__setitem__(key, value)
# тест
if __name__ == "__main__":
conns = PairedConnections()
conns['one'] = None
conns['two'] = None
conns['three'] = None
print('1:', conns)
print('\t', conns.waiting)
conns['two'] = 'one'
print('2:', conns)
print('\t', conns.waiting)
del conns['one']
print('3:', conns)
print('\t', conns.waiting)
del conns['three']
print('4:', conns)
print('\t', conns.waiting)
# по идее ошибок возникать не должно
Y2xhc3MgVW5wYWlyZWRFeGNlcHRpb24oRXhjZXB0aW9uKToKICAgIHBhc3MKCgpjbGFzcyBQYWlyZWRDb25uZWN0aW9ucyhkaWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIHNlbGYud2FpdGluZyA9IHNldCgpICAjINGB0LTQtdGB0Ywg0YXRgNCw0L3Rj9GC0YHRjyDRgdC+0LXQtNC40L3QtdC90LjRjyAi0LIg0YHQvtGB0YLQvtGP0L3QuNC4INC+0LbQuNC00LDQvdC40Y8iCiAgICAgICAgc3VwZXIoKS5fX2luaXRfXygqYXJncywgKiprd2FyZ3MpCgogICAgZGVmIF9fZGVsaXRlbV9fKHNlbGYsIGtleSk6CiAgICAgICAgcGFpcmVkX2tleSA9IHNlbGZba2V5XQogICAgICAgIGlmIHBhaXJlZF9rZXkgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIHN1cGVyKCkuX19kZWxpdGVtX18ocGFpcmVkX2tleSkKICAgICAgICAgICAgZXhjZXB0IEtleUVycm9yIGFzIGU6CiAgICAgICAgICAgICAgICByYWlzZSBVbnBhaXJlZEV4Y2VwdGlvbihmIlBhaXJlZCBrZXkge3BhaXJlZF9rZXl9IG5vdCBmb3VuZCIpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53YWl0aW5nLnJlbW92ZShrZXkpCiAgICAgICAgc3VwZXIoKS5fX2RlbGl0ZW1fXyhrZXkpCgogICAgZGVmIF9fc2V0aXRlbV9fKHNlbGYsIGtleSwgdmFsdWUpOgogICAgICAgIGlmIHZhbHVlIGlzIG5vdCBOb25lOgogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICBzZWxmW3ZhbHVlXQogICAgICAgICAgICBleGNlcHQgS2V5RXJyb3IgYXMgZToKICAgICAgICAgICAgICAgIHJhaXNlIFVucGFpcmVkRXhjZXB0aW9uKGYiQ29ubmVjdGlvbiB7a2V5fS17dmFsdWV9IG5vdCBwYWlyZWQiKQogICAgICAgICAgICBzdXBlcigpLl9fc2V0aXRlbV9fKHZhbHVlLCBrZXkpCiAgICAgICAgICAgIHNlbGYud2FpdGluZy5yZW1vdmUoa2V5KQogICAgICAgICAgICBzZWxmLndhaXRpbmcucmVtb3ZlKHZhbHVlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud2FpdGluZy5hZGQoa2V5KQogICAgICAgIHN1cGVyKCkuX19zZXRpdGVtX18oa2V5LCB2YWx1ZSkKCiMg0YLQtdGB0YIKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKCWNvbm5zID0gUGFpcmVkQ29ubmVjdGlvbnMoKQoJY29ubnNbJ29uZSddID0gTm9uZQoJY29ubnNbJ3R3byddID0gTm9uZQoJY29ubnNbJ3RocmVlJ10gPSBOb25lCglwcmludCgnMTonLCBjb25ucykKCXByaW50KCdcdCcsIGNvbm5zLndhaXRpbmcpCgljb25uc1sndHdvJ10gPSAnb25lJwoJcHJpbnQoJzI6JywgY29ubnMpCglwcmludCgnXHQnLCBjb25ucy53YWl0aW5nKQoJZGVsIGNvbm5zWydvbmUnXQoJcHJpbnQoJzM6JywgY29ubnMpCglwcmludCgnXHQnLCBjb25ucy53YWl0aW5nKQoJZGVsIGNvbm5zWyd0aHJlZSddCglwcmludCgnNDonLCBjb25ucykKCXByaW50KCdcdCcsIGNvbm5zLndhaXRpbmcpCgkjINC/0L4g0LjQtNC10LUg0L7RiNC40LHQvtC6INCy0L7Qt9C90LjQutCw0YLRjCDQvdC1INC00L7Qu9C20L3Qvg==