diff --git a/src/hio/base/hier/boxing.py b/src/hio/base/hier/boxing.py index 785091fe..5da23240 100644 --- a/src/hio/base/hier/boxing.py +++ b/src/hio/base/hier/boxing.py @@ -31,35 +31,44 @@ # Regular expression to detect special need 'count' condition LAPSEREX = r'^\s*(?Plapse)(?P(\s|\W|\Z).*)' Rexlps = re.compile(LAPSEREX) # compile is faster -"""Usage: -if m := Rexlps.match("lapse >= 1.0"): - lps, cmp = m.group("lps","cmp") +"""Example usage. -if not Rexlps.match("lapse >= 1.0"): - return +Usage:: + + if m := Rexlps.match("lapse >= 1.0"): + lps, cmp = m.group("lps","cmp") + + if not Rexlps.match("lapse >= 1.0"): + return """ # Regular expression to detect special need 'count' condition RELAPSEREX = r'^\s*(?Prelapse)(?P(\s|\W|\Z).*)' Rexrlp = re.compile(RELAPSEREX) # compile is faster -"""Usage: -if m := Rexrlp.match("relapse >= 1.0"): - rel, cmp = m.group("rlp","cmp") +"""Example usage. + +Usage:: -if rel Rexrlp.match("relapse >= 1.0"): - return + if m := Rexrlp.match("relapse >= 1.0"): + rel, cmp = m.group("rlp","cmp") + + if rel Rexrlp.match("relapse >= 1.0"): + return """ # Regular expression to detect special need 'count' condition COUNTREX = r'^\s*(?Pcount)(?P(\s|\W|\Z).*)' Rexcnt = re.compile(COUNTREX) # compile is faster -"""Usage: -if m := Rexcnt.match("count >= 1"): - cnt, cmp = m.group("cnt","cmp") +"""Example usage. + +Usage:: -if not Rexcnt.match("count >= 1"): - return + if m := Rexcnt.match("count >= 1"): + cnt, cmp = m.group("cnt","cmp") + + if not Rexcnt.match("count >= 1"): + return """ @@ -83,7 +92,8 @@ class Box(Tymee): Box instance holds references (links) to its over box and its under boxes. Box instance holds the acts to be executed in their nabe. - Inherited Properties + Inherited Properties:: + .tyme (float | None): relative cycle time of associated Tymist which is provided by calling .tymth function wrapper closure which is obtained from Tymist.tymen(). @@ -93,7 +103,8 @@ class Box(Tymee): Tymist.tyme. Provides injected dependency on Tymist cycle tyme base. None means not assigned yet. - Attributes: + Attributes:: + hold (Hold): data shared by boxwork over (Box | None): this box's over box instance or None unders (list[Box]): this box's under box instances or empty @@ -109,7 +120,8 @@ class Box(Tymee): exacts (list[act]): exdo nabe acts rexacts (list[act]): rexdo (re-exdo) nabe acts (retained) - Properties: + Properties:: + name (str): unique identifier of instance pile (list[Box]): this box's pile of boxes generated by tracing .over up and .unders[0] down if any. This is generated lazily. @@ -118,7 +130,8 @@ class Box(Tymee): box names from .pile. This is generated lazily. To refresh call ._trace() - Hidden: + Hidden:: + _name (str): unique identifier of instance _pile (list[Box] | None): pile of Boxes to which this box belongs. None means not yet traced. @@ -138,12 +151,14 @@ class Box(Tymee): def __init__(self, *, name='box', hold=None, over=None, **kwa): """Initialize instance. - Inherited Parameters: + Inherited Parameters:: + tymth (closure): injected function wrapper closure returned by .tymen() of Tymist instance. Calling tymth() returns associated Tymist .tyme. - Parameters: + Parameters:: + name (str): unique identifier of box hold (None|Hold): data shared by boxwork over (Box | None): this box's over box instance or None @@ -208,7 +223,8 @@ def _trace(self): def name(self): """Property getter for ._name - Returns: + Returns:: + name (str): unique identifier of instance """ return self._name @@ -218,7 +234,8 @@ def name(self): def name(self, name): """Property setter for ._name - Parameters: + Parameters:: + name (str): unique identifier of instance """ if not Renam.match(name): @@ -230,7 +247,8 @@ def name(self, name): def pile(self): """Property getter for ._pile - Returns: + Returns:: + pile (list[Box]): this box's pile of boxes generated by tracing .over up and .unders[0] down if any. This is generated lazily to refresh call ._trace(). @@ -244,7 +262,8 @@ def pile(self): def spot(self): """Property getter for ._spot - Returns: + Returns:: + spot (int): zero based offset of this box into its pile of boxes generated by tracing .over up and .unders[0] down if any. This is generated lazily. To refresh call ._trace(). @@ -259,7 +278,8 @@ def spot(self): def trail(self): """Property getter for ._trail - Returns: + Returns:: + trail (str): human frieldly delimited string of box names from .pile. This is generated lazily. To refresh call ._trace(). Since pile always includes self, trail is always defined @@ -273,7 +293,8 @@ def trail(self): def predo(self): """Action predo nabe - Returns: + Returns:: + met (bool): True if all preconditions met, True if no preconditions False if any precondition not met """ @@ -330,7 +351,8 @@ class Boxer(Tymee): Box instance holds a reference to its first (beginning) box. Box instance holds references to all its boxes in dict keyed by box name. - Inherited Properties: (Tymee) + Inherited Properties: (Tymee):: + .tyme (float | None): relative cycle time of associated Tymist which is provided by calling .tymth function wrapper closure which is obtained from Tymist.tymen(). @@ -340,7 +362,8 @@ class Boxer(Tymee): Tymist.tyme. Provides injected dependency on Tymist cycle tyme base. None means not assigned yet. - Attributes: + Attributes:: + hold (Hold): data shared by boxwork fun (Callable): function to make boxwork boxes (dict): all boxes mapping of (box name, box) pairs @@ -348,10 +371,12 @@ class Boxer(Tymee): box (Box | None): active box durable (bool): default value for durable arg to .make - Properties: + Properties:: + name (str): unique identifier of instance - Hidden: + Hidden:: + _name (str): unique identifier of instance ._tymth is injected function wrapper closure returned by .tymen() of associated Tymist instance that returns Tymist .tyme. when called. @@ -361,12 +386,14 @@ class Boxer(Tymee): def __init__(self, *, name='boxer', hold=None, fun=None, durable=False, **kwa): """Initialize instance. - Inherited Parameters: + Inherited Parameters:: + tymth (closure): injected function wrapper closure returned by .tymen() of Tymist instance. Calling tymth() returns associated Tymist .tyme. - Parameters: + Parameters:: + name (str): unique identifier of box hold (None|Hold): data shared by boxwork fun (None|Callable): function to make boxwork @@ -390,7 +417,8 @@ def __init__(self, *, name='boxer', hold=None, fun=None, durable=False, **kwa): def name(self): """Property getter for ._name - Returns: + Returns:: + name (str): unique identifier of instance """ return self._name @@ -400,7 +428,8 @@ def name(self): def name(self, name): """Property setter for ._name - Parameters: + Parameters:: + name (str): unique identifier of instance """ if not Renam.match(name): @@ -413,7 +442,8 @@ def wind(self, tymth): Override in subclasses to update any dependencies on a change in tymist.tymth base - Parameters: + Parameters:: + tymth (Callable): closure of injected tyme from tymist.tymen() """ super().wind(tymth=tymth) @@ -427,7 +457,8 @@ def rewind(self, tymth=None): Changes tymist.tyme base when not None. Winds bags in .mine. When tymth is None then use .tymth - Parameters: + Parameters:: + tymth (Callable|None): closure of injected tyme from tymist.tymen() None if not yet injected """ @@ -441,7 +472,8 @@ def rewind(self, tymth=None): def run(self, tock=0.0): """Run boxer hierarchical state machine (boxwork) as generator. - Parameters: + Parameters:: + tock (float|None): creation of generator supplies tock as parameter. The doist tyme is delegated through 'yield from' delegations to the eventual target yield at bottom of 'yield from' delegation @@ -450,8 +482,9 @@ def run(self, tock=0.0): to run again ASAP (on next iteration of doist.do) - Returns: - completion (bool): completion state boxwork. + Returns:: + + completion (bool): completion state boxwork. True means completed successfully False completed unsuccessfully @@ -546,7 +579,8 @@ def endial(self): """Check for desire to end execution and return True otherwise False End condition if bag value at .hold['_boxer_boxername_end'].value == True - Returns: + Returns:: + end (bool): True means end condition satisfied False otherwise """ @@ -560,11 +594,13 @@ def endial(self): def predo(self, predos): """Evaluate preconditions for entry of boxes in endos in top down order - Parameters: + Parameters:: + predos (list[Box]): boxes to be predo (checked for entry) given all their preacts are satisfied - Returns: + Returns:: + met (bool): True means all preconditions are satisfied for predos False otherwise When no preconditions then returns True. @@ -583,7 +619,8 @@ def rendo(self, rendos): .rendos in top down order. Boxes retained in hierarchical state. Re-enter box - Parameters: + Parameters:: + rendos (list[Box]): boxes to be rendo (re-entered) """ for box in rendos: @@ -594,7 +631,8 @@ def endo(self, endos): """Action e-mark (emacts) and endo (enacts) acts of boxes in .endos in top down order. Enter box. - Parameters: + Parameters:: + endos (list[Box]): boxes to be endo (entered) """ @@ -610,7 +648,8 @@ def redo(self): def exdo(self, exdos): """Action exacts of boxes in exdos in bottom up order. Exit box. - Parameters: + Parameters:: + exdos (list[Box]): boxes to be exdo in bottom up order """ @@ -622,7 +661,8 @@ def rexdo(self, rexdos): """Action rexacts of boxes in rexdos (re-exdos) in bottom up order. Boxes retained in hierarchical state. Re-exit box. - Parameters: + Parameters:: + rexdos (list[Box]): boxes to be re-exdo in bottom up order """ for box in rexdos: @@ -670,11 +710,13 @@ def resolve(self): def make(self, fun=None, *, durable=None, temp=False): """Make box work for this boxer from function fun - Parameters: + Parameters:: + fun (Callable|None): employs be, go, do, on, at, be, verb functions with injected mods of boxwork state vars When None use self.fun Signature: + fun(H: (Hold), bx: (Callable), go: (Callable), @@ -722,7 +764,8 @@ def bx(self, name: None|str=None, over: None|str|Box="", first: bool=False, *, mods: WorkDom|None=None)->Box: """Make a box and add to box work - Parameters: + Parameters:: + name (None | str): when None then create name from bepre and beidx items in works. if non-empty string then use provided @@ -803,10 +846,12 @@ def go(self, dest: None|str=None, expr: None|str|Need=None, *, mods: WorkDom|None=None, **kwa)->Goact: """Make a Goact and add it to the tracts nabe of the current box. - Returns: + Returns:: + goact (Goact): newly created goact - Parameters: + Parameters:: + dest (None|str|Box): destination box its name for transition. When None use next box if any When str then resolve name to box if possible else save for @@ -862,7 +907,8 @@ def do(self, deed: None|str|Type[ActBase]|Callable=None, nabe=None, *, name: str|None=None, mods: WorkDom|None=None, **iops)->str: """Make an act and add to box work - Parameters: + Parameters:: + deed (None|str|Type[ActBase]|Callable): When None use Act with default lambda and iops as parameters When str name of class in ActBase registry. @@ -918,10 +964,12 @@ def on(self, cond: None|str=None, key: None|str=None, expr: None|str=None, Use inside go verb as need argument for special need condition Use inside do verb as deed argument for preact - Returns: + Returns:: + need (Need): newly created special need - Parameters: + Parameters:: + cond (None|str): special need condition to be satisfied. This is resolved in evalable boolean expression. When None then ignore @@ -944,6 +992,7 @@ def on(self, cond: None|str=None, key: None|str=None, expr: None|str=None, mods (None | WorkDom): state variables used to construct box work None is just to allow definition as keyword arg. Assumes that mods is always provided as WorkDom instance of form: + box (Box| None): current box in box work. None if not yet a box over (Box | None): current over Box in box work. None if top level bxpre (str): default box name prefix used to generate unique box name @@ -1104,7 +1153,8 @@ def on(self, cond: None|str=None, key: None|str=None, expr: None|str=None, def at(self, nabe: str=Nabes.native, *, mods: WorkDom|None=None)->str: """Make set mods.nabe to nabe - Parameters: + Parameters:: + nabe (str): action nabe (context) for mods. Defualt is native mods (None | WorkDom): state variables used to construct box work @@ -1125,15 +1175,18 @@ def be(self, lhs: str|tuple[str], rhs: None|str|Callable=None, nabe=None, *, """Make Beact instance that assigns mine bag at lhs to value from rhs. lhs is of form "key.field" rhs may be either a Callable or an evalable expression or None. - Resulting act performs on of: - H.key.field = None when rhs is None - H.key.field = eval(rhs) when rhs is evalable str - H.key.field = rhs(**parms) when rhs is callable + Resulting act performs one of:: + + H.key.field = None when rhs is None + H.key.field = eval(rhs) when rhs is evalable str + H.key.field = rhs(``**parms``) when rhs is callable + + Usage:: - Usage: be(lhs, rhs) - Parameters: + Parameters:: + lhs (str|tuple[str]): key.field in mine to be assigned. Resolves lhs to (key, field) rhs (None|str|Callable): @@ -1178,14 +1231,17 @@ def exen(near, far): """Computes the relative differences (uncommon and common parts) between the box pile lists nears passed in and fars from box far.pile - Parameters: + Parameters:: + near (Box): near box giving nears =near.pile in top down order far (Box): far box giving fars = far.pile in top down order. Assumes piles nears and fars are in top down order - Returns: - quadruple (tuple[list]): quadruple of lists of form: + Returns:: + + quadruple (tuple[list]): quadruple of lists of form:: + (exdos, endos, rendos, rexdos) where: exdos is list of uncommon boxes in nears but not in fars to be exited. Reversed to bottom up order. @@ -1201,9 +1257,9 @@ def exen(near, far): Supports forced reentry transitions when far is in nears. This means fars - == nears. In this case: - The common part of nears/fars from far down is force exited - The common part of nears/fars from far down is force entered + == nears. In this case: + The common part of nears/fars from far down is force exited + The common part of nears/fars from far down is force entered When far in nears then forced endo at far so far is nears[i] catches that case for forced endo at some far in nears. Since @@ -1219,9 +1275,9 @@ def exen(near, far): Two different topologies are accounted for with this code. Recall that python slice of list is zero based where: - fars[i] not in fars[:i] and fars[i] in fars[i:] - nears[i] not in nears[:i] and nears[i] in nears[i:] - this means fars[:0] == nears[:0] == [] empty list + fars[i] not in fars[:i] and fars[i] in fars[i:] + nears[i] not in nears[:i] and nears[i] in nears[i:] + this means fars[:0] == nears[:0] == [] empty list 1.0 near and far in same tree either on same branch or different branches 1.1 on same branch forced endo where nears == fars so far in nears. @@ -1256,25 +1312,29 @@ class Boxery(Mixin): multi-boxer boxworks Holds reference to current Boxer and Box being built - ****Placeholder for now. Future to be able to make multiple boxers from - single fun or in multiple iterations making.**** + Placeholder for now. Future: enable multiple boxers from a single fun or + across multiple iterations. + + Attributes:: - Attributes: hold (Hold): data shared by boxwork boxer (Boxer | None): current boxer box (Box | None): cureent box - Properties: + Properties:: + name (str): unique identifier of instance - Hidden: + Hidden:: + _name (str): unique identifier of instance """ def __init__(self, *, name='maker', hold=None, **kwa): """Initialize instance. - Parameters: + Parameters:: + name (str): unique identifier of instance hold (None|Hold): data shared by boxwork """ @@ -1288,7 +1348,8 @@ def __init__(self, *, name='maker', hold=None, **kwa): def name(self): """Property getter for ._name - Returns: + Returns:: + name (str): unique identifier of instance """ return self._name @@ -1298,7 +1359,8 @@ def name(self): def name(self, name): """Property setter for ._name - Parameters: + Parameters:: + name (str): unique identifier of instance """ if not Renam.match(name): @@ -1308,7 +1370,8 @@ def name(self, name): def make(self, fun, hold=None, boxes=None): """Make box work from function fun - Parameters: + Parameters:: + fun (function): employs be, do, on, go maker functions with globals hold (None|Hold): data shared by boxwork @@ -1336,13 +1399,15 @@ class BoxerDoer(Doer): .send(). - Inherited Attributes: + Inherited Attributes:: + done (bool | None): completion state: True means completed Otherwise incomplete. Incompletion maybe due to close or abort. opts (dict): injected options into its .do generator by scheduler temp (bool | None): use temporary file resources if any - Inherited Properties: + Inherited Properties:: + tyme (float): relative cycle time of associated Tymist .tyme obtained via injected .tymth function wrapper closure. tymth (closure): function wrapper closure returned by Tymist.tymen() method. @@ -1351,7 +1416,8 @@ class BoxerDoer(Doer): tock (float): desired time in seconds between runs or until next run, non negative, zero means run asap - Inherited Methods: + Inherited Methods:: + .wind injects ._tymth dependency from associated Tymist to get its .tyme .__call__ makes instance callable Appears as generator function that returns generator @@ -1362,13 +1428,16 @@ class BoxerDoer(Doer): .close is close context method .abort is abort context method - Attributes: + Attributes:: + boxer (Boxer): boxwork instance this doer runs - Overidden Methods: + Overidden Methods:: + .recur - Hidden: + Hidden:: + ._tymth is injected function wrapper closure returned by .tymen() of associated Tymist instance that returns Tymist .tyme. when called. ._tock is hidden attribute for .tock property @@ -1379,7 +1448,8 @@ def __init__(self, boxer, **kwa): """ Initialize instance. - Parameters: + Parameters:: + boxer (Boxer): instance of boxer to run """ @@ -1401,7 +1471,8 @@ def enter(self, *, temp=None): """Do 'enter' context actions. Not a generator method. Set up resources. Comparable to context manager enter. - Parameters: + Parameters:: + temp (bool | None): True means use temporary file resources if any None means ignore parameter value. Use self.temp @@ -1416,7 +1487,8 @@ def enter(self, *, temp=None): def recur(self, tock=None): """Do 'recur' context actions as a generator method. - Parameters: + Parameters:: + tock (float|None): this doer when creating this generator in recur section of its .do method supplies its .tock as this method's tock parameter. @@ -1426,8 +1498,9 @@ def recur(self, tock=None): run again ASAP (on next iteration of doist.do) - Returns: - completion (bool): completion state of recurrence actions. + Returns:: + + completion (bool): completion state of recurrence actions. True means completed successfully False completed unsuccessfully