pipelime-python 1.9.0__tar.gz → 1.9.1__tar.gz

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.
Files changed (123) hide show
  1. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/PKG-INFO +1 -1
  2. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/__init__.py +1 -1
  3. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/utils/io.py +4 -3
  4. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/main.py +26 -1
  5. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/interfaces.py +2 -2
  6. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/shell.py +4 -4
  7. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/split_ops.py +2 -2
  8. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/tempman.py +2 -2
  9. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/checkpoint.py +3 -2
  10. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/drawing/mermaid.py +1 -1
  11. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/executors/base.py +2 -0
  12. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/executors/factory.py +1 -1
  13. pipelime_python-1.9.1/pipelime/utils/deprecated.py +51 -0
  14. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/.gitignore +0 -0
  15. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/LICENSE +0 -0
  16. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/README.md +0 -0
  17. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/__init__.py +0 -0
  18. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/ast/__init__.py +0 -0
  19. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/ast/nodes.py +0 -0
  20. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/ast/parser.py +0 -0
  21. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/utils/__init__.py +0 -0
  22. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/utils/common.py +0 -0
  23. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/utils/imports.py +0 -0
  24. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/utils/rand.py +0 -0
  25. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/__init__.py +0 -0
  26. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/decoder.py +0 -0
  27. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/inspector.py +0 -0
  28. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/processor.py +0 -0
  29. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/processor_ui.py +0 -0
  30. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/unparser.py +0 -0
  31. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/visitors/walker.py +0 -0
  32. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/choixe/xconfig.py +0 -0
  33. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/__init__.py +0 -0
  34. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/parser.py +0 -0
  35. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/pretty_print.py +0 -0
  36. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/subcommands.py +0 -0
  37. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/tui/__init__.py +0 -0
  38. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/tui/tui.css +0 -0
  39. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/tui/tui.py +0 -0
  40. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/tui/utils.py +0 -0
  41. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/cli/utils.py +0 -0
  42. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/__init__.py +0 -0
  43. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/general.py +0 -0
  44. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/piper.py +0 -0
  45. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/resume.py +0 -0
  46. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/commands/toy_dataset.py +0 -0
  47. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/__init__.py +0 -0
  48. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/base.py +0 -0
  49. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/binary_item.py +0 -0
  50. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/image_item.py +0 -0
  51. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/metadata_item.py +0 -0
  52. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/model3d_item.py +0 -0
  53. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/numpy_item.py +0 -0
  54. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/items/pickle_item.py +0 -0
  55. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/__init__.py +0 -0
  56. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/drawing/__init__.py +0 -0
  57. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/drawing/base.py +0 -0
  58. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/drawing/factory.py +0 -0
  59. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/drawing/graphviz.py +0 -0
  60. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/executors/__init__.py +0 -0
  61. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/executors/naive.py +0 -0
  62. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/graph.py +0 -0
  63. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/model.py +0 -0
  64. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/parsers/__init__.py +0 -0
  65. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/parsers/base.py +0 -0
  66. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/parsers/choixe_parser.py +0 -0
  67. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/parsers/factory.py +0 -0
  68. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/__init__.py +0 -0
  69. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/estimator/__init__.py +0 -0
  70. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/estimator/base.py +0 -0
  71. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/estimator/factory.py +0 -0
  72. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/estimator/naive.py +0 -0
  73. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/__init__.py +0 -0
  74. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/base.py +0 -0
  75. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/callbacks/__init__.py +0 -0
  76. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/callbacks/file.py +0 -0
  77. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/callbacks/rich_table.py +0 -0
  78. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/callbacks/tqdm_bars.py +0 -0
  79. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/factory.py +0 -0
  80. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/receiver/__init__.py +0 -0
  81. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/listener/receiver/zmq.py +0 -0
  82. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/model.py +0 -0
  83. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/__init__.py +0 -0
  84. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/base.py +0 -0
  85. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/direct.py +0 -0
  86. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/factory.py +0 -0
  87. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/loguru.py +0 -0
  88. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/piper/progress/tracker/zmq.py +0 -0
  89. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/remotes/__init__.py +0 -0
  90. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/remotes/base.py +0 -0
  91. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/remotes/s3_remote.py +0 -0
  92. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/remotes/shared_folder_remote.py +0 -0
  93. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/__init__.py +0 -0
  94. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/direct_access.py +0 -0
  95. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/grabber.py +0 -0
  96. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/__init__.py +0 -0
  97. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/base.py +0 -0
  98. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/mapping.py +0 -0
  99. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/operations.py +0 -0
  100. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/validation.py +0 -0
  101. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/pipes/writers.py +0 -0
  102. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sample.py +0 -0
  103. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/samples_sequence.py +0 -0
  104. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sources/__init__.py +0 -0
  105. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sources/from_callable.py +0 -0
  106. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sources/raw.py +0 -0
  107. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sources/readers.py +0 -0
  108. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/sources/toy_dataset.py +0 -0
  109. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/torch.py +0 -0
  110. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/sequences/utils.py +0 -0
  111. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/__init__.py +0 -0
  112. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/augmentations.py +0 -0
  113. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/base.py +0 -0
  114. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/entities.py +0 -0
  115. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/item_info.py +0 -0
  116. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/item_replacement.py +0 -0
  117. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/item_sources.py +0 -0
  118. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/stages/key_transformations.py +0 -0
  119. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/utils/__init__.py +0 -0
  120. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/utils/context_managers.py +0 -0
  121. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/utils/inspection.py +0 -0
  122. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pipelime/utils/pydantic_types.py +0 -0
  123. {pipelime_python-1.9.0 → pipelime_python-1.9.1}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pipelime-python
