runem 0.3.0__tar.gz → 0.4.0__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 (79) hide show
  1. {runem-0.3.0 → runem-0.4.0}/HISTORY.md +21 -0
  2. {runem-0.3.0 → runem-0.4.0}/PKG-INFO +1 -1
  3. runem-0.4.0/runem/VERSION +1 -0
  4. runem-0.4.0/runem/blocking_print.py +62 -0
  5. {runem-0.3.0 → runem-0.4.0}/runem/runem.py +3 -4
  6. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/PKG-INFO +1 -1
  7. {runem-0.3.0 → runem-0.4.0}/tests/conftest.py +14 -0
  8. {runem-0.3.0 → runem-0.4.0}/tests/test_blocking_print.py +3 -3
  9. {runem-0.3.0 → runem-0.4.0}/tests/test_hook_manager.py +1 -1
  10. {runem-0.3.0 → runem-0.4.0}/tests/test_run_command.py +1 -1
  11. {runem-0.3.0 → runem-0.4.0}/tests/test_runem.py +99 -98
  12. runem-0.3.0/runem/VERSION +0 -1
  13. runem-0.3.0/runem/blocking_print.py +0 -26
  14. {runem-0.3.0 → runem-0.4.0}/Containerfile +0 -0
  15. {runem-0.3.0 → runem-0.4.0}/LICENSE +0 -0
  16. {runem-0.3.0 → runem-0.4.0}/MANIFEST.in +0 -0
  17. {runem-0.3.0 → runem-0.4.0}/README.md +0 -0
  18. {runem-0.3.0 → runem-0.4.0}/requirements-test.txt +0 -0
  19. {runem-0.3.0 → runem-0.4.0}/requirements.txt +0 -0
  20. {runem-0.3.0 → runem-0.4.0}/runem/__init__.py +0 -0
  21. {runem-0.3.0 → runem-0.4.0}/runem/__main__.py +0 -0
  22. {runem-0.3.0 → runem-0.4.0}/runem/base.py +0 -0
  23. {runem-0.3.0 → runem-0.4.0}/runem/cli/initialise_options.py +0 -0
  24. {runem-0.3.0 → runem-0.4.0}/runem/cli.py +0 -0
  25. {runem-0.3.0 → runem-0.4.0}/runem/command_line.py +0 -0
  26. {runem-0.3.0 → runem-0.4.0}/runem/config.py +0 -0
  27. {runem-0.3.0 → runem-0.4.0}/runem/config_metadata.py +0 -0
  28. {runem-0.3.0 → runem-0.4.0}/runem/config_parse.py +0 -0
  29. {runem-0.3.0 → runem-0.4.0}/runem/files.py +0 -0
  30. {runem-0.3.0 → runem-0.4.0}/runem/hook_manager.py +0 -0
  31. {runem-0.3.0 → runem-0.4.0}/runem/informative_dict.py +0 -0
  32. {runem-0.3.0 → runem-0.4.0}/runem/job.py +0 -0
  33. {runem-0.3.0 → runem-0.4.0}/runem/job_execute.py +0 -0
  34. {runem-0.3.0 → runem-0.4.0}/runem/job_filter.py +0 -0
  35. {runem-0.3.0 → runem-0.4.0}/runem/job_runner_simple_command.py +0 -0
  36. {runem-0.3.0 → runem-0.4.0}/runem/job_wrapper.py +0 -0
  37. {runem-0.3.0 → runem-0.4.0}/runem/job_wrapper_python.py +0 -0
  38. {runem-0.3.0 → runem-0.4.0}/runem/log.py +0 -0
  39. {runem-0.3.0 → runem-0.4.0}/runem/py.typed +0 -0
  40. {runem-0.3.0 → runem-0.4.0}/runem/report.py +0 -0
  41. {runem-0.3.0 → runem-0.4.0}/runem/run_command.py +0 -0
  42. {runem-0.3.0 → runem-0.4.0}/runem/runem_version.py +0 -0
  43. {runem-0.3.0 → runem-0.4.0}/runem/types/__init__.py +0 -0
  44. {runem-0.3.0 → runem-0.4.0}/runem/types/common.py +0 -0
  45. {runem-0.3.0 → runem-0.4.0}/runem/types/errors.py +0 -0
  46. {runem-0.3.0 → runem-0.4.0}/runem/types/filters.py +0 -0
  47. {runem-0.3.0 → runem-0.4.0}/runem/types/hooks.py +0 -0
  48. {runem-0.3.0 → runem-0.4.0}/runem/types/options.py +0 -0
  49. {runem-0.3.0 → runem-0.4.0}/runem/types/runem_config.py +0 -0
  50. {runem-0.3.0 → runem-0.4.0}/runem/types/types_jobs.py +0 -0
  51. {runem-0.3.0 → runem-0.4.0}/runem/utils.py +0 -0
  52. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/SOURCES.txt +0 -0
  53. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/dependency_links.txt +0 -0
  54. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/entry_points.txt +0 -0
  55. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/requires.txt +0 -0
  56. {runem-0.3.0 → runem-0.4.0}/runem.egg-info/top_level.txt +0 -0
  57. {runem-0.3.0 → runem-0.4.0}/setup.cfg +0 -0
  58. {runem-0.3.0 → runem-0.4.0}/setup.py +0 -0
  59. {runem-0.3.0 → runem-0.4.0}/tests/__init__.py +0 -0
  60. {runem-0.3.0 → runem-0.4.0}/tests/cli/test_initialise_options.py +0 -0
  61. {runem-0.3.0 → runem-0.4.0}/tests/data/help_output.3.10.txt +0 -0
  62. {runem-0.3.0 → runem-0.4.0}/tests/data/help_output.3.11.txt +0 -0
  63. {runem-0.3.0 → runem-0.4.0}/tests/intentional_test_error.py +0 -0
  64. {runem-0.3.0 → runem-0.4.0}/tests/sanitise_reports_footer.py +0 -0
  65. {runem-0.3.0 → runem-0.4.0}/tests/test_base.py +0 -0
  66. {runem-0.3.0 → runem-0.4.0}/tests/test_cli.py +0 -0
  67. {runem-0.3.0 → runem-0.4.0}/tests/test_config.py +0 -0
  68. {runem-0.3.0 → runem-0.4.0}/tests/test_config_parse.py +0 -0
  69. {runem-0.3.0 → runem-0.4.0}/tests/test_files.py +0 -0
  70. {runem-0.3.0 → runem-0.4.0}/tests/test_informative_dict.py +0 -0
  71. {runem-0.3.0 → runem-0.4.0}/tests/test_job.py +0 -0
  72. {runem-0.3.0 → runem-0.4.0}/tests/test_job_execute.py +0 -0
  73. {runem-0.3.0 → runem-0.4.0}/tests/test_job_filter.py +0 -0
  74. {runem-0.3.0 → runem-0.4.0}/tests/test_job_runner_simple_command.py +0 -0
  75. {runem-0.3.0 → runem-0.4.0}/tests/test_job_wrapper.py +0 -0
  76. {runem-0.3.0 → runem-0.4.0}/tests/test_job_wrapper_python.py +0 -0
  77. {runem-0.3.0 → runem-0.4.0}/tests/test_report.py +0 -0
  78. {runem-0.3.0 → runem-0.4.0}/tests/test_types/__init__.py +0 -0
  79. {runem-0.3.0 → runem-0.4.0}/tests/test_types/test_public_api.py +0 -0
