Skip to content

Instantly share code, notes, and snippets.

@alekssamos
Last active February 18, 2023 11:31
Show Gist options
  • Save alekssamos/d4c9f45a4a841df4a426ab0473872bb1 to your computer and use it in GitHub Desktop.
Save alekssamos/d4c9f45a4a841df4a426ab0473872bb1 to your computer and use it in GitHub Desktop.
How can I make a permanent (between restarts) set or any other object
from threading import Lock
import os, os.path
try:
import dill as pickle
import dill.settings
from dill import FILE_FMODE
dill.settings.update({'byref': True, 'fmode': FILE_FMODE, 'recurse': True, 'ignore': True})
except ImportError:
import pickle
class PersistentSet(set):
def __init__(self, setname, arg=()):
self.setname = setname
if len(arg):
super().__init__(arg)
self._load()
def _load(self):
if not os.path.isfile(self.setname) or os.path.getsize(self.setname) < 5:
return None
with open(self.setname, "rb") as f:
self.update(pickle.load(f))
def _dump(self):
with Lock():
with open(self.setname, "wb") as f:
pickle.dump(set(self), f)
os.fsync(f)
def add(self, arg):
super().add(pickle.loads(pickle.dumps(arg)))
self._dump()
def discard(self, arg):
super().discard(pickle.loads(pickle.dumps(arg)))
self._dump()
def update(self, arg):
super().update(pickle.loads(pickle.dumps(arg)))
self._dump()
def clear(self):
super().clear()
self._dump()
def pop(self):
r = super().pop()
self._dump()
return r
if __name__ == "__main__":
ps = PersistentSet("ps", (1,2,3))
ps.update((4,5,6))
for item in ps:
print(item)
ps.discard(5)
ps.pop()
ps.add(10)
assert len(ps) >= 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment