Skip to content

Commit 33277c4

Browse files
authored
Merge pull request #14 from sandialabs/8-support-down-to-python-3.8
Support down to Python 3.8
2 parents 07bf054 + 0c69f03 commit 33277c4

5 files changed

+30
-22
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
.vscode
2+
.coverage
3+
coverage.json
4+
coverage.xml
5+
**/__pycache__

staged_script/staged_script.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from datetime import datetime, timedelta, timezone
2525
from pathlib import Path
2626
from subprocess import CompletedProcess
27-
from typing import Callable, NamedTuple
27+
from typing import Callable, Dict, List, NamedTuple, Optional, Set
2828

2929
import __main__
3030
import rich.traceback
@@ -122,14 +122,14 @@ class StagedScript:
122122
Attributes:
123123
args (Namespace): The parsed command line arguments for the
124124
script.
125-
commands_executed (list[str]): The commands that were executed
125+
commands_executed (List[str]): The commands that were executed
126126
in the shell.
127127
console (Console): Used to print rich text to the console.
128128
current_stage (str): The name of the stage being run.
129129
dry_run (bool): If ``True``, don't actually run the command
130130
that would be executed in the shell; instead just print it
131131
out.
132-
durations (list[StageDuration]): A mapping from stage names to
132+
durations (List[StageDuration]): A mapping from stage names to
133133
how long it took for each to run. This is implemented as a
134134
``list`` of named tuples instead of as a ``dict`` to allow
135135
the flexibility for stages to be run multiple times.
@@ -145,12 +145,12 @@ class StagedScript:
145145
script_success (bool): Subclass developers can toggle this
146146
attribute to indicate whether the script has succeeded.
147147
stage_start_time (datetime): The time at which a stage began.
148-
stages (set[str]): The stages registered for an instantiation
148+
stages (Set[str]): The stages registered for an instantiation
149149
of a :class:`StagedScript` subclass, which are used to
150150
automatically populate pieces of the
151151
:class:`ArgumentParser`. This may be a subset of all the
152152
stages defined in the subclass.
153-
stages_to_run (set[str]): Which stages to run, as specified by
153+
stages_to_run (Set[str]): Which stages to run, as specified by
154154
the user via the command line arguments.
155155
start_time (datetime): The time at which this object was
156156
initialized.
@@ -176,9 +176,9 @@ class StagedScript:
176176

177177
def __init__(
178178
self,
179-
stages: set[str],
179+
stages: Set[str],
180180
*,
181-
console_force_terminal: bool | None = None,
181+
console_force_terminal: Optional[bool] = None,
182182
console_log_path: bool = True,
183183
print_commands: bool = True,
184184
):
@@ -207,20 +207,20 @@ def __init__(
207207
for stage in stages:
208208
self._validate_stage_name(stage)
209209
self.args = Namespace()
210-
self.commands_executed: list[str] = []
210+
self.commands_executed: List[str] = []
211211
self.console = Console(
212212
force_terminal=console_force_terminal, log_path=console_log_path
213213
)
214214
self.current_stage = "CURRENT STAGE NOT SET"
215215
self.dry_run = False
216-
self.durations: list[StageDuration] = []
216+
self.durations: List[StageDuration] = []
217217
self.print_commands = print_commands
218218
self.script_name = Path(__main__.__file__).name
219219
self.script_stem = Path(__main__.__file__).stem
220220
self.script_success = True
221221
self.stage_start_time = datetime.now(tz=timezone.utc)
222222
self.stages = stages
223-
self.stages_to_run: set[str] = set()
223+
self.stages_to_run: Set[str] = set()
224224
self.start_time = datetime.now(tz=timezone.utc)
225225

226226
@staticmethod
@@ -364,7 +364,7 @@ def parser(self) -> ArgumentParser:
364364
setattr(self, f"{stage}_retry_timeout_arg", retry_timeout)
365365
return ap
366366

367-
def parse_args(self, argv: list[str]) -> None:
367+
def parse_args(self, argv: List[str]) -> None:
368368
"""
369369
Parse the command line arguments.
370370
@@ -376,7 +376,7 @@ def parse_args(self, argv: list[str]) -> None:
376376
377377
.. code-block:: python
378378
379-
def parse_args(self, argv: list[str]) -> None:
379+
def parse_args(self, argv: List[str]) -> None:
380380
super().parse_args(argv)
381381
# Parse additional arguments and store as attributes.
382382
self.foo = self.args.foo
@@ -912,7 +912,7 @@ def print_heading(self, message: str, *, color: str = "cyan") -> None:
912912
self.console.log(Panel(f"[bold]{message}", style=color))
913913

914914
def print_script_execution_summary(
915-
self, extra_sections: dict[str, str] | None = None
915+
self, extra_sections: Optional[Dict[str, str]] = None
916916
) -> None:
917917
"""
918918
Print a summary of everything that was done by the script.
@@ -934,11 +934,11 @@ def print_script_execution_summary(
934934
935935
def print_script_execution_summary(
936936
self,
937-
extra_sections: dict[str, str] | None = None
937+
extra_sections: Optional[Dict[str, str]] = None
938938
) -> None:
939939
extras = {"Additional section": "With some details."}
940940
if extra_sections is not None:
941-
extras |= extra_sections
941+
extras.update(extra_sections)
942942
super().print_script_execution_summary(
943943
extra_sections=extras
944944
)
@@ -955,7 +955,7 @@ def print_script_execution_summary(
955955
),
956956
}
957957
if extra_sections is not None:
958-
sections |= extra_sections
958+
sections.update(extra_sections)
959959
items = [""]
960960
for section, details in sections.items():
961961
items.extend([f"➤ {section}:", Padding(details, (1, 0, 1, 4))])
@@ -969,7 +969,7 @@ def run(
969969
command: str,
970970
*,
971971
pretty_print: bool = False,
972-
print_command: bool | None = None,
972+
print_command: Optional[bool] = None,
973973
**kwargs,
974974
) -> CompletedProcess:
975975
"""
@@ -1028,7 +1028,7 @@ def _get_timing_report(self) -> Table:
10281028
return table
10291029

10301030
@staticmethod
1031-
def _current_arg_is_long_flag(args: list[str]) -> bool:
1031+
def _current_arg_is_long_flag(args: List[str]) -> bool:
10321032
"""
10331033
Determine if the first argument in the list is a long flag.
10341034
@@ -1041,7 +1041,7 @@ def _current_arg_is_long_flag(args: list[str]) -> bool:
10411041
return len(args) > 0 and args[0].startswith("--")
10421042

10431043
@staticmethod
1044-
def _next_arg_is_flag(args: list[str]) -> bool:
1044+
def _next_arg_is_flag(args: List[str]) -> bool:
10451045
"""
10461046
Determine if the second argument in the list is a flag.
10471047

test/test_staged_script.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import shlex
1010
from datetime import datetime, timedelta, timezone
1111
from subprocess import CompletedProcess
12+
from typing import Dict, Optional
1213
from unittest.mock import MagicMock, patch
1314

1415
import pytest
@@ -239,7 +240,7 @@ def test_run_override_print_commands(
239240
)
240241
def test_print_script_execution_summary(
241242
mock_get_pretty_command_line_invocation: MagicMock,
242-
extras: dict[str, str] | None,
243+
extras: Optional[Dict[str, str]],
243244
script_success: bool, # noqa: FBT001
244245
script: StagedScript,
245246
capsys: pytest.CaptureFixture,

test/test_staged_script_advanced_subclass.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import pytest
1212
from rich.console import Console
1313
from tenacity import RetryCallState, Retrying, TryAgain
14+
from typing import Set
1415

1516
from staged_script import StagedScript
1617

@@ -103,7 +104,7 @@ def ensure_phase_comes_next(
103104
@pytest.mark.parametrize("custom_pre_stage", [True, False])
104105
@pytest.mark.parametrize("stages_to_run", [{"test"}, set()])
105106
def test_stage( # noqa: PLR0913
106-
stages_to_run: set[str],
107+
stages_to_run: Set[str],
107108
custom_pre_stage: bool, # noqa: FBT001
108109
custom_begin_stage: bool, # noqa: FBT001
109110
custom_skip_stage: bool, # noqa: FBT001

test/test_staged_script_basic_subclass.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
# SPDX-License-Identifier: BSD-3-Clause
88

9+
from typing import Set
10+
911
import pytest
1012
from rich.console import Console
1113

@@ -49,7 +51,7 @@ def script() -> MyBasicScript:
4951

5052
@pytest.mark.parametrize("stages_to_run", [{"good"}, set()])
5153
def test_good_stage(
52-
stages_to_run: set[str],
54+
stages_to_run: Set[str],
5355
script: MyBasicScript,
5456
capsys: pytest.CaptureFixture,
5557
) -> None:

0 commit comments

Comments
 (0)