@parallelize(method=Method.PROCESS)
def my_other_function(d, e, f) -> str:
- ...do more really expensice work, e.g., a network read
+ ...do more really expensive work, e.g., a network read
@parallelize(method=Method.REMOTE)
def my_other_other_function(g, h) -> int:
# © Copyright 2021-2022, Scott Gasch
-"""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
+"""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
def was_file_written_today(filename: str) -> bool:
- """Convenience wrapper around was_file_written_within_n_seconds.
+ """Convenience wrapper around :meth:`was_file_written_within_n_seconds`.
Args:
filename: filename to check
"""
An enum to describe the conditions under which state is persisted
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
+ 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: 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,)
class persistent_autoloaded_singleton(object):
- """A decorator that can be applied to a :class:Persistent subclass
- (i.e. a class with :meth:save and :meth:load methods. The
+ """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
+ 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 :meth: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
:code:`persist_at_shutdown` argument, (NEVER, IF_NOT_LOADED,
- ALWAYS), the :meth:save method of the class will be invoked just
+ 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
+ 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
"""The set of information specific to where the program is running."""
location_name: str
+ """Either "HOUSE" or "CABIN" depending on where we're running"""
+
location: Location
+ """Same as above but as an enum value instead of a string"""
+
network: str
+ """The local network specification, e.g. 192.168.0.0/24."""
+
network_netmask: str
+ """The netmask of the local network, e.g. 255.255.255.0."""
+
network_router_ip: str
+ """The IP address of the local router, e.g. 192.168.0.1."""
+
presence_location: Location
+ """Same as location, above."""
+
is_anyone_present: Callable
+ """Returns a callable which, when invoked, will tell you if it detects
+ any person in your location by auditing network device MAC addresses."""
+
arper_minimum_device_count: int
+ """How many MAC addresses do we need to see for it to be considered a
+ successful scan?"""
+
arper_cache_file: str
+ """The location of the persisted IP-MAC address mappings."""
-def get_location_name():
+def get_location_name() -> str:
"""
Where are we?
return get_config().location_name
-def get_location():
+def get_location() -> Location:
"""
Returns location as an enum instead of a string.
return get_config().location
-def is_anyone_present_wrapper(location: Location):
+def _is_anyone_present_wrapper(location: Location):
import base_presence
p = base_presence.PresenceDetection()
network_netmask='255.255.255.0',
network_router_ip='10.0.0.1',
presence_location=Location.HOUSE,
- is_anyone_present=lambda x=Location.HOUSE: is_anyone_present_wrapper(x),
+ is_anyone_present=lambda x=Location.HOUSE: _is_anyone_present_wrapper(x),
arper_minimum_device_count=50,
arper_cache_file='/home/scott/cache/.arp_table_cache_house',
)
network_netmask='255.255.255.0',
network_router_ip='192.168.0.1',
presence_location=Location.CABIN,
- is_anyone_present=lambda x=Location.CABIN: is_anyone_present_wrapper(x),
+ is_anyone_present=lambda x=Location.CABIN: _is_anyone_present_wrapper(x),
arper_minimum_device_count=15,
arper_cache_file='/home/scott/cache/.arp_table_cache_cabin',
)
# © Copyright 2021-2022, Scott Gasch
-"""A :class:Future that can be treated as a substutute for the result
+"""A :class:`Future` that can be treated as a substutute for the result
that it contains and will not block until it is used. At that point,
if the underlying value is not yet available yet, it will block until
the internal result actually becomes available.
# © Copyright 2021-2022, Scott Gasch
"""Several helpers to keep track of internal state via periodic
-polling. :class:StateTracker expects to be invoked periodically to
-maintain state whereas the others (:class:AutomaticStateTracker and
-:class:WaitableAutomaticStateTracker) automatically update themselves
+polling. :class:`StateTracker` expects to be invoked periodically to
+maintain state whereas the others (:class:`AutomaticStateTracker` and
+:class:`WaitableAutomaticStateTracker`) automatically update themselves
and, optionally, expose an event for client code to wait on state
changes.
"""
Args:
update_id: the string you passed to the c'tor as a key in
- the update_ids_to_update_secs dict. :meth:update will
+ the update_ids_to_update_secs dict. :meth:`update` will
only be invoked on the shoulder, at most, every update_secs
seconds.
def heartbeat(self, *, force_all_updates_to_run: bool = False) -> None:
"""Invoke this method to cause the StateTracker instance to identify
and invoke any overdue updates based on the schedule passed to
- the c'tor. In the base :class:StateTracker class, this method must
+ the c'tor. In the base :class:`StateTracker` class, this method must
be invoked manually by a thread from external code. Other subclasses
are available that create their own updater threads (see below).
class AutomaticStateTracker(StateTracker):
- """Just like :class:StateTracker but you don't need to pump the
- :meth:heartbeat method periodically because we create a background
- thread that manages periodic calling. You must call :meth:shutdown,
+ """Just like :class:`StateTracker` but you don't need to pump the
+ :meth:`heartbeat` method periodically because we create a background
+ thread that manages periodic calling. You must call :meth:`shutdown`,
though, in order to terminate the update thread.
"""
@background_thread
def pace_maker(self, should_terminate: threading.Event) -> None:
- """Entry point for a background thread to own calling :meth:heartbeat
+ """Entry point for a background thread to own calling :meth:`heartbeat`
at regular intervals so that the main thread doesn't need to
do so.
"""
override_sleep_delay: By default, this class determines
how long the background thread should sleep between
- automatic invocations to :meth:heartbeat based on the
+ automatic invocations to :meth:`heartbeat` based on the
period of each update type in update_ids_to_update_secs.
If this argument is non-None, it overrides this computation
and uses this period as the sleep in the background thread.
override_sleep_delay: By default, this class determines
how long the background thread should sleep between
- automatic invocations to :meth:heartbeat based on the
+ automatic invocations to :meth:`heartbeat` based on the
period of each update type in update_ids_to_update_secs.
If this argument is non-None, it overrides this computation
and uses this period as the sleep in the background thread.
def ngrams_presplit(words: Sequence[str], n: int):
"""
- Same as :meth:ngrams but with the string pre-split.
+ Same as :meth:`ngrams` but with the string pre-split.
"""
return list_utils.ngrams(words, n)
def generate_padded_columns(text: List[str]) -> Generator:
- """Given a list of strings, break them into columns using :meth:split
+ """Given a list of strings, break them into columns using :meth:`split`
and then compute the maximum width of each column. Finally,
distribute the columular chunks into the output padding each to
the proper width.
call forever
Returns:
- a :class:Thread object and an :class:Event that, when
+ a :class:`Thread` object and an :class:`Event` that, when
signaled, will stop the invocations.
.. note::
- It is possible to be invoked one time after the :class:Event
+ It is possible to be invoked one time after the :class:`Event`
is set. This event can be used to stop infinite
invocation style or finite invocation style decorations.