@@ -4,6 +4,27 @@ Changelog
4
4
 
5
5
  (unreleased)
6
6
  ------------
7
+ - Merge pull request #67 from lursight/feat/prettier_logging. [Frank
8
+ Harrison]
9
+
10
+ feat(rich): prettier logging with rich
11
+ - Feat(rich): disable markup handling. [Frank Harrison]
12
+
13
+ We got errors running logging through rich in CiCd where
14
+ [/path/to/thing] was being seen as rich markup, specifically as a rich
15
+ markup close-tag.
16
+
17
+ This stops parsing strings as markup and therefore works around the
18
+ error.
19
+ - Feat(rich): prettier logging with rich. [Frank Harrison]
20
+
21
+ It also makes the logging more useful in different contexts by removing
22
+ tabs and so on.
23
+
24
+
25
+ 0.3.0 (2024-12-03)
26
+ ------------------
27
+ - Release: version 0.3.0 🚀 [Frank Harrison]
7
28
  - Merge pull request #66 from
8
29
  lursight/feat/option_switches_in_simple_commands. [Frank Harrison]
9
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runem
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Awesome runem created by lursight
5
5
  Home-page: https://github.com/lursight/runem/
6
6
  Author: lursight
@@ -0,0 +1 @@
1
+ 0.4.0
@@ -0,0 +1,62 @@
1
+ import time
2
+ import typing
3
+
4
+ from rich.console import Console
5
+
6
+
7
+ def _reset_console() -> Console:
8
+ """Sets the nice user-facing console.
9
+
10
+ This function exists so we can reset the output from tests.
11
+ """
12
+ global RICH_CONSOLE # pylint: disable=global-statement
13
+
14
+ RICH_CONSOLE = Console(
15
+ log_path=False, # Do NOT print the source path.
16
+ markup=False, # Do NOT print markup e.g. `[blink]Don't Panic![/blink]`.
17
+ )
18
+ return RICH_CONSOLE
19
+
20
+
21
+ # Overridden in tests.
22
+ RICH_CONSOLE: Console = _reset_console()
23
+
24
+
25
+ def _reset_console_for_tests() -> None:
26
+ """Overrides the console output with more deterministic version.
27
+
28
+ ... so we can have deterministic tests.
29
+ """
30
+ global RICH_CONSOLE # pylint: disable=global-statement
31
+ RICH_CONSOLE = Console(
32
+ log_path=False, # Do NOT print the source path.
33
+ log_time=False, # Do not prefix with log time e.g. `[time] log message`.
34
+ markup=False, # Do NOT print markup e.g. `[blink]Don't Panic![/blink]`.
35
+ width=999, # A very wide width.
36
+ )
37
+
38
+
39
+ def blocking_print(
40
+ msg: str = "",
41
+ end: typing.Optional[str] = None,
42
+ max_retries: int = 5,
43
+ sleep_time_s: float = 0.1,
44
+ ) -> None:
45
+ """Attempt to print a message, retrying on BlockingIOError.
46
+
47
+ Sometimes in long-lasting jobs, that produce lots of output, we hit
48
+ BlockingIOError where we can't print to screen because the buffer is full or
49
+ already being written to (for example), i.e. the `print` would need to be a
50
+ 'blocking' call, which it is not.
51
+ """
52
+ if end is None:
53
+ end = "\n"
54
+ for _ in range(max_retries):
55
+ try:
56
+ RICH_CONSOLE.print(msg, end=end)
57
+ break # Success, exit the retry loop
58
+ except BlockingIOError:
59
+ time.sleep(sleep_time_s) # Wait a bit for the buffer to clear
60
+ else:
61
+ # Optional: handle the failure to print after all retries
62
+ pass
@@ -36,6 +36,7 @@ from rich.console import Console, ConsoleOptions, ConsoleRenderable, RenderResul
36
36
  from rich.spinner import Spinner
