ddeutil-workflow 0.0.46__py3-none-any.whl → 0.0.48__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ddeutil/workflow/logs.py CHANGED
@@ -9,33 +9,65 @@
9
9
  from __future__ import annotations
10
10
 
11
11
  import json
12
+ import logging
12
13
  import os
13
14
  from abc import ABC, abstractmethod
14
15
  from collections.abc import Iterator
16
+ from dataclasses import field
15
17
  from datetime import datetime
18
+ from functools import lru_cache
16
19
  from inspect import Traceback, currentframe, getframeinfo
17
20
  from pathlib import Path
18
21
  from threading import get_ident
19
22
  from typing import ClassVar, Literal, Optional, Union
20
23
 
21
- from pydantic import BaseModel, Field
24
+ from pydantic import BaseModel, Field, ValidationInfo
22
25
  from pydantic.dataclasses import dataclass
23
26
  from pydantic.functional_validators import model_validator
24
27
  from typing_extensions import Self
25
28
 
26
29
  from .__types import DictData, DictStr, TupleStr
27
- from .conf import config, get_logger
30
+ from .conf import config, dynamic
28
31
  from .utils import cut_id, get_dt_now
29
32
 
33
+
34
+ @lru_cache
35
+ def get_logger(name: str):
36
+ """Return logger object with an input module name.
37
+
38
+ :param name: A module name that want to log.
39
+ """
40
+ lg = logging.getLogger(name)
41
+
42
+ # NOTE: Developers using this package can then disable all logging just for
43
+ # this package by;
44
+ #
45
+ # `logging.getLogger('ddeutil.workflow').propagate = False`
46
+ #
47
+ lg.addHandler(logging.NullHandler())
48
+
49
+ formatter = logging.Formatter(
50
+ fmt=config.log_format,
51
+ datefmt=config.log_datetime_format,
52
+ )
53
+ stream = logging.StreamHandler()
54
+ stream.setFormatter(formatter)
55
+ lg.addHandler(stream)
56
+
57
+ lg.setLevel(logging.DEBUG if config.debug else logging.INFO)
58
+ return lg
59
+
60
+
30
61
  logger = get_logger("ddeutil.workflow")
31
62
 