3
- Version: 1.9.0
3
+ Version: 1.9.1
4
4
  Summary: Data workflows, cli and dataflow automation.
5
5
  Project-URL: Source, https://github.com/eyecan-ai/pipelime-python
6
6
  Project-URL: Issues, https://github.com/eyecan-ai/pipelime-python/issues
@@ -2,4 +2,4 @@
2
2
 
3
3
  __author__ = "Eyecan.ai"
4
4
  __email__ = "info@eyecan.ai"
5
- __version__ = "1.9.0"
5
+ __version__ = "1.9.1"
@@ -111,9 +111,9 @@ class PipelimeTmp:
111
111
 
112
112
  user_dirs: Dict[str, List[str]] = {}
113
113
  for d in iglob(str(PipelimeTmp.base_dir() / (PipelimeTmp.prefix() + "*"))):
114
- if os.path.isdir(d):
114
+ if os.path.isdir(d): # pragma: no branch
115
115
  names = os.path.basename(d).split("-")
116
- if len(names) >= 3:
116
+ if len(names) >= 3: # pragma: no branch
117
117
  user_dirs.setdefault(names[2], []).append(d)
118
118
  return user_dirs
119
119
 
@@ -135,7 +135,8 @@ class PipelimeTemporaryDirectory:
135
135
  import shutil
136
136
 
137
137
  def onerror(func, path, exc_info):
138
- if issubclass(exc_info[0], PermissionError):
138
+ # this code comes from TemporaryDirectory
139
+ if issubclass(exc_info[0], PermissionError): # pragma: no cover
139
140
 
140
141
  def resetperms(path):
141
142
  try:
@@ -57,7 +57,30 @@ class PlCliOptions(BaseModel):
57
57
  return data
58
58
 
59
59
 
60
- def _complete_yaml(incomplete: str):
60
+ def _set_logger_level(verbose: int):
61
+ """Set the logger level if not forced by the user."""
62
+ import os
63
+ import sys
64
+
65
+ from loguru import logger
66
+
67
+ if "LOGURU_LEVEL" not in os.environ:
68
+ if verbose == 0:
69
+ level = "WARNING"
70
+ elif verbose == 1:
71
+ level = "INFO"
72
+ elif verbose == 2:
73
+ level = "DEBUG"
74
+ else:
75
+ level = "TRACE"
76
+ logger.remove()
77
+ logger.add(sys.stderr, level=level)
78
+
79
+ # set the level in the environment so that it is inherited by subprocesses
80
+ os.environ["LOGURU_LEVEL"] = level
81
+
82
+
83
+ def _complete_yaml(incomplete: str): # pragma: no cover
61
84
  for v in Path(".").glob(f"{incomplete}*.yaml"):
62
85
  yield str(v)
63
86
 
