|
|
|
|
@ -22,7 +22,7 @@
|
|
|
|
|
# SOFTWARE. |
|
|
|
|
import binascii |
|
|
|
|
import os, sys, re, json |
|
|
|
|
from collections import defaultdict |
|
|
|
|
from collections import defaultdict, OrderedDict |
|
|
|
|
from typing import NamedTuple, Union, TYPE_CHECKING, Tuple, Optional, Callable |
|
|
|
|
from datetime import datetime |
|
|
|
|
import decimal |
|
|
|
|
@ -993,3 +993,55 @@ def create_and_start_event_loop() -> Tuple[asyncio.AbstractEventLoop,
|
|
|
|
|
name='EventLoop') |
|
|
|
|
loop_thread.start() |
|
|
|
|
return loop, stopping_fut, loop_thread |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OrderedDictWithIndex(OrderedDict): |
|
|
|
|
"""An OrderedDict that keeps track of the positions of keys. |
|
|
|
|
|
|
|
|
|
Note: very inefficient to modify contents, except to add new items. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
_key_to_pos = {} |
|
|
|
|
|
|
|
|
|
def _recalc_key_to_pos(self): |
|
|
|
|
self._key_to_pos = {key: pos for (pos, key) in enumerate(self.keys())} |
|
|
|
|
|
|
|
|
|
def get_pos_of_key(self, key): |
|
|
|
|
return self._key_to_pos[key] |
|
|
|
|
|
|
|
|
|
def popitem(self, *args, **kwargs): |
|
|
|
|
ret = super().popitem(*args, **kwargs) |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def move_to_end(self, *args, **kwargs): |
|
|
|
|
ret = super().move_to_end(*args, **kwargs) |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def clear(self): |
|
|
|
|
ret = super().clear() |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def pop(self, *args, **kwargs): |
|
|
|
|
ret = super().pop(*args, **kwargs) |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def update(self, *args, **kwargs): |
|
|
|
|
ret = super().update(*args, **kwargs) |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def __delitem__(self, *args, **kwargs): |
|
|
|
|
ret = super().__delitem__(*args, **kwargs) |
|
|
|
|
self._recalc_key_to_pos() |
|
|
|
|
return ret |
|
|
|
|
|
|
|
|
|
def __setitem__(self, key, *args, **kwargs): |
|
|
|
|
is_new_key = key not in self |
|
|
|
|
ret = super().__setitem__(key, *args, **kwargs) |
|
|
|
|
if is_new_key: |
|
|
|
|
self._key_to_pos[key] = len(self) - 1 |
|
|
|
|
return ret |
|
|
|
|
|