32
63
  __all__: TupleStr = (
33
64
  "FileTraceLog",
34
65
  "SQLiteTraceLog",
35
66
  "TraceData",
36
- "TraceMeda",
67
+ "TraceMeta",
37
68
  "TraceLog",
38
69
  "get_dt_tznow",
70
+ "get_logger",
39
71
  "get_trace",
40
72
  "get_trace_obj",
41
73
  "get_audit",
@@ -53,7 +85,9 @@ def get_dt_tznow() -> datetime: # pragma: no cov
53
85
  return get_dt_now(tz=config.tz)
54
86
 
55
87
 
56
- class TraceMeda(BaseModel): # pragma: no cov
88
+ class TraceMeta(BaseModel): # pragma: no cov
89
+ """Trace Meta model."""
90
+
57
91
  mode: Literal["stdout", "stderr"]
58
92
  datetime: str
59
93
  process: int
@@ -63,14 +97,28 @@ class TraceMeda(BaseModel): # pragma: no cov
63
97
  lineno: int
64
98
 
65
99
  @classmethod
66
- def make(cls, mode: Literal["stdout", "stderr"], message: str) -> Self:
67
- """Make a TraceMeda instance."""
100
+ def make(
101
+ cls,
102
+ mode: Literal["stdout", "stderr"],
103
+ message: str,
104
+ *,
105
+ extras: Optional[DictData] = None,
106
+ ) -> Self:
107
+ """Make the current TraceMeta instance that catching local state.
108
+
109
+ :rtype: Self
110
+ """
68
111
  frame_info: Traceback = getframeinfo(
69
112
  currentframe().f_back.f_back.f_back
70
113
  )
114
+ extras: DictData = extras or {}
71
115
  return cls(
72
116
  mode=mode,
73
- datetime=get_dt_tznow().strftime(config.log_datetime_format),
117
+ datetime=(
118
+ get_dt_now(tz=dynamic("tz", extras=extras)).strftime(
119
+ dynamic("log_datetime_format", extras=extras)
120
+ )
121
+ ),
74
122
  process=os.getpid(),
75
123
  thread=get_ident(),
76
124
  message=message,
@@ -84,7 +132,7 @@ class TraceData(BaseModel): # pragma: no cov
84
132
 
85
133
  stdout: str = Field(description="A standard output trace data.")
86
134
  stderr: str = Field(description="A standard error trace data.")
87
- meta: list[TraceMeda] = Field(
135
+ meta: list[TraceMeta] = Field(
88
136
  default_factory=list,
89
137
  description=(
90
138
  "A metadata mapping of this output and error before making it to "
@@ -126,7 +174,8 @@ class BaseTraceLog(ABC): # pragma: no cov
126
174
  """Base Trace Log dataclass object."""
127
175
 
128
176
  run_id: str
129
- parent_run_id: Optional[str] = None
177
+ parent_run_id: Optional[str] = field(default=None)
178
+ extras: DictData = field(default_factory=dict, compare=False, repr=False)
130
179
 
131
180
  @abstractmethod
132
181
  def writer(self, message: str, is_err: bool = False) -> None:
@@ -148,6 +197,9 @@ class BaseTraceLog(ABC): # pragma: no cov
148
197
  :param message:
149
198
  :param is_err:
150
199
  """
200
+ raise NotImplementedError(
201
+ "Create async writer logic for this trace object before using."
202
+ )
151
203
 
152
204
  @abstractmethod
153
205
  def make_message(self, message: str) -> str:
@@ -169,7 +221,7 @@ class BaseTraceLog(ABC): # pragma: no cov
169
221
  """
170
222
  msg: str = self.make_message(message)
171
223
 
172
- if config.debug:
224
+ if dynamic("debug", extras=self.extras):
173
225
  self.writer(msg)
174
226
 
175
227
  logger.debug(msg, stacklevel=2)
@@ -221,7 +273,7 @@ class BaseTraceLog(ABC): # pragma: no cov
221
273
  :param message: (str) A message that want to log.
222
274
  """
223
275
  msg: str = self.make_message(message)
224
- if config.debug:
276
+ if dynamic("debug", extras=self.extras):
225
277
  await self.awriter(msg)
226
278
  logger.info(msg, stacklevel=2)
227
279
 
@@ -271,21 +323,38 @@ class FileTraceLog(BaseTraceLog): # pragma: no cov
271
323
 
272
324
  @classmethod
273
325
  def find_logs(
274
- cls, path: Path | None = None
326
+ cls,
327
+ path: Path | None = None,
328
+ extras: Optional[DictData] = None,
275
329
  ) -> Iterator[TraceData]: # pragma: no cov
276
- """Find trace logs."""
330
+ """Find trace logs.
331
+
332
+ :param path: (Path)
333
+ :param extras: An extra parameter that want to override core config.
334
+ """
277
335
  for file in sorted(
278
- (path or config.log_path).glob("./run_id=*"),
336
+ (path or dynamic("log_path", extras=extras)).glob("./run_id=*"),
279
337
  key=lambda f: f.lstat().st_mtime,
280
338
  ):
281
339
  yield TraceData.from_path(file)
282
340
 
283
341
  @classmethod
284
342
  def find_log_with_id(
285
- cls, run_id: str, force_raise: bool = True, *, path: Path | None = None
343
+ cls,
344
+ run_id: str,
345
+ force_raise: bool = True,
346
+ *,
347
+ path: Path | None = None,
348
+ extras: Optional[DictData] = None,
286
349
  ) -> TraceData:
287
- """Find trace log with an input specific run ID."""
288
- base_path: Path = path or config.log_path
350
+ """Find trace log with an input specific run ID.
351
+
352
+ :param run_id: A running ID of trace log.
353
+ :param force_raise:
354
+ :param path:
355
+ :param extras: An extra parameter that want to override core config.
356
+ """
357
+ base_path: Path = path or dynamic("log_path", extras=extras)
289
358
  file: Path = base_path / f"run_id={run_id}"
290
359
  if file.exists():
291
360
  return TraceData.from_path(file)
@@ -299,7 +368,8 @@ class FileTraceLog(BaseTraceLog): # pragma: no cov
299
368
  @property
300
369
  def pointer(self) -> Path:
301
370
  log_file: Path = (
302
- config.log_path / f"run_id={self.parent_run_id or self.run_id}"
371
+ dynamic("log_path", extras=self.extras)
372
+ / f"run_id={self.parent_run_id or self.run_id}"
303
373
  )
304
374
  if not log_file.exists():
305
375
  log_file.mkdir(parents=True)
@@ -340,18 +410,17 @@ class FileTraceLog(BaseTraceLog): # pragma: no cov
340
410
  :param message: A message after making.
341
411
  :param is_err: A flag for writing with an error trace or not.
342
412
  """
343
- if not config.enable_write_log:
413
+ if not dynamic("enable_write_log", extras=self.extras):
344
414
  return
345
415
 
346
416
  write_file: str = "stderr" if is_err else "stdout"
347
- trace_meta: TraceMeda = TraceMeda.make(mode=write_file, message=message)
417
+ trace_meta: TraceMeta = TraceMeta.make(mode=write_file, message=message)
348
418
 
349
419
  with (self.pointer / f"{write_file}.txt").open(
350
420
  mode="at", encoding="utf-8"
351
421
  ) as f:
352
- f.write(
353
- f"{config.log_format_file}\n".format(**trace_meta.model_dump())
354
- )
422
+ fmt: str = dynamic("log_format_file", extras=self.extras)
423
+ f.write(f"{fmt}\n".format(**trace_meta.model_dump()))
355
424
 
356
425
  with (self.pointer / "metadata.json").open(
357
426
  mode="at", encoding="utf-8"
@@ -361,7 +430,7 @@ class FileTraceLog(BaseTraceLog): # pragma: no cov
361
430
  async def awriter(
362
431
  self, message: str, is_err: bool = False
363
432
  ) -> None: # pragma: no cov
364
- if not config.enable_write_log:
433
+ if not dynamic("enable_write_log", extras=self.extras):
365
434
  return
366
435
 
367
436
  try:
@@ -370,14 +439,13 @@ class FileTraceLog(BaseTraceLog): # pragma: no cov
370
439
  raise ImportError("Async mode need aiofiles package") from e
371
440
 
372
441
  write_file: str = "stderr" if is_err else "stdout"
373
- trace_meta: TraceMeda = TraceMeda.make(mode=write_file, message=message)
442
+ trace_meta: TraceMeta = TraceMeta.make(mode=write_file, message=message)
374
443
 
375
444
  async with aiofiles.open(
376
445
  self.pointer / f"{write_file}.txt", mode="at", encoding="utf-8"
377
446
  ) as f:
378
- await f.write(
379
- f"{config.log_format_file}\n".format(**trace_meta.model_dump())
380
- )
447
+ fmt: str = dynamic("log_format_file", extras=self.extras)
448
+ await f.write(f"{fmt}\n".format(**trace_meta.model_dump()))
381
449
 
382
450
  async with aiofiles.open(
383
451
  self.pointer / "metadata.json", mode="at", encoding="utf-8"
@@ -419,16 +487,38 @@ TraceLog = Union[
419
487
 
420
488
 
421
489
  def get_trace(
422
- run_id: str, parent_run_id: str | None = None
490
+ run_id: str,
491
+ parent_run_id: str | None = None,
492
+ *,
493
+ extras: Optional[DictData] = None,
423
494
  ) -> TraceLog: # pragma: no cov
424
- """Get dynamic TraceLog object from the setting config."""
425
- if config.log_path.is_file():
426
- return SQLiteTraceLog(run_id, parent_run_id=parent_run_id)
427
- return FileTraceLog(run_id, parent_run_id=parent_run_id)
495
+ """Get dynamic TraceLog object from the setting config.
496
+
497
+ :param run_id: A running ID.
498
+ :param parent_run_id: A parent running ID.
499
+ :param extras: An extra parameter that want to override the core config.
500
+
501
+ :rtype: TraceLog
502
+ """
503
+ if dynamic("log_path", extras=extras).is_file():
504
+ return SQLiteTraceLog(
505
+ run_id, parent_run_id=parent_run_id, extras=(extras or {})
506
+ )
507
+ return FileTraceLog(
508
+ run_id, parent_run_id=parent_run_id, extras=(extras or {})
509
+ )
510
+
511
+
512
+ def get_trace_obj(
513
+ extras: Optional[DictData] = None,
514
+ ) -> type[TraceLog]: # pragma: no cov
515
+ """Get trace object.
428
516
 
517
+ :param extras: An extra parameter that want to override the core config.
429
518
 
430
- def get_trace_obj() -> type[TraceLog]: # pragma: no cov
431
- if config.log_path.is_file():
519
+ :rtype: type[TraceLog]
520
+ """
521
+ if dynamic("log_path", extras=extras).is_file():
432
522
  return SQLiteTraceLog
433
523
  return FileTraceLog
434
524
 
@@ -439,6 +529,10 @@ class BaseAudit(BaseModel, ABC):
439
529
  subclass like file, sqlite, etc.
440
530
  """
441
531
 
532
+ extras: DictData = Field(
533
+ default_factory=dict,
534
+ description="An extras parameter that want to override core config",
535
+ )
442
536
  name: str = Field(description="A workflow name.")
443
537
  release: datetime = Field(description="A release datetime.")
444
538
  type: str = Field(description="A running type before logging.")
@@ -454,12 +548,12 @@ class BaseAudit(BaseModel, ABC):
454
548
  execution_time: float = Field(default=0, description="An execution time.")
455
549
 
456
550
  @model_validator(mode="after")
457
- def __model_action(self) -> Self:
551
+ def __model_action(self, info: ValidationInfo) -> Self:
458
552
  """Do before the Audit action with WORKFLOW_AUDIT_ENABLE_WRITE env variable.
459
553
 
460
554
  :rtype: Self
461
555
  """
462
- if config.enable_write_audit:
556
+ if dynamic("enable_write_audit", extras=info.data.get("extras")):
463
557
  self.do_before()
464
558
  return self
465
559
 
@@ -487,15 +581,20 @@ class FileAudit(BaseAudit):
487
581
  self.pointer().mkdir(parents=True, exist_ok=True)
488
582
 
489
583
  @classmethod
490
- def find_audits(cls, name: str) -> Iterator[Self]:
584
+ def find_audits(
585
+ cls, name: str, *, extras: Optional[DictData] = None
586
+ ) -> Iterator[Self]:
491
587
  """Generate the audit data that found from logs path with specific a
492
588
  workflow name.
493
589
 
494
590
  :param name: A workflow name that want to search release logging data.
591
+ :param extras: An extra parameter that want to override core config.
495
592
 
496
593
  :rtype: Iterator[Self]
497
594
  """
498
- pointer: Path = config.audit_path / f"workflow={name}"
595
+ pointer: Path = (
596
+ dynamic("audit_path", extras=extras) / f"workflow={name}"
597
+ )
499
598
  if not pointer.exists():
500
599
  raise FileNotFoundError(f"Pointer: {pointer.absolute()}.")
501
600
 
@@ -508,13 +607,16 @@ class FileAudit(BaseAudit):
508
607
  cls,
509
608
  name: str,
510
609
  release: datetime | None = None,
610
+ *,
611
+ extras: Optional[DictData] = None,
511
612
  ) -> Self:
512
613
  """Return the audit data that found from logs path with specific
513
614
  workflow name and release values. If a release does not pass to an input
514
615
  argument, it will return the latest release from the current log path.
515
616
 
516
- :param name: A workflow name that want to search log.
517
- :param release: A release datetime that want to search log.
617
+ :param name: (str) A workflow name that want to search log.
618
+ :param release: (datetime) A release datetime that want to search log.
619
+ :param extras: An extra parameter that want to override core config.
518
620
 
519
621
  :raise FileNotFoundError:
520
622
  :raise NotImplementedError: If an input release does not pass to this
@@ -526,7 +628,7 @@ class FileAudit(BaseAudit):
526
628
  raise NotImplementedError("Find latest log does not implement yet.")
527
629
 
528
630
  pointer: Path = (
529
- config.audit_path
631
+ dynamic("audit_path", extras=extras)
530
632
  / f"workflow={name}/release={release:%Y%m%d%H%M%S}"
531
633
  )
532
634
  if not pointer.exists():
@@ -540,24 +642,31 @@ class FileAudit(BaseAudit):
540
642
  return cls.model_validate(obj=json.load(f))
541
643
 
542
644
  @classmethod
543
- def is_pointed(cls, name: str, release: datetime) -> bool:
645
+ def is_pointed(
646
+ cls,
647
+ name: str,
648
+ release: datetime,
649
+ *,
650
+ extras: Optional[DictData] = None,
651
+ ) -> bool:
544
652
  """Check the release log already pointed or created at the destination
545
653
  log path.
546
654
 
547
- :param name: A workflow name.
548
- :param release: A release datetime.
655
+ :param name: (str) A workflow name.
656
+ :param release: (datetime) A release datetime.
657
+ :param extras: An extra parameter that want to override core config.
549
658
 
550
659
  :rtype: bool
551
660
  :return: Return False if the release log was not pointed or created.
552
661
  """
553
662
  # NOTE: Return False if enable writing log flag does not set.
554
- if not config.enable_write_audit:
663
+ if not dynamic("enable_write_audit", extras=extras):
555
664
  return False
556
665
 
557
666
  # NOTE: create pointer path that use the same logic of pointer method.
558
- pointer: Path = config.audit_path / cls.filename_fmt.format(
559
- name=name, release=release
560
- )
667
+ pointer: Path = dynamic(
668
+ "audit_path", extras=extras
669
+ ) / cls.filename_fmt.format(name=name, release=release)
561
670
 
562
671
  return pointer.exists()
563
672
 
@@ -566,9 +675,9 @@ class FileAudit(BaseAudit):
566
675
 
567
676
  :rtype: Path
568
677
  """
569
- return config.audit_path / self.filename_fmt.format(
570
- name=self.name, release=self.release
571
- )
678
+ return dynamic(
679
+ "audit_path", extras=self.extras
680
+ ) / self.filename_fmt.format(name=self.name, release=self.release)
572
681
 
573
682
  def save(self, excluded: list[str] | None) -> Self:
574
683
  """Save logging data that receive a context data from a workflow
@@ -582,7 +691,7 @@ class FileAudit(BaseAudit):
582
691
  trace: TraceLog = get_trace(self.run_id, self.parent_run_id)
583
692
 
584
693
  # NOTE: Check environ variable was set for real writing.
585
- if not config.enable_write_audit:
694
+ if not dynamic("enable_write_audit", extras=self.extras):
586
695
  trace.debug("[LOG]: Skip writing log cause config was set")
587
696
  return self
588
697
 
@@ -624,7 +733,7 @@ class SQLiteAudit(BaseAudit): # pragma: no cov
624
733
  trace: TraceLog = get_trace(self.run_id, self.parent_run_id)
625
734
 
626
735
  # NOTE: Check environ variable was set for real writing.
627
- if not config.enable_write_audit:
736
+ if not dynamic("enable_write_audit", extras=self.extras):
628
737
  trace.debug("[LOG]: Skip writing log cause config was set")
629
738
  return self
630
739
 
@@ -649,11 +758,15 @@ Audit = Union[
649
758
  ]
650
759
 
651
760
 
652
- def get_audit() -> type[Audit]: # pragma: no cov
761
+ def get_audit(
762
+ extras: Optional[DictData] = None,
763
+ ) -> type[Audit]: # pragma: no cov
653
764
  """Get an audit class that dynamic base on the config audit path value.
654
765
 
766
+ :param extras: An extra parameter that want to override the core config.
767
+
655
768
  :rtype: type[Audit]
656
769
  """
657
- if config.audit_path.is_file():
770
+ if dynamic("audit_path", extras=extras).is_file():
658
771
  return SQLiteAudit
659
772
  return FileAudit
@@ -3,6 +3,7 @@
3
3
  # Licensed under the MIT License. See LICENSE in the project root for
4
4
  # license information.
5
5
  # ------------------------------------------------------------------------------
6
+ # [x] Use dynamic config
6
7
  """Result module. It is the data context transfer objects that use by all object
7
8
  in this package. This module provide Status enum object and Result dataclass.
8
9
  """
@@ -18,18 +19,10 @@ from pydantic.dataclasses import dataclass
18
19
  from pydantic.functional_validators import model_validator
19
20
  from typing_extensions import Self
20
21
 
21
- from .__types import DictData, TupleStr
22
+ from .__types import DictData
23
+ from .conf import dynamic
22
24
  from .logs import TraceLog, get_dt_tznow, get_trace
23
- from .utils import default_gen_id, gen_id
24
-
25
- __all__: TupleStr = (
26
- "SUCCESS",
27
- "FAILED",
28
- "WAIT",
29
- "SKIP",
30
- "Result",
31
- "Status",
32
- )
25
+ from .utils import default_gen_id, gen_id, get_dt_now
33
26
 
34
27
 
35
28
  class Status(IntEnum):
@@ -62,6 +55,10 @@ class Result:
62
55
 
63
56
  For comparison property, this result will use ``status``, ``context``,
64
57
  and ``_run_id`` fields to comparing with other result instance.
58
+
59
+ Warning:
60
+ I use dataclass object instead of Pydantic model object because context
61
+ field that keep dict value change its ID when update new value to it.
65
62
  """
66
63
 
67
64
  status: Status = field(default=WAIT)
@@ -72,7 +69,7 @@ class Result:
72
69
  ts: datetime = field(default_factory=get_dt_tznow, compare=False)
73
70
 
74
71
  trace: Optional[TraceLog] = field(default=None, compare=False, repr=False)
75
- extras: DictData = field(default_factory=dict)
72
+ extras: DictData = field(default_factory=dict, compare=False, repr=False)
76
73
 
77
74
  @classmethod
78
75
  def construct_with_rs_or_id(
@@ -87,11 +84,11 @@ class Result:
87
84
  """Create the Result object or set parent running id if passing Result
88
85
  object.
89
86
 
90
- :param result:
91
- :param run_id:
92
- :param parent_run_id:
93
- :param id_logic:
94
- :param extras:
87
+ :param result: A Result instance.
88
+ :param run_id: A running ID.
89
+ :param parent_run_id: A parent running ID.
90
+ :param id_logic: A logic function that use to generate a running ID.
91
+ :param extras: An extra parameter that want to override the core config.
95
92
 
96
93
  :rtype: Self
97
94
  """
@@ -116,17 +113,22 @@ class Result:
116
113
  :rtype: Self
117
114
  """
118
115
  if self.trace is None: # pragma: no cov
119
- self.trace: TraceLog = get_trace(self.run_id, self.parent_run_id)
116
+ self.trace: TraceLog = get_trace(
117
+ self.run_id, self.parent_run_id, extras=self.extras
118
+ )
120
119
  return self
121
120
 
122
121
  def set_parent_run_id(self, running_id: str) -> Self:
123
122
  """Set a parent running ID.
124
123
 
125
- :param running_id: A running ID that want to update on this model.
124
+ :param running_id: (str) A running ID that want to update on this model.
125
+
126
126
  :rtype: Self
127
127
  """
128
128
  self.parent_run_id: str = running_id
129
- self.trace: TraceLog = get_trace(self.run_id, running_id)
129
+ self.trace: TraceLog = get_trace(
130
+ self.run_id, running_id, extras=self.extras
131
+ )
130
132
  return self
131
133
 
132
134
  def catch(
@@ -157,4 +159,6 @@ class Result:
157
159
 
158
160
  :rtype: float
159
161
  """
160
- return (get_dt_tznow() - self.ts).total_seconds()
162
+ return (
163
+ get_dt_now(tz=dynamic("tz", extras=self.extras)) - self.ts
164
+ ).total_seconds()
@@ -10,7 +10,6 @@ from __future__ import annotations
10
10
  import inspect
11
11
  import logging
12
12
  from ast import Call, Constant, Expr, Module, Name, parse
13
- from dataclasses import dataclass
14
13
  from datetime import datetime
15
14
  from functools import wraps
16
15
  from importlib import import_module
@@ -23,6 +22,7 @@ except ImportError:
23
22
 
24
23
  from ddeutil.core import getdot, import_string, lazy
25
24
  from ddeutil.io import search_env_replace
25
+ from pydantic.dataclasses import dataclass
26
26
 
27
27
  from .__types import DictData, Re
28
28
  from .conf import dynamic
@@ -437,6 +437,7 @@ Registry = dict[str, Callable[[], TagFunc]]
437
437
 
438
438
  def make_registry(
439
439
  submodule: str,
440
+ *,
440
441
  registries: Optional[list[str]] = None,
441
442
  ) -> dict[str, Registry]:
442
443
  """Return registries of all functions that able to called with task.
@@ -533,19 +534,18 @@ def extract_call(
533
534
 
534
535
  call: CallSearchData = CallSearchData(**found.groupdict())
535
536
  rgt: dict[str, Registry] = make_registry(
536
- submodule=f"{call.path}",
537
- registries=registries,
537
+ submodule=f"{call.path}", registries=registries
538
538
  )
539
539
 
540
540
  if call.func not in rgt:
541
541
  raise NotImplementedError(
542
- f"`REGISTER-MODULES.{call.path}.registries` not implement "
542
+ f"`REGISTERS.{call.path}.registries` not implement "
543
543
  f"registry: {call.func!r}."
544
544
  )
545
545
 
546
546
  if call.tag not in rgt[call.func]:
547
547
  raise NotImplementedError(
548
548
  f"tag: {call.tag!r} not found on registry func: "
549
- f"`REGISTER-MODULES.{call.path}.registries.{call.func}`"
549
+ f"`REGISTER.{call.path}.registries.{call.func}`"
550
550
  )
551
551
  return rgt[call.func][call.tag]