@@ -468,6 +491,8 @@ def pl_main(
468
491
  TRUE boolean values. Use `false` or `true` to explicitly set a boolean
469
492
  and `none`/`null`/`nul` to enforce `None`.
470
493
  """
494
+ _set_logger_level(verbose)
495
+
471
496
  PipelimeSymbolsHelper.set_extra_modules(extra_modules)
472
497
 
473
498
  if command_args is None:
@@ -819,7 +819,7 @@ class Interval(PydanticFieldWithDefaultMixin, pyd.BaseModel, extra="forbid"):
819
819
  """
820
820
 
821
821
  _default_type_description: t.ClassVar[t.Optional[str]] = "An interval of indexes."
822
- _compact_form: t.ClassVar[t.Optional[str]] = "<start>[:<stop>]"
822
+ _compact_form: t.ClassVar[t.Optional[str]] = "[<start>][:<stop>]"
823
823
 
824
824
  start: t.Optional[int] = pyd.Field(
825
825
  None,
@@ -872,7 +872,7 @@ class ExtendedInterval(Interval):
872
872
  ``step`` indices or a string ``start:stop:step``.
873
873
  """
874
874
 
875
- _compact_form: t.ClassVar[t.Optional[str]] = "<start>[:<stop>[:<step>]]"
875
+ _compact_form: t.ClassVar[t.Optional[str]] = "[<start>][:<stop>][:<step>]"
876
876
 
877
877
  step: t.Optional[int] = pyd.Field(
878
878
  None, description="The slice step, defaults to 1 (can be negative)."
@@ -50,8 +50,9 @@ class ShellCommand(PipelimeCommand, title="shell"):
50
50
 
51
51
  def _to_command_chunk(self, key: str, value: Any) -> str:
52
52
  cmd = ""
53
- if isinstance(value, Sequence):
54
- cmd += f" --{key} {value[0]} {self._to_command_chunk(key, value[1:])}"
53
+ if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
54
+ if value:
55
+ cmd += f" --{key} {value[0]} {self._to_command_chunk(key, value[1:])}"
55
56
  elif isinstance(value, Mapping):
56
57
  raise NotImplementedError("Mapping values are not supported")
57
58
  elif isinstance(value, bool):
@@ -68,8 +69,7 @@ class ShellCommand(PipelimeCommand, title="shell"):
68
69
  cmd = cmd.format(**args)
69
70
 
70
71
  for key in set(args.keys()).difference(fields):
71
- value = args[key]
72
- cmd += self._to_command_chunk(key, value)
72
+ cmd += self._to_command_chunk(key, args[key])
73
73
 
74
74
  with self.create_task(1, "Executing") as t:
75
75
  subprocess.run(cmd, shell=True)
@@ -202,7 +202,7 @@ class SplitCommand(PipelimeCommand, title="split"):
202
202
  range(len(split_sizes)), split_sizes, splits
203
203
  ):
204
204
  split_stop = split_start + split_length # type: ignore
205
- if split.output is not None:
205
+ if split.output is not None: # pragma: no branch
206
206
  seq = reader[split_start:split_stop]
207
207
  seq = split.output.append_writer(seq)
208
208
  self.grabber.grab_all(
@@ -376,7 +376,7 @@ class SplitByValueCommand(PipelimeCommand, title="split-value"):
376
376
 
377
377
  def __call__(self, x: Sample):
378
378
  value = x.deep_get(self._value_key)
379
- if value is not None:
379
+ if value is not None: # pragma: no branch
380
380
  value = self._value_to_str(value)
381
381
  self._groups.setdefault(value, []).append(
382
382
  int(x[self._idx_key]()) # type: ignore
@@ -102,7 +102,7 @@ class TempCommand(PipelimeCommand, title="tmp"):
102
102
 
103
103
  to_delete = self._folders_to_delete()
104
104
 
105
- if not self.force and to_delete:
105
+ if not self.force and to_delete: # pragma: no cover
106
106
  table, total_size = self._paths_table(to_delete)
107
107
  table.title = f"\nTotal clean up: {self._human_size(total_size)}"
108
108
  rprint(table)
@@ -251,7 +251,7 @@ class TempCommand(PipelimeCommand, title="tmp"):
251
251
  fp = os.path.join(dirpath, f)
252
252
  try:
253
253
  stat = os.stat(fp)
254
- except OSError:
254
+ except OSError: # pragma: no cover
255
255
  continue
256
256
 
257
257
  if stat.st_ino in seen:
@@ -164,6 +164,7 @@ class LocalCheckpoint(Checkpoint, pyd.BaseModel):
164
164
 
165
165
  if self.try_link:
166
166
  if source.is_dir():
167
+ target.mkdir(parents=True, exist_ok=True)
167
168
  for parent_dir, dirs, files in os.walk(source):
168
169
  subdir = os.path.relpath(parent_dir, source)
169
170
  trg_parent = os.path.join(target, subdir)
@@ -174,12 +175,12 @@ class LocalCheckpoint(Checkpoint, pyd.BaseModel):
174
175
  trgf = os.path.join(trg_parent, f)
175
176
  try:
176
177
  os.link(srcf, trgf)
177
- except Exception:
178
+ except Exception: # pragma: no cover
178
179
  shutil.copy2(srcf, trgf)
179
180
  else:
180
181
  try:
181
182
  os.link(source, target)
182
- except Exception:
183
+ except Exception: # pragma: no cover
183
184
  shutil.copy2(source, target)
184
185
  elif source.is_dir():
185
186
  shutil.copytree(source, target)
@@ -16,7 +16,7 @@ from pipelime.piper.graph import (
16
16
  )
17
17
 
18
18
 
19
- class MermaidNodesGraphDrawer(NodesGraphDrawer):
19
+ class MermaidNodesGraphDrawer(NodesGraphDrawer): # pragma: no cover
20
20
  PRIVATE_CHARS = ["@"]
21
21
  SUBSTITUTION_CHAR = "_"
22
22
  OPERATION_NAME = "operation"
@@ -14,6 +14,7 @@ from pipelime.piper.progress.listener.factory import (
14
14
  )
15
15
  from pipelime.piper.progress.tracker.base import TrackedTask
16
16
  from pipelime.piper import PipelimeCommand
17
+ from pipelime.utils.deprecated import deprecated
17
18
 
18
19
 
19
20
  class NodesGraphExecutor(ABC):
@@ -155,6 +156,7 @@ class NodesGraphExecutor(ABC):
155
156
  """
156
157
 
157
158
 
159
+ @deprecated("Use a DirectTrackCallback instead, see RunCommandBase")
158
160
  class WatcherNodesGraphExecutor(NodesGraphExecutor):
159
161
  """Decorator for `NodesGraphExecutor` that wraps an existing executor.
160
162
 
@@ -27,7 +27,7 @@ class NodesGraphExecutorFactory:
27
27
  )
28
28
  executor.task = task
29
29
 
30
- if watch:
30
+ if watch: # pragma: no cover
31
31
  executor = WatcherNodesGraphExecutor(
32
32
  executor, watch if isinstance(watch, (str, Path)) else None
33
33
  )
@@ -0,0 +1,51 @@
1
+ import functools
2
+ import inspect
3
+ import warnings
4
+
5
+
6
+ def deprecated(reason): # pragma: no cover
7
+ """Decorator to mark classes and functions as deprecated.
8
+ A warning will be emitted when the function is used or the class is created.
9
+ """
10
+
11
+ def _helper(wrapped, extra):
12
+ msg = (
13
+ "Call to deprecated "
14
+ f"{'class' if inspect.isclass(wrapped) else 'function'} "
15
+ f"{wrapped.__name__}{extra}"
16
+ )
17
+
18
+ def show_warning():
19
+ warnings.simplefilter("always", DeprecationWarning)
20
+ warnings.warn(
21
+ msg,
22
+ category=DeprecationWarning,
23
+ stacklevel=3,
24
+ )
25
+ warnings.simplefilter("default", DeprecationWarning)
26
+
27
+ if inspect.isclass(wrapped):
28
+ old_new1 = wrapped.__new__
29
+
30
+ def wrapped_new(cls, *args, **kwargs):
31
+ show_warning()
32
+ if old_new1 is object.__new__:
33
+ return old_new1(cls) # type: ignore
34
+ return old_new1(cls, *args, **kwargs)
35
+
36
+ wrapped.__new__ = staticmethod(functools.wraps(old_new1)(wrapped_new)) # type: ignore
37
+
38
+ return wrapped
39
+ else:
40
+
41
+ @functools.wraps(wrapped)
42
+ def wrapper(*args, **kwargs):
43
+ show_warning()
44
+ return wrapped(*args, **kwargs)
45
+
46
+ return wrapper
47
+
48
+ if isinstance(reason, (str, bytes)):
49
+ return functools.partial(_helper, extra=f" ({reason})")
50
+ else:
51
+ return _helper(reason, "")
File without changes