Source code for doot.util.dkey

  1#!/usr/bin/env python3
  2"""
  3
  4"""
  5
  6# Imports:
  7from __future__ import annotations
  8
  9# ##-- stdlib imports
 10import datetime
 11import enum
 12import functools as ftz
 13import itertools as itz
 14import logging as logmod
 15import pathlib as pl
 16import re
 17import string
 18import time
 19import types
 20import weakref
 21from uuid import UUID, uuid1
 22
 23# ##-- end stdlib imports
 24
 25# ##-- 3rd party imports
 26from pydantic import BaseModel, Field, field_validator, model_validator
 27from jgdv.decorators import DecoratorAccessor_m
 28from jgdv.structs.chainguard import ChainGuard
 29from jgdv.structs.strang import CodeReference
 30from jgdv.structs.dkey import DKey, DKeyMark_e, SingleDKey, MultiDKey, NonDKey, DKeyExpansionDecorator
 31from jgdv.structs.dkey import DKeyed
 32from jgdv.structs.dkey import ExpInst_d
 33from jgdv._abstract.protocols.general import SpecStruct_p, Buildable_p
 34# ##-- end 3rd party imports
 35
 36# ##-- 1st party imports
 37import doot
 38import doot.errors
 39from doot.workflow.structs.task_name import TaskName
 40
 41# ##-- end 1st party imports
 42
 43# ##-- types
 44# isort: off
 45import abc
 46import collections.abc
 47from typing import TYPE_CHECKING, Generic, cast, assert_type, assert_never
 48# Protocols:
 49from typing import Protocol, runtime_checkable
 50# Typing Decorators:
 51from typing import no_type_check, final, override, overload
 52
 53if TYPE_CHECKING:
 54   from jgdv import Maybe, Ident, Method, Func, Decorator
 55   from typing import Final
 56   from typing import ClassVar, Any, LiteralString
 57   from typing import Never, Self, Literal
 58   from typing import TypeGuard
 59   from collections.abc import Iterable, Iterator, Callable, Generator
 60   from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 61
 62   from jgdv.structs.dkey import Key_p
 63   from jgdv.structs.dkey._util._interface import SourceChain_d, InstructionFactory_p, ExpOpts, ExpInstChain_d
 64
 65# isort: on
 66# ##-- end types
 67
 68##-- logging
 69logging = logmod.getLogger(__name__)
 70##-- end logging
 71
 72##--| Vars
 73STATE_TASK_NAME_K = doot.constants.patterns.STATE_TASK_NAME_K # type: ignore[attr-defined]
 74##--|
 75
[docs] 76class TaskNameDKey(DKey, mark=TaskName, convert="t"): 77 __slots__ = () 78 79 def __init__(self, *args:Any, **kwargs:Any) -> None: 80 super().__init__(*args, **kwargs) 81 self.data.expansion_type = TaskName 82 self.data.typecheck = TaskName
83
[docs] 84class DootPathDKey(DKey[pl.Path], mark=pl.Path, ctor=pl.Path, convert="p", overwrite=True): 85 """ 86 A MultiKey that always expands as a path, 87 eg: `{temp}/{name}.log` 88 """ 89 __slots__ = ("_relative",) 90 _extra_kwargs : ClassVar[set[str]] = {"relative"} 91 92 def __init__(self, *args:Any, **kwargs:Any) -> None: 93 super().__init__(*args, **kwargs) 94 self.data.expansion_type = pl.Path 95 self.data.typecheck = pl.Path 96 self._relative = kwargs.get('relative', False) 97
[docs] 98 def _multi(self) -> Literal[True]: 99 return True
100
[docs] 101 def exp_extra_sources_h(self, current:SourceChain_d) -> SourceChain_d: 102 return current.extend(doot.locs.Current)
103
[docs] 104 def exp_final_h(self, inst:ExpInst_d, root:Maybe[ExpInst_d], factory:InstructionFactory_p, opts:dict) -> Maybe[ExpInst_d]: 105 relative = opts.get("relative", False) 106 match inst: 107 case ExpInst_d(value=pl.Path() as x) if relative and x.is_absolute(): 108 as_relative = x.relative_to(doot.locs.root) 109 return factory.literal_inst(as_relative) 110 case ExpInst_d(value=pl.Path()) as x if relative: 111 return x 112 case ExpInst_d(value=pl.Path() as x) as v: 113 logging.debug("Normalizing Single Path Key: %s", x) 114 normed = doot.locs.Current.normalize(x) # type: ignore[attr-defined] 115 return factory.literal_inst(normed) 116 case x: 117 raise TypeError("Path Expansion did not produce a path", x)
118
[docs] 119class DootKeyed(DecoratorAccessor_m, DKeyed): 120 """ Extends jgdv.structs.dkey.DKeyed to handle additional decoration types 121 specific for doot 122 """ 123 _decoration_builder : ClassVar[type] = DKeyExpansionDecorator 124
[docs] 125 @classmethod 126 def taskname(cls, fn:Callable) -> Decorator: 127 keys = [DKey[TaskName](STATE_TASK_NAME_K, implicit=True)] 128 dec = cls._build_decorator(keys) 129 result = dec(fn) 130 return result