37
37
  from rich.text import Text
38
38
 
39
+ from runem.blocking_print import RICH_CONSOLE
39
40
  from runem.command_line import parse_args
40
41
  from runem.config import load_project_config, load_user_configs
41
42
  from runem.config_metadata import ConfigMetadata
@@ -57,8 +58,6 @@ from runem.types.types_jobs import (
57
58
  )
58
59
  from runem.utils import printable_set
59
60
 
60
- rich_console = Console()
61
-
62
61
 
63
62
  def _determine_run_parameters(argv: typing.List[str]) -> ConfigMetadata:
64
63
  """Loads config, parsing cli input and produces the run config.
@@ -143,7 +142,7 @@ def _update_progress(
143
142
 
144
143
  last_running_jobs_set: typing.Set[str] = set()
145
144
 
146
- with rich_console.status(spinner):
145
+ with RICH_CONSOLE.status(spinner):
147
146
  while is_running.value:
148
147
  running_jobs_set: typing.Set[str] = set(running_jobs.values())
149
148
 
@@ -157,7 +156,7 @@ def _update_progress(
157
156
  spinner.text = report
158
157
  else:
159
158
  if last_running_jobs_set != running_jobs_set:
160
- rich_console.log(report)
159
+ RICH_CONSOLE.log(report)
161
160
 
162
161
  # Sleep for reduced CPU usage
163
162
  time.sleep(0.1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: runem
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Awesome runem created by lursight
5
5
  Home-page: https://github.com/lursight/runem/
6
6
  Author: lursight
@@ -5,9 +5,23 @@ import typing
5
5
 
6
6
  import pytest
7
7
 
8
+ from runem.blocking_print import _reset_console, _reset_console_for_tests
9
+
8
10
  FixtureRequest = typing.Any
9
11
 
10
12
 
13
+ @pytest.fixture(autouse=True)
14
+ def use_test_rich_print(request: FixtureRequest) -> typing.Generator[None, None, None]:
15
+ """Each test should use the test-version of the `rich` print function.
16
+
17
+ This is so we get deterministic output with out timestamps nor auto-wrapping console
18
+ output.
19
+ """
20
+ _reset_console_for_tests()
21
+ yield
22
+ _reset_console()
23
+
24
+
11
25
  # each test runs on cwd to its temp dir
12
26
  @pytest.fixture(autouse=True)
13
27
  def go_to_tmp_path(request: FixtureRequest) -> typing.Generator[None, None, None]:
@@ -8,7 +8,7 @@ from runem import blocking_print
8
8
 
9
9
  @pytest.fixture(name="mock_print")
10
10
  def mock_print_fixture() -> typing.Generator[MagicMock, None, None]:
11
- with patch("runem.blocking_print.print") as mock_print:
11
+ with patch("runem.blocking_print.RICH_CONSOLE.print") as mock_print:
12
12
  yield mock_print
13
13
 
14
14
 
@@ -23,7 +23,7 @@ def test_blocking_print_success_first_try(
23
23
  ) -> None:
24
24
  """Test that blocking_print prints the message successfully on the first try."""
25
25
  blocking_print.blocking_print("Test message")
26
- mock_print.assert_called_once_with("Test message", end=None)
26
+ mock_print.assert_called_once_with("Test message", end="\n")
27
27
  mock_sleep.assert_not_called()
28
28
 
29
29
 
@@ -57,7 +57,7 @@ def test_blocking_print_empty_message(
57
57
  ) -> None:
58
58
  """Test that blocking_print handles an empty message."""
59
59
  blocking_print.blocking_print()
60
- mock_print.assert_called_once_with("", end=None)
60
+ mock_print.assert_called_once_with("", end="\n")
61
61
  mock_sleep.assert_not_called()
62
62
 
63
63
 
@@ -149,7 +149,7 @@ def test_invoke_hooks(do_hooks: bool, hook_man: HookManager) -> None:
149
149
  if do_hooks:
150
150
  expected_stdout = [
151
151
  "runem: hooks: initialising 2 hooks",
152
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
152
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
153
153
  (
154
154
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: "
155
155
  "<THIS_FILE>._dummy_hook"
@@ -300,7 +300,7 @@ def test_run_command_basic_call_non_standard_exit_ok_code_verbose(
300
300
  # check the log output hasn't changed. Update as needed.
301
301
  assert run_command_stdout == (
302
302
  "runem: running: start: test command: ls\n"
303
- "runem: allowed return ids are: 3\n"
303
+ "runem: allowed return ids are: 3\n"
304
304
  "runem: test command: test output\n"
305
305
  "runem: running: done: test command: ls\n"
306
306
  )
@@ -110,16 +110,17 @@ def test_runem_basic_with_config(
110
110
  runem_stdout: typing.List[str] = sanitise_reports_footer(buf.getvalue())
111
111
  assert [] == _strip_reports_footer(runem_stdout)
112
112
 
113
- assert [
114
- "runem: reports:",
115
- "runem (total wall-clock) [<float>]",
116
- "runem.pre-build [<float>]",
117
- "runem.run-phases [<float>]",
118
- " mock phase (user-time) [<float>]",
119
- "runem: DONE: runem took: <float>, saving you <float>, without runem you "
120
- "would have waited <float>",
121
- "",
122
- ] == runem_stdout
113
+ pprint(runem_stdout)
114
+ assert runem_stdout == [
115
+ "runem: reports:",
116
+ "runem (total wall-clock) [<float>]",
117
+ "runem.pre-build [<float>]",
118
+ "└runem.run-phases [<float>]",
119
+ " └mock phase (user-time) [<float>]",
120
+ "runem: DONE: runem took: <float>, saving you <float>, without runem you "
121
+ "would have waited <float>",
122
+ "",
123
+ ]
123
124
  load_config_metadata_mock.assert_called_once()
124
125
 
125
126
 
@@ -156,7 +157,7 @@ def test_runem_basic_with_config_no_options(
156
157
  # with pytest.raises(SystemExit):
157
158
  timed_main(["--help"])
158
159
  runem_stdout = buf.getvalue()
159
- assert [
160
+ assert sanitise_reports_footer(runem_stdout) == [
160
161
  "runem: reports:",
161
162
  "runem (total wall-clock) [<float>]",
162
163
  "├runem.pre-build [<float>]",
@@ -165,7 +166,7 @@ def test_runem_basic_with_config_no_options(
165
166
  "runem: DONE: runem took: <float>, saving you <float>, without runem you "
166
167
  "would have waited <float>",
167
168
  "",
168
- ] == sanitise_reports_footer(runem_stdout)
169
+ ]
169
170
 
170
171
 
171
172
  MOCK_JOB_EXECUTE_INNER_RET: typing.Tuple[JobTiming, JobReturn] = (
@@ -407,17 +408,17 @@ def test_runem_with_full_config(verbosity: bool) -> None:
407
408
  ),
408
409
  ]
409
410
  else:
410
- assert [
411
+ assert runem_stdout == [
411
412
  (
412
413
  "runem: WARNING: no phase found for 'echo \"hello world!\"', using "
413
414
  "'dummy phase 1'"
414
415
  ),
415
416
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
416
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
417
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
417
418
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
418
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
419
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
419
420
  "runem: hooks: initialising 2 hooks",
420
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
421
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
421
422
  (
422
423
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
423
424
  "user local hook'"
@@ -433,9 +434,9 @@ def test_runem_with_full_config(verbosity: bool) -> None:
433
434
  "'tag only on job 1', 'tag only on job 2'"
434
435
  ),
435
436
  "runem: will run 2 jobs for phase 'dummy phase 1'",
436
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
437
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
437
438
  "runem: will run 2 jobs for phase 'dummy phase 2'",
438
- "runem: \t'dummy job label 2', 'hello world'",
439
+ "runem: 'dummy job label 2', 'hello world'",
439
440
  "runem: Running Phase dummy phase 1",
440
441
  (
441
442
  "runem: Running 'dummy phase 1' with 2 workers (of [NUM CORES] max) "
@@ -446,7 +447,7 @@ def test_runem_with_full_config(verbosity: bool) -> None:
446
447
  "runem: Running 'dummy phase 2' with 2 workers (of [NUM CORES] max) "
447
448
  "processing 2 jobs"
448
449
  ),
449
- ] == runem_stdout
450
+ ]
450
451
 
451
452
 
452
453
  def test_runem_with_full_config_verbose() -> None:
@@ -463,17 +464,17 @@ def test_runem_with_full_config_verbose() -> None:
463
464
  if error_raised is not None: # pragma: no cover
464
465
  raise error_raised # re-raise the error that shouldn't have been raised
465
466
 
466
- assert [
467
+ assert runem_stdout == [
467
468
  (
468
469
  "runem: WARNING: no phase found for 'echo \"hello world!\"', using "
469
470
  "'dummy phase 1'"
470
471
  ),
471
472
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
472
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
473
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
473
474
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
474
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
475
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
475
476
  "runem: hooks: initialising 2 hooks",
476
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
477
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
477
478
  (
478
479
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
479
480
  "user local hook'"
@@ -489,14 +490,14 @@ def test_runem_with_full_config_verbose() -> None:
489
490
  "'tag only on job 1', 'tag only on job 2'"
490
491
  ),
491
492
  "runem: will run 2 jobs for phase 'dummy phase 1'",
492
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
493
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
493
494
  "runem: will run 2 jobs for phase 'dummy phase 2'",
494
- "runem: \t'dummy job label 2', 'hello world'",
495
+ "runem: 'dummy job label 2', 'hello world'",
495
496
  "runem: Running Phase dummy phase 1",
496
497
  "runem: Running 'dummy phase 1' with 2 workers (of [NUM CORES] max) processing 2 jobs",
497
498
  "runem: Running Phase dummy phase 2",
498
499
  "runem: Running 'dummy phase 2' with 2 workers (of [NUM CORES] max) processing 2 jobs",
499
- ] == runem_stdout
500
+ ]
500
501
 
501
502
 
502
503
  def test_runem_with_single_phase() -> None:
@@ -513,17 +514,17 @@ def test_runem_with_single_phase() -> None:
513
514
  if error_raised is not None: # pragma: no cover
514
515
  raise error_raised # re-raise the error that shouldn't have been raised
515
516
 
516
- assert [
517
+ assert runem_stdout == [
517
518
  (
518
519
  "runem: WARNING: no phase found for 'echo \"hello world!\"', using "
519
520
  "'dummy phase 1'"
520
521
  ),
521
522
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
522
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
523
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
523
524
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
524
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
525
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
525
526
  "runem: hooks: initialising 2 hooks",
526
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
527
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
527
528
  (
528
529
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
529
530
  "user local hook'"
@@ -539,14 +540,14 @@ def test_runem_with_single_phase() -> None:
539
540
  "'tag only on job 1', 'tag only on job 2'"
540
541
  ),
541
542
  "runem: will run 2 jobs for phase 'dummy phase 1'",
542
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
543
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
543
544
  "runem: skipping phase 'dummy phase 2'",
544
545
  "runem: Running Phase dummy phase 1",
545
546
  (
546
547
  "runem: Running 'dummy phase 1' with 2 workers (of [NUM CORES] max) "
547
548
  "processing 2 jobs"
548
549
  ),
549
- ] == runem_stdout
550
+ ]
550
551
 
551
552
 
552
553
  def test_runem_with_single_phase_verbose() -> None:
@@ -570,11 +571,11 @@ def test_runem_with_single_phase_verbose() -> None:
570
571
  "'dummy phase 1'"
571
572
  ),
572
573
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
573
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
574
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
574
575
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
575
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
576
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
576
577
  "runem: hooks: initialising 2 hooks",
577
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
578
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
578
579
  (
579
580
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
580
581
  "user local hook'"
@@ -590,7 +591,7 @@ def test_runem_with_single_phase_verbose() -> None:
590
591
  "'tag only on job 1', 'tag only on job 2'"
591
592
  ),
592
593
  "runem: will run 2 jobs for phase 'dummy phase 1'",
593
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
594
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
594
595
  "runem: skipping phase 'dummy phase 2'",
595
596
  "runem: Running Phase dummy phase 1",
596
597
  (
@@ -758,11 +759,11 @@ def test_runem_version(switch_to_test: str, verbosity: bool) -> None:
758
759
  if verbosity:
759
760
  expected_version_output = [
760
761
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
761
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
762
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
762
763
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
763
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
764
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
764
765
  "runem: hooks: initialising 2 hooks",
765
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
766
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
766
767
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
767
768
  "user local hook'",
768
769
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 2: echo 'mock "
@@ -828,11 +829,11 @@ def test_runem_bad_validate_switch_jobs(switch_to_test: str) -> None:
828
829
  "'dummy phase 1'"
829
830
  ),
830
831
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
831
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
832
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
832
833
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
833
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
834
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
834
835
  "runem: hooks: initialising 2 hooks",
835
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
836
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
836
837
  (
837
838
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
838
839
  "user local hook'"
@@ -879,11 +880,11 @@ def test_runem_bad_validate_switch_tags(switch_to_test: str) -> None:
879
880
  "'dummy phase 1'"
880
881
  ),
881
882
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
882
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
883
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
883
884
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
884
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
885
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
885
886
  "runem: hooks: initialising 2 hooks",
886
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
887
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
887
888
  (
888
889
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
889
890
  "user local hook'"
@@ -925,11 +926,11 @@ def test_runem_bad_validate_tag_exclude() -> None:
925
926
  "'dummy phase 1'"
926
927
  ),
927
928
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
928
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
929
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
929
930
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
930
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
931
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
931
932
  "runem: hooks: initialising 2 hooks",
932
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
933
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
933
934
  (
934
935
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
935
936
  "user local hook'"
@@ -945,13 +946,13 @@ def test_runem_bad_validate_tag_exclude() -> None:
945
946
  "only on job 2'"
946
947
  ),
947
948
  "runem: will run 2 jobs for phase 'dummy phase 1'",
948
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
949
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
949
950
  (
950
951
  "runem: not running job 'dummy job label 2' because it contains the "
951
952
  "following tags: 'tag only on job 2'"
952
953
  ),
953
954
  "runem: will run 1 jobs for phase 'dummy phase 2'",
954
- "runem: \t'hello world'",
955
+ "runem: 'hello world'",
955
956
  "runem: Running Phase dummy phase 1",
956
957
  (
957
958
  "runem: Running 'dummy phase 1' with 2 workers (of [NUM CORES] max) "
@@ -994,11 +995,11 @@ def test_runem_bad_validate_switch_phases(switch_to_test: str) -> None:
994
995
  "'dummy phase 1'"
995
996
  ),
996
997
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
997
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
998
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
998
999
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
999
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1000
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1000
1001
  "runem: hooks: initialising 2 hooks",
1001
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1002
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1002
1003
  (
1003
1004
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1004
1005
  "user local hook'"
@@ -1046,11 +1047,11 @@ def test_runem_job_filters_work(verbosity: bool) -> None:
1046
1047
  "'dummy phase 1'"
1047
1048
  ),
1048
1049
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1049
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1050
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1050
1051
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1051
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1052
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1052
1053
  "runem: hooks: initialising 2 hooks",
1053
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1054
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1054
1055
  (
1055
1056
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1056
1057
  "user local hook'"
@@ -1070,7 +1071,7 @@ def test_runem_job_filters_work(verbosity: bool) -> None:
1070
1071
  "in the list of job names. See --jobs and --not-jobs"
1071
1072
  ),
1072
1073
  "runem: will run 1 jobs for phase 'dummy phase 1'",
1073
- "runem: \t'dummy job label 1'",
1074
+ "runem: 'dummy job label 1'",
1074
1075
  (
1075
1076
  "runem: not running job 'dummy job label 2' because it isn't in the list "
1076
1077
  "of job names. See --jobs and --not-jobs"
@@ -1097,11 +1098,11 @@ def test_runem_job_filters_work(verbosity: bool) -> None:
1097
1098
  "'dummy phase 1'"
1098
1099
  ),
1099
1100
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1100
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1101
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1101
1102
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1102
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1103
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1103
1104
  "runem: hooks: initialising 2 hooks",
1104
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1105
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1105
1106
  (
1106
1107
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1107
1108
  "user local hook'"
@@ -1121,7 +1122,7 @@ def test_runem_job_filters_work(verbosity: bool) -> None:
1121
1122
  "the list of job names. See --jobs and --not-jobs"
1122
1123
  ),
1123
1124
  "runem: will run 1 jobs for phase 'dummy phase 1'",
1124
- "runem: \t'dummy job label 1'",
1125
+ "runem: 'dummy job label 1'",
1125
1126
  (
1126
1127
  "runem: not running job 'dummy job label 2' because it isn't in the list of "
1127
1128
  "job names. See --jobs and --not-jobs"
@@ -1176,11 +1177,11 @@ def test_runem_tag_filters_work(verbosity: bool) -> None:
1176
1177
  "'dummy phase 1'"
1177
1178
  ),
1178
1179
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1179
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1180
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1180
1181
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1181
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1182
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1182
1183
  "runem: hooks: initialising 2 hooks",
1183
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1184
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1184
1185
  (
1185
1186
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1186
1187
  "user local hook'"
@@ -1193,7 +1194,7 @@ def test_runem_tag_filters_work(verbosity: bool) -> None:
1193
1194
  "runem: found 1 batches, 1 'mock phase' files, ",
1194
1195
  "runem: filtering for tags 'tag only on job 1'",
1195
1196
  "runem: will run 2 jobs for phase 'dummy phase 1'",
1196
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
1197
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
1197
1198
  (
1198
1199
  "runem: not running job 'dummy job label 2' because it doesn't have "
1199
1200
  "any of the following tags: 'tag only on job 1'"
@@ -1216,11 +1217,11 @@ def test_runem_tag_filters_work(verbosity: bool) -> None:
1216
1217
  "'dummy phase 1'"
1217
1218
  ),
1218
1219
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1219
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1220
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1220
1221
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1221
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1222
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1222
1223
  "runem: hooks: initialising 2 hooks",
1223
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1224
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1224
1225
  (
1225
1226
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1226
1227
  "user local hook'"
@@ -1233,7 +1234,7 @@ def test_runem_tag_filters_work(verbosity: bool) -> None:
1233
1234
  "runem: found 1 batches, 1 'mock phase' files, ",
1234
1235
  "runem: filtering for tags 'tag only on job 1'",
1235
1236
  "runem: will run 2 jobs for phase 'dummy phase 1'",
1236
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
1237
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
1237
1238
  (
1238
1239
  "runem: not running job 'dummy job label 2' because it doesn't have "
1239
1240
  "any of the following tags: 'tag only on job 1'"
@@ -1295,11 +1296,11 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1295
1296
  "'dummy phase 1'"
1296
1297
  ),
1297
1298
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1298
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1299
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1299
1300
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1300
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1301
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1301
1302
  "runem: hooks: initialising 2 hooks",
1302
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1303
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1303
1304
  (
1304
1305
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1305
1306
  "user local hook'"
@@ -1319,9 +1320,9 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1319
1320
  "the following tags: 'tag only on job 1'"
1320
1321
  ),
1321
1322
  "runem: will run 1 jobs for phase 'dummy phase 1'",
1322
- "runem: \t'echo \"hello world!\"'",
1323
+ "runem: 'echo \"hello world!\"'",
1323
1324
  "runem: will run 2 jobs for phase 'dummy phase 2'",
1324
- "runem: \t'dummy job label 2', 'hello world'",
1325
+ "runem: 'dummy job label 2', 'hello world'",
1325
1326
  "runem: Running Phase dummy phase 1",
1326
1327
  (
1327
1328
  "runem: Running 'dummy phase 1' with 1 workers (of [NUM CORES] max) "
@@ -1341,11 +1342,11 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1341
1342
  "'dummy phase 1'"
1342
1343
  ),
1343
1344
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1344
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1345
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1345
1346
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1346
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1347
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1347
1348
  "runem: hooks: initialising 2 hooks",
1348
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1349
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1349
1350
  (
1350
1351
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1351
1352
  "user local hook'"
@@ -1365,9 +1366,9 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1365
1366
  "the following tags: 'tag only on job 1'"
1366
1367
  ),
1367
1368
  "runem: will run 1 jobs for phase 'dummy phase 1'",
1368
- "runem: \t'echo \"hello world!\"'",
1369
+ "runem: 'echo \"hello world!\"'",
1369
1370
  "runem: will run 2 jobs for phase 'dummy phase 2'",
1370
- "runem: \t'dummy job label 2', 'hello world'",
1371
+ "runem: 'dummy job label 2', 'hello world'",
1371
1372
  "runem: Running Phase dummy phase 1",
1372
1373
  (
1373
1374
  "runem: Running 'dummy phase 1' with 1 workers (of [NUM CORES] max) "
@@ -1384,11 +1385,11 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1384
1385
  # no-one-liner + verbosity
1385
1386
  assert runem_stdout == [
1386
1387
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1387
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1388
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1388
1389
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1389
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1390
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1390
1391
  "runem: hooks: initialising 2 hooks",
1391
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1392
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1392
1393
  (
1393
1394
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1394
1395
  "user local hook'"
@@ -1412,7 +1413,7 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1412
1413
  "'dummy tag 2', 'tag only on job 2'"
1413
1414
  ),
1414
1415
  "runem: will run 2 jobs for phase 'dummy phase 2'",
1415
- "runem: \t'dummy job label 2', 'hello world'",
1416
+ "runem: 'dummy job label 2', 'hello world'",
1416
1417
  "runem: Running Phase dummy phase 2",
1417
1418
  (
1418
1419
  "runem: Running 'dummy phase 2' with 2 workers (of [NUM CORES] max) "
@@ -1423,11 +1424,11 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1423
1424
  # no-one-liner + no-verbosity
1424
1425
  assert runem_stdout == [
1425
1426
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1426
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1427
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1427
1428
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1428
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1429
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1429
1430
  "runem: hooks: initialising 2 hooks",
1430
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1431
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1431
1432
  (
1432
1433
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1433
1434
  "user local hook'"
@@ -1451,7 +1452,7 @@ def test_runem_tag_out_filters_work(verbosity: bool, one_liner: bool) -> None:
1451
1452
  "'dummy tag 2', 'tag only on job 2'"
1452
1453
  ),
1453
1454
  "runem: will run 2 jobs for phase 'dummy phase 2'",
1454
- "runem: \t'dummy job label 2', 'hello world'",
1455
+ "runem: 'dummy job label 2', 'hello world'",
1455
1456
  "runem: Running Phase dummy phase 2",
1456
1457
  (
1457
1458
  "runem: Running 'dummy phase 2' with 2 workers (of [NUM CORES] max) "
@@ -1497,11 +1498,11 @@ def test_runem_tag_out_filters_work_all_tags(verbosity: bool) -> None:
1497
1498
  if verbosity:
1498
1499
  assert runem_stdout == [
1499
1500
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1500
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1501
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1501
1502
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1502
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1503
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1503
1504
  "runem: hooks: initialising 2 hooks",
1504
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1505
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1505
1506
  (
1506
1507
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1507
1508
  "user local hook'"
@@ -1576,11 +1577,11 @@ def test_runem_phase_filters_work(verbosity: bool) -> None:
1576
1577
  "'dummy phase 1'"
1577
1578
  ),
1578
1579
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1579
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1580
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1580
1581
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1581
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1582
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1582
1583
  "runem: hooks: initialising 2 hooks",
1583
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1584
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1584
1585
  (
1585
1586
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1586
1587
  "user local hook'"
@@ -1596,7 +1597,7 @@ def test_runem_phase_filters_work(verbosity: bool) -> None:
1596
1597
  "'tag only on job 2'"
1597
1598
  ),
1598
1599
  "runem: will run 2 jobs for phase 'dummy phase 1'",
1599
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
1600
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
1600
1601
  "runem: skipping phase 'dummy phase 2'",
1601
1602
  "runem: Running Phase dummy phase 1",
1602
1603
  (
@@ -1611,11 +1612,11 @@ def test_runem_phase_filters_work(verbosity: bool) -> None:
1611
1612
  "'dummy phase 1'"
1612
1613
  ),
1613
1614
  "runem: hooks: loading user hooks from 'local-user-config.yml'",
1614
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1615
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1615
1616
  "runem: hooks: loading user hooks from 'local-user-home-dir-config.yml'",
1616
- "runem: hooks:\tadded 1 user hooks for 'HookName.ON_EXIT'",
1617
+ "runem: hooks: added 1 user hooks for 'HookName.ON_EXIT'",
1617
1618
  "runem: hooks: initialising 2 hooks",
1618
- "runem: hooks:\tinitialising 2 hooks for 'HookName.ON_EXIT'",
1619
+ "runem: hooks: initialising 2 hooks for 'HookName.ON_EXIT'",
1619
1620
  (
1620
1621
  "runem: hooks: registered hook for 'HookName.ON_EXIT', have 1: echo 'mock "
1621
1622
  "user local hook'"
@@ -1631,7 +1632,7 @@ def test_runem_phase_filters_work(verbosity: bool) -> None:
1631
1632
  "'tag only on job 1', 'tag only on job 2'"
1632
1633
  ),
1633
1634
  "runem: will run 2 jobs for phase 'dummy phase 1'",
1634
- "runem: \t'dummy job label 1', 'echo \"hello world!\"'",
1635
+ "runem: 'dummy job label 1', 'echo \"hello world!\"'",
1635
1636
  "runem: skipping phase 'dummy phase 2'",
1636
1637
  "runem: Running Phase dummy phase 1",
1637
1638
  (
runem-0.3.0/runem/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.0
@@ -1,26 +0,0 @@
1
- import time
2
- import typing
3
-
4
-
5
- def blocking_print(
6
- msg: str = "",
7
- end: typing.Optional[str] = None,
8
- max_retries: int = 5,
9
- sleep_time_s: float = 0.1,
10
- ) -> None:
11
- """Attempt to print a message, retrying on BlockingIOError.
12
-
13
- Sometimes in long-lasting jobs, that produce lots of output, we hit
14
- BlockingIOError where we can't print to screen because the buffer is full or
15
- already being written to (for example), i.e. the `print` would need to be a
16
- 'blocking' call, which it is not.
17
- """
18
- for _ in range(max_retries):
19
- try:
20
- print(msg, end=end)
21
- break # Success, exit the retry loop
22
- except BlockingIOError:
23
- time.sleep(sleep_time_s) # Wait a bit for the buffer to clear
24
- else:
25
- # Optional: handle the failure to print after all retries
26
- pass
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes