summaryrefslogtreecommitdiff
path: root/persistent.py
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2022-05-31 15:36:40 -0700
committerScott Gasch <[email protected]>2022-05-31 15:36:40 -0700
commit02302bbd9363facb59c4df2c1f4013087702cfa6 (patch)
tree938e51338678416afc891d2839c2ee8dd341f34d /persistent.py
parentf3dbc7dc19ba5703f8f5aa9bf8af3c491b3510f6 (diff)
Improve docstrings for sphinx.
Diffstat (limited to 'persistent.py')
-rw-r--r--persistent.py85
1 files changed, 56 insertions, 29 deletions
diff --git a/persistent.py b/persistent.py
index 0391144..808f955 100644
--- a/persistent.py
+++ b/persistent.py
@@ -2,8 +2,8 @@
# © Copyright 2021-2022, Scott Gasch
-"""A Persistent is just a class with a load and save method. This
-module defines the Persistent base and a decorator that can be used to
+"""A :class:Persistent is just a class with a load and save method. This
+module defines the :class:Persistent base and a decorator that can be used to
create a persistent singleton that autoloads and autosaves."""
import atexit
@@ -22,29 +22,27 @@ logger = logging.getLogger(__name__)
class Persistent(ABC):
"""
A base class of an object with a load/save method. Classes that are
- decorated with @persistent_autoloaded_singleton should subclass this
- and implement their save() and load() methods.
-
+ decorated with :code:`@persistent_autoloaded_singleton` should subclass
+ this and implement their :meth:`save` and :meth:`load` methods.
"""
@abstractmethod
def save(self) -> bool:
"""
Save this thing somewhere that you'll remember when someone calls
- load() later on in a way that makes sense to your code.
+ :meth:`load` later on in a way that makes sense to your code.
"""
pass
@classmethod
@abstractmethod
def load(cls) -> Any:
- """
- Load this thing from somewhere and give back an instance which
- will become the global singleton and which will may (see
- below) be save()d at program exit time.
+ """Load this thing from somewhere and give back an instance which
+ will become the global singleton and which may (see
+ below) be saved (via :meth:`save`) at program exit time.
- Oh, in case this is handy, here's how to write a factory
- method that doesn't call the c'tor in python::
+ Oh, in case this is handy, here's a reminder how to write a
+ factory method that doesn't call the c'tor in python::
@classmethod
def load_from_somewhere(cls, somewhere):
@@ -62,7 +60,13 @@ class Persistent(ABC):
def was_file_written_today(filename: str) -> bool:
- """Returns True if filename was written today.
+ """Convenience wrapper around was_file_written_within_n_seconds.
+
+ Args:
+ filename: filename to check
+
+ Returns:
+ True if filename was written today.
>>> import os
>>> filename = f'/tmp/testing_persistent_py_{os.getpid()}'
@@ -93,8 +97,15 @@ def was_file_written_within_n_seconds(
filename: str,
limit_seconds: int,
) -> bool:
- """Returns True if filename was written within the pas limit_seconds
- seconds.
+ """Helper for determining persisted state staleness.
+
+ Args:
+ filename: the filename to check
+ limit_seconds: how fresh, in seconds, it must be
+
+ Returns:
+ True if filename was written within the past limit_seconds
+ or False otherwise (or on error).
>>> import os
>>> filename = f'/tmp/testing_persistent_py_{os.getpid()}'
@@ -124,7 +135,14 @@ def was_file_written_within_n_seconds(
class PersistAtShutdown(enum.Enum):
"""
An enum to describe the conditions under which state is persisted
- to disk. See details below.
+ to disk. This is passed as an argument to the decorator below and
+ is used to indicate when to call :meth:save on a :class:Persistent
+ subclass.
+
+ * NEVER: never call :meth:save
+ * IF_NOT_LOADED: call :meth:save as long as we did not successfully
+ :meth:load its state.
+ * ALWAYS: always call :meth:save
"""
NEVER = (0,)
@@ -133,23 +151,32 @@ class PersistAtShutdown(enum.Enum):
class persistent_autoloaded_singleton(object):
- """A decorator that can be applied to a Persistent subclass (i.e. a
- class with a save() and load() method. It will intercept attempts
- to instantiate the class via it's c'tor and, instead, invoke the
- class' load() method to give it a chance to read state from
- somewhere persistent.
+ """A decorator that can be applied to a :class:Persistent subclass
+ (i.e. a class with :meth:save and :meth:load methods. The
+ decorator will intercept attempts to instantiate the class via
+ it's c'tor and, instead, invoke the class' :meth:load to give it a
+ chance to read state from somewhere persistent (disk, db,
+ whatever). Subsequent calls to construt instances of the wrapped
+ class will return a single, global instance (i.e. the wrapped
+ class is a singleton).
- If load() fails (returns None), the c'tor is invoked with the
+ If :meth:load fails (returns None), the c'tor is invoked with the
original args as a fallback.
- Based upon the value of the optional argument persist_at_shutdown,
- (NEVER, IF_NOT_LOADED, ALWAYS), the save() method of the class will
- be invoked just before program shutdown to give the class a chance
- to save its state somewhere.
+ Based upon the value of the optional argument
+ :code:`persist_at_shutdown` argument, (NEVER, IF_NOT_LOADED,
+ ALWAYS), the :meth:save method of the class will be invoked just
+ before program shutdown to give the class a chance to save its
+ state somewhere.
+
+ .. note::
+ The implementations of :meth:save and :meth:load and where the
+ class persists its state are details left to the :class:Persistent
+ implementation. Essentially this decorator just handles the
+ plumbing of calling your save/load and appropriate times and
+ creates a transparent global singleton whose state can be
+ persisted between runs.
- The implementations of save() and load() and where the class
- persists its state are details left to the Persistent
- implementation.
"""
def __init__(