protoprimer 0.12.0.dev1__tar.gz → 0.12.1.dev0__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.
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/PKG-INFO +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer/primer_kernel.py +426 -242
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/PKG-INFO +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/pyproject.toml +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer/__init__.py +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer/proto_generator.py +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/SOURCES.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/dependency_links.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/requires.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/top_level.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protoprimer
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.1.dev0
|
|
4
4
|
Summary: Escape the fragile mess of pre-venv shell scripts with a pure Python bootstrap wrapper: 🚀 ⏩ single-touch, zero-args, self-contained, no-deps, cross-platform, testable init logic using standard tools to run apps in a custom environment isolated per repository
|
|
5
5
|
Author-email: uvsmtid <uvsmtid@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -52,7 +52,7 @@ from typing import (
|
|
|
52
52
|
|
|
53
53
|
# The release process ensures that content in this file matches the version below while tagging the release commit
|
|
54
54
|
# (otherwise, if the file comes from a different commit, the version is irrelevant):
|
|
55
|
-
__version__ = "0.12.
|
|
55
|
+
__version__ = "0.12.1.dev0"
|
|
56
56
|
|
|
57
57
|
logger: logging.Logger = logging.getLogger()
|
|
58
58
|
|
|
@@ -67,8 +67,8 @@ def run_process(env_ctx: EnvContext) -> None:
|
|
|
67
67
|
try:
|
|
68
68
|
ensure_min_python_version()
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
assert
|
|
70
|
+
state_everything_executed: bool = env_ctx.state_graph.eval_state(TargetState.target_everything_executed.value.name)
|
|
71
|
+
assert state_everything_executed
|
|
72
72
|
atexit.register(lambda: env_ctx.print_exit_line(0))
|
|
73
73
|
|
|
74
74
|
except subprocess.CalledProcessError as subproc_error:
|
|
@@ -482,6 +482,10 @@ class ValueName(enum.Enum):
|
|
|
482
482
|
|
|
483
483
|
value_version = "version"
|
|
484
484
|
|
|
485
|
+
value_file_basename = "file_basename"
|
|
486
|
+
|
|
487
|
+
value_version_constraints = "version_constraints"
|
|
488
|
+
|
|
485
489
|
|
|
486
490
|
class PathName(enum.Enum):
|
|
487
491
|
|
|
@@ -639,6 +643,9 @@ class ConfField(enum.Enum):
|
|
|
639
643
|
# state_venv_driver_inited:
|
|
640
644
|
field_venv_driver = f"{ValueName.value_venv_driver.value}"
|
|
641
645
|
|
|
646
|
+
# state_version_constraints_file_basename_inited:
|
|
647
|
+
field_version_constraints_file_basename = f"{ValueName.value_version_constraints.value}_{ValueName.value_file_basename.value}"
|
|
648
|
+
|
|
642
649
|
# parent of `field_build_root_dir_rel_path` & `field_install_extras`:
|
|
643
650
|
# state_project_descriptors_inited:
|
|
644
651
|
field_project_descriptors = f"{ValueName.value_project_descriptors.value}"
|
|
@@ -1314,8 +1321,8 @@ class ConfConstGeneral:
|
|
|
1314
1321
|
relative_path_field_note: str = f"The path is relative to the `{PathName.path_ref_root.value}` dir specified in the `{ConfField.field_ref_root_dir_rel_path.value}` field."
|
|
1315
1322
|
common_field_global_note: str = f"This field can be specified in global config (see `{ConfLeap.leap_client.name}`) but it is override-able by local environment-specific config (see `{ConfLeap.leap_env.name}`)."
|
|
1316
1323
|
common_field_local_note: str = f"This local environment-specific field overrides the global one (see description in `{ConfLeap.leap_client.name}`)."
|
|
1317
|
-
func_note_derived_based_on_common = lambda field_name:
|
|
1318
|
-
func_note_derived_based_on_conf_leap_field = lambda field_name, conf_leap:
|
|
1324
|
+
func_note_derived_based_on_common = lambda field_name: f"This value is derived from `{field_name}` in `{ConfLeap.leap_client.name}` (override-able in `{ConfLeap.leap_env.name}`) - see description there."
|
|
1325
|
+
func_note_derived_based_on_conf_leap_field = lambda field_name, conf_leap: f"This value is derived from `{field_name}` - see description in `{conf_leap.name}`."
|
|
1319
1326
|
|
|
1320
1327
|
|
|
1321
1328
|
class ConfConstInput:
|
|
@@ -1406,6 +1413,8 @@ class ConfConstEnv:
|
|
|
1406
1413
|
# The default is `uv` only if it is supported by the selected `python` version:
|
|
1407
1414
|
default_venv_driver = VenvDriverType.venv_uv.name
|
|
1408
1415
|
|
|
1416
|
+
default_version_constraints_file_basename = "constraints.txt"
|
|
1417
|
+
|
|
1409
1418
|
default_project_descriptors = [
|
|
1410
1419
|
{
|
|
1411
1420
|
ConfField.field_build_root_dir_rel_path.value: ".",
|
|
@@ -1416,8 +1425,6 @@ class ConfConstEnv:
|
|
|
1416
1425
|
|
|
1417
1426
|
default_install_specs = []
|
|
1418
1427
|
|
|
1419
|
-
constraints_txt_basename = "constraints.txt"
|
|
1420
|
-
|
|
1421
1428
|
# FT_84_11_73_28.supported_python_versions.md:
|
|
1422
1429
|
latest_known_python_version = "3.14"
|
|
1423
1430
|
|
|
@@ -1463,6 +1470,15 @@ def _create_parent_argparser():
|
|
|
1463
1470
|
default=0,
|
|
1464
1471
|
help="Increase log verbosity level.",
|
|
1465
1472
|
)
|
|
1473
|
+
parent_argparser.add_argument(
|
|
1474
|
+
SyntaxArg.arg_e,
|
|
1475
|
+
SyntaxArg.arg_env,
|
|
1476
|
+
type=str,
|
|
1477
|
+
default=None,
|
|
1478
|
+
dest=ParsedArg.name_selected_env_dir.value,
|
|
1479
|
+
metavar=ParsedArg.name_selected_env_dir.value,
|
|
1480
|
+
help="Path to the env-specific config dir.",
|
|
1481
|
+
)
|
|
1466
1482
|
return parent_argparser
|
|
1467
1483
|
|
|
1468
1484
|
|
|
@@ -1475,21 +1491,6 @@ def _create_child_argparser(parent_argparsers):
|
|
|
1475
1491
|
description=sub_command_desc,
|
|
1476
1492
|
)
|
|
1477
1493
|
parser_boot.set_defaults(sub_command=SubCommand.command_boot.value)
|
|
1478
|
-
parser_boot.add_argument(
|
|
1479
|
-
SyntaxArg.arg_e,
|
|
1480
|
-
SyntaxArg.arg_env,
|
|
1481
|
-
type=str,
|
|
1482
|
-
default=None,
|
|
1483
|
-
dest=ParsedArg.name_selected_env_dir.value,
|
|
1484
|
-
metavar=ParsedArg.name_selected_env_dir.value,
|
|
1485
|
-
help=(
|
|
1486
|
-
f"Path to the env-specific config dir. "
|
|
1487
|
-
f"If specified, `{SubCommand.command_boot.value}` sub command creates the symlink to that dir. "
|
|
1488
|
-
f"If not specified, the existing symlink is reused. "
|
|
1489
|
-
#
|
|
1490
|
-
),
|
|
1491
|
-
)
|
|
1492
|
-
|
|
1493
1494
|
parser_boot.add_argument(
|
|
1494
1495
|
SyntaxArg.arg_c,
|
|
1495
1496
|
SyntaxArg.arg_command,
|
|
@@ -1542,7 +1543,7 @@ def _create_child_argparser(parent_argparsers):
|
|
|
1542
1543
|
parser_check.set_defaults(sub_command=SubCommand.command_check.value)
|
|
1543
1544
|
|
|
1544
1545
|
child_argparser = CustomArgumentParser(
|
|
1545
|
-
description=
|
|
1546
|
+
description=f"The early [{PrimerRuntime.runtime_proto.value}] environment bootstrapper [{KeyWord.key_primer.value}].",
|
|
1546
1547
|
parents=parent_argparsers,
|
|
1547
1548
|
epilog=f"Version: {__version__} | {ConfConstGeneral.name_protoprimer_site_link} | {pathlib.Path(__file__).resolve()}",
|
|
1548
1549
|
)
|
|
@@ -1942,45 +1943,58 @@ class Bootstrapper_state_default_stderr_log_handler_configured(AbstractCachingSt
|
|
|
1942
1943
|
|
|
1943
1944
|
|
|
1944
1945
|
# noinspection PyPep8Naming
|
|
1945
|
-
@
|
|
1946
|
-
class
|
|
1946
|
+
@conditional_factory
|
|
1947
|
+
class Bootstrapper_state_args_parsed_func_boot_env(AbstractCachingStateNode[argparse.Namespace]):
|
|
1948
|
+
|
|
1949
|
+
_state_name = staticmethod(lambda: EnvState.state_args_parsed.name)
|
|
1950
|
+
|
|
1951
|
+
def _eval_state_once(self) -> ValueType:
|
|
1952
|
+
return parse_args()
|
|
1953
|
+
|
|
1954
|
+
|
|
1955
|
+
# noinspection PyPep8Naming
|
|
1956
|
+
@conditional_factory
|
|
1957
|
+
class Bootstrapper_state_args_parsed_not_func_boot_env(AbstractCachingStateNode[argparse.Namespace]):
|
|
1947
1958
|
|
|
1948
1959
|
_state_name = staticmethod(lambda: EnvState.state_args_parsed.name)
|
|
1949
1960
|
|
|
1950
1961
|
def _eval_state_once(self) -> ValueType:
|
|
1951
|
-
"""
|
|
1952
|
-
Parse the args if `EntryFunc.func_boot_env` or `EntryFunc.func_run_main`.
|
|
1953
|
-
Otherwise, pretend there are no args except `SubCommand.command_start`.
|
|
1954
|
-
"""
|
|
1955
1962
|
# TODO: TODO_60_63_68_81.refactor_DAG_builder.md:
|
|
1956
1963
|
# This step should not be executed without need to parse args.
|
|
1957
1964
|
# Do not fake args. Just redesign dependency. No?
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
state_args_parsed,
|
|
1966
|
-
ParsedArg.name_sub_command.value,
|
|
1967
|
-
SubCommand.command_start.value,
|
|
1968
|
-
)
|
|
1965
|
+
# Pretend there is no args except `SubCommand.command_start`:
|
|
1966
|
+
state_args_parsed: argparse.Namespace = parse_args([])
|
|
1967
|
+
setattr(
|
|
1968
|
+
state_args_parsed,
|
|
1969
|
+
ParsedArg.name_sub_command.value,
|
|
1970
|
+
SubCommand.command_start.value,
|
|
1971
|
+
)
|
|
1969
1972
|
return state_args_parsed
|
|
1970
1973
|
|
|
1971
1974
|
|
|
1975
|
+
# noinspection PyPep8Naming
|
|
1976
|
+
class Factory_state_args_parsed(NodeFactory[StateStride]):
|
|
1977
|
+
|
|
1978
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
1979
|
+
# TODO: TODO_60_63_68_81.refactor_DAG_builder.md:
|
|
1980
|
+
# This step should not be executed without need to parse args.
|
|
1981
|
+
# Do not fake args. Just redesign dependency. No?
|
|
1982
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
1983
|
+
EntryFunc.func_boot_env,
|
|
1984
|
+
EntryFunc.func_run_main,
|
|
1985
|
+
]:
|
|
1986
|
+
return Bootstrapper_state_args_parsed_func_boot_env(self.env_ctx)
|
|
1987
|
+
else:
|
|
1988
|
+
return Bootstrapper_state_args_parsed_not_func_boot_env(self.env_ctx)
|
|
1989
|
+
|
|
1990
|
+
|
|
1972
1991
|
# noinspection PyPep8Naming
|
|
1973
1992
|
@trivial_factory
|
|
1974
1993
|
class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingStateNode[int]):
|
|
1975
|
-
"""
|
|
1976
|
-
There is a narrow window between the default log level is set and this state is evaluated.
|
|
1977
|
-
To control the default log level, see `EnvVar.var_PROTOPRIMER_STDERR_LOG_LEVEL`.
|
|
1978
|
-
"""
|
|
1979
1994
|
|
|
1980
1995
|
_parent_states = staticmethod(
|
|
1981
1996
|
lambda: [
|
|
1982
1997
|
EnvState.state_input_stderr_log_level_var_loaded.name,
|
|
1983
|
-
EnvState.state_default_stderr_log_handler_configured.name,
|
|
1984
1998
|
EnvState.state_args_parsed.name,
|
|
1985
1999
|
]
|
|
1986
2000
|
)
|
|
@@ -1990,8 +2004,6 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
1990
2004
|
|
|
1991
2005
|
state_input_stderr_log_level_var_loaded: int = self.eval_parent_state(EnvState.state_input_stderr_log_level_var_loaded.name)
|
|
1992
2006
|
|
|
1993
|
-
state_default_stderr_logger_configured: logging.Handler = self.eval_parent_state(EnvState.state_default_stderr_log_handler_configured.name)
|
|
1994
|
-
|
|
1995
2007
|
parsed_args = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
1996
2008
|
stderr_log_level_quiet_count: int = getattr(
|
|
1997
2009
|
parsed_args,
|
|
@@ -2002,9 +2014,9 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
2002
2014
|
SyntaxArg.dest_verbose,
|
|
2003
2015
|
)
|
|
2004
2016
|
|
|
2005
|
-
|
|
2017
|
+
state_input_stderr_log_level_eval_finalized: int
|
|
2006
2018
|
if stderr_log_level_quiet_count == 0 and stderr_log_level_verbose_count == 0:
|
|
2007
|
-
|
|
2019
|
+
state_input_stderr_log_level_eval_finalized = state_input_stderr_log_level_var_loaded
|
|
2008
2020
|
else:
|
|
2009
2021
|
# FT_38_73_38_52.log_verbosity.md
|
|
2010
2022
|
# The base is the numeric value of `ConfConstInput.default_PROTOPRIMER_STDERR_LOG_LEVEL`.
|
|
@@ -2015,37 +2027,50 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
2015
2027
|
|
|
2016
2028
|
relative_log_level = 10 * (stderr_log_level_quiet_count - stderr_log_level_verbose_count)
|
|
2017
2029
|
|
|
2018
|
-
|
|
2030
|
+
state_input_stderr_log_level_eval_finalized = base_log_level + relative_log_level
|
|
2019
2031
|
|
|
2020
|
-
if
|
|
2021
|
-
|
|
2032
|
+
if state_input_stderr_log_level_eval_finalized < logging.NOTSET:
|
|
2033
|
+
state_input_stderr_log_level_eval_finalized = logging.NOTSET
|
|
2022
2034
|
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2035
|
+
return state_input_stderr_log_level_eval_finalized
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
# noinspection PyPep8Naming
|
|
2039
|
+
@trivial_factory
|
|
2040
|
+
class Bootstrapper_state_input_stderr_log_level_handler_configured(AbstractCachingStateNode[logging.Handler]):
|
|
2041
|
+
"""
|
|
2042
|
+
There is a narrow window between the default log level is set and this state is evaluated.
|
|
2043
|
+
To control the default log level, see `EnvVar.var_PROTOPRIMER_STDERR_LOG_LEVEL`.
|
|
2044
|
+
"""
|
|
2045
|
+
|
|
2046
|
+
_parent_states = staticmethod(
|
|
2047
|
+
lambda: [
|
|
2048
|
+
EnvState.state_default_stderr_log_handler_configured.name,
|
|
2049
|
+
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2050
|
+
]
|
|
2051
|
+
)
|
|
2052
|
+
_state_name = staticmethod(lambda: EnvState.state_input_stderr_log_level_handler_configured.name)
|
|
2053
|
+
|
|
2054
|
+
def _eval_state_once(self) -> ValueType:
|
|
2026
2055
|
|
|
2027
|
-
state_default_stderr_logger_configured.
|
|
2056
|
+
state_default_stderr_logger_configured: logging.Handler = self.eval_parent_state(EnvState.state_default_stderr_log_handler_configured.name)
|
|
2057
|
+
|
|
2058
|
+
state_input_stderr_log_level_eval_finalized: int = self.eval_parent_state(EnvState.state_input_stderr_log_level_eval_finalized.name)
|
|
2059
|
+
|
|
2060
|
+
state_default_stderr_logger_configured.setLevel(state_input_stderr_log_level_eval_finalized)
|
|
2028
2061
|
assert isinstance(
|
|
2029
2062
|
state_default_stderr_logger_configured.formatter,
|
|
2030
2063
|
_PrimerStderrLogFormatter,
|
|
2031
2064
|
)
|
|
2032
|
-
state_default_stderr_logger_configured.formatter.set_verbosity_level(
|
|
2033
|
-
|
|
2034
|
-
# Set default log level for subsequent invocations:
|
|
2035
|
-
level_var_value: str = logging.getLevelName(stderr_log_level_eval_finalized)
|
|
2036
|
-
assert isinstance(level_var_value, str)
|
|
2037
|
-
if " " in level_var_value:
|
|
2038
|
-
# Due to some hacks in the `python` `logging` library,
|
|
2039
|
-
# it may return non-existing level names - use number instead:
|
|
2040
|
-
level_var_value = str(stderr_log_level_eval_finalized)
|
|
2065
|
+
state_default_stderr_logger_configured.formatter.set_verbosity_level(state_input_stderr_log_level_eval_finalized)
|
|
2041
2066
|
|
|
2042
2067
|
# Remove stack trace for levels >= WARNING (it will only print the exception itself):
|
|
2043
|
-
if
|
|
2068
|
+
if state_input_stderr_log_level_eval_finalized >= logging.WARNING:
|
|
2044
2069
|
# Avoid changing that in tests - it changes the global state and causes many tests to fail unexpectedly:
|
|
2045
2070
|
if not is_test_run():
|
|
2046
2071
|
sys.tracebacklimit = 0
|
|
2047
2072
|
|
|
2048
|
-
return
|
|
2073
|
+
return state_default_stderr_logger_configured
|
|
2049
2074
|
|
|
2050
2075
|
|
|
2051
2076
|
# noinspection PyPep8Naming
|
|
@@ -2074,13 +2099,12 @@ class Bootstrapper_state_input_sub_command_arg_loaded(AbstractCachingStateNode[S
|
|
|
2074
2099
|
|
|
2075
2100
|
|
|
2076
2101
|
# noinspection PyPep8Naming
|
|
2077
|
-
@
|
|
2078
|
-
class
|
|
2102
|
+
@conditional_factory
|
|
2103
|
+
class Bootstrapper_state_input_final_state_eval_finalized_func_boot_env(AbstractCachingStateNode[str]):
|
|
2079
2104
|
|
|
2080
2105
|
_parent_states = staticmethod(
|
|
2081
2106
|
lambda: [
|
|
2082
2107
|
EnvState.state_args_parsed.name,
|
|
2083
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2084
2108
|
]
|
|
2085
2109
|
)
|
|
2086
2110
|
_state_name = staticmethod(lambda: EnvState.state_input_final_state_eval_finalized.name)
|
|
@@ -2088,8 +2112,6 @@ class Bootstrapper_state_input_final_state_eval_finalized(AbstractCachingStateNo
|
|
|
2088
2112
|
def _eval_state_once(self) -> ValueType:
|
|
2089
2113
|
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
2090
2114
|
|
|
2091
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2092
|
-
|
|
2093
2115
|
state_input_final_state_eval_finalized: str | None
|
|
2094
2116
|
state_input_final_state_eval_finalized = getattr(
|
|
2095
2117
|
state_args_parsed,
|
|
@@ -2107,33 +2129,55 @@ class Bootstrapper_state_input_final_state_eval_finalized(AbstractCachingStateNo
|
|
|
2107
2129
|
return state_input_final_state_eval_finalized
|
|
2108
2130
|
|
|
2109
2131
|
|
|
2132
|
+
# noinspection PyPep8Naming
|
|
2133
|
+
@conditional_factory
|
|
2134
|
+
class Bootstrapper_state_input_final_state_eval_finalized_not_func_boot_env(AbstractCachingStateNode[str]):
|
|
2135
|
+
|
|
2136
|
+
_parent_states = staticmethod(lambda: [])
|
|
2137
|
+
_state_name = staticmethod(lambda: EnvState.state_input_final_state_eval_finalized.name)
|
|
2138
|
+
|
|
2139
|
+
def _eval_state_once(self) -> ValueType:
|
|
2140
|
+
state_input_final_state_eval_finalized = self.env_ctx.final_state
|
|
2141
|
+
return state_input_final_state_eval_finalized
|
|
2142
|
+
|
|
2143
|
+
|
|
2144
|
+
# noinspection PyPep8Naming
|
|
2145
|
+
class Factory_state_input_final_state_eval_finalized(NodeFactory[StateStride]):
|
|
2146
|
+
|
|
2147
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2148
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2149
|
+
EntryFunc.func_boot_env,
|
|
2150
|
+
EntryFunc.func_run_main,
|
|
2151
|
+
]:
|
|
2152
|
+
return Bootstrapper_state_input_final_state_eval_finalized_func_boot_env(self.env_ctx)
|
|
2153
|
+
else:
|
|
2154
|
+
return Bootstrapper_state_input_final_state_eval_finalized_not_func_boot_env(self.env_ctx)
|
|
2155
|
+
|
|
2156
|
+
|
|
2110
2157
|
# noinspection PyPep8Naming
|
|
2111
2158
|
@trivial_factory
|
|
2112
|
-
class
|
|
2159
|
+
class Bootstrapper_state_func_boot_env_executed(AbstractCachingStateNode[bool]):
|
|
2113
2160
|
"""
|
|
2114
|
-
This is a special node - it traverses ALL nodes.
|
|
2161
|
+
This is a special node - it traverses ALL nodes for `EntryFunc` cases with parsed args.
|
|
2115
2162
|
|
|
2116
|
-
BUT: It does not depend on ALL nodes - instead,
|
|
2163
|
+
BUT: It does not depend on ALL nodes - instead, re-executes the graph with a new target.
|
|
2117
2164
|
"""
|
|
2118
2165
|
|
|
2119
2166
|
_parent_states = staticmethod(
|
|
2120
2167
|
lambda: [
|
|
2121
|
-
EnvState.
|
|
2168
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
2122
2169
|
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2123
2170
|
EnvState.state_input_final_state_eval_finalized.name,
|
|
2124
2171
|
]
|
|
2125
2172
|
)
|
|
2126
|
-
_state_name = staticmethod(lambda: EnvState.
|
|
2173
|
+
_state_name = staticmethod(lambda: EnvState.state_func_boot_env_executed.name)
|
|
2127
2174
|
|
|
2128
2175
|
def _eval_state_once(self) -> ValueType:
|
|
2129
2176
|
|
|
2130
|
-
|
|
2131
|
-
assert state_input_stderr_log_level_eval_finalized >= 0
|
|
2177
|
+
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2132
2178
|
|
|
2133
2179
|
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2134
2180
|
|
|
2135
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2136
|
-
|
|
2137
2181
|
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2138
2182
|
|
|
2139
2183
|
selected_strategy: RunStrategy
|
|
@@ -2156,6 +2200,111 @@ class Bootstrapper_state_sub_command_executed(AbstractCachingStateNode[bool]):
|
|
|
2156
2200
|
return True
|
|
2157
2201
|
|
|
2158
2202
|
|
|
2203
|
+
# noinspection PyPep8Naming
|
|
2204
|
+
@trivial_factory
|
|
2205
|
+
class Bootstrapper_state_func_start_app_executed(AbstractCachingStateNode[bool]):
|
|
2206
|
+
|
|
2207
|
+
_parent_states = staticmethod(
|
|
2208
|
+
lambda: [
|
|
2209
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
2210
|
+
EnvState.state_input_final_state_eval_finalized.name,
|
|
2211
|
+
]
|
|
2212
|
+
)
|
|
2213
|
+
_state_name = staticmethod(lambda: EnvState.state_func_start_app_executed.name)
|
|
2214
|
+
|
|
2215
|
+
def _eval_state_once(self) -> ValueType:
|
|
2216
|
+
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2217
|
+
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2218
|
+
state_node.eval_own_state()
|
|
2219
|
+
return True
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
# noinspection PyPep8Naming
|
|
2223
|
+
@trivial_factory
|
|
2224
|
+
class Bootstrapper_state_func_call_lib_executed(AbstractCachingStateNode[bool]):
|
|
2225
|
+
|
|
2226
|
+
_parent_states = staticmethod(
|
|
2227
|
+
lambda: [
|
|
2228
|
+
EnvState.state_input_final_state_eval_finalized.name,
|
|
2229
|
+
]
|
|
2230
|
+
)
|
|
2231
|
+
_state_name = staticmethod(lambda: EnvState.state_func_call_lib_executed.name)
|
|
2232
|
+
|
|
2233
|
+
def _eval_state_once(self) -> ValueType:
|
|
2234
|
+
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2235
|
+
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2236
|
+
state_node.eval_own_state()
|
|
2237
|
+
return True
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
# noinspection PyPep8Naming
|
|
2241
|
+
@conditional_factory
|
|
2242
|
+
class Bootstrapper_state_everything_executed_func_boot_env(AbstractCachingStateNode[bool]):
|
|
2243
|
+
|
|
2244
|
+
_parent_states = staticmethod(
|
|
2245
|
+
lambda: [
|
|
2246
|
+
EnvState.state_func_boot_env_executed.name,
|
|
2247
|
+
]
|
|
2248
|
+
)
|
|
2249
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2250
|
+
|
|
2251
|
+
def _eval_state_once(self) -> ValueType:
|
|
2252
|
+
state_func_boot_env_executed: bool = self.eval_parent_state(EnvState.state_func_boot_env_executed.name)
|
|
2253
|
+
return state_func_boot_env_executed
|
|
2254
|
+
|
|
2255
|
+
|
|
2256
|
+
# noinspection PyPep8Naming
|
|
2257
|
+
@conditional_factory
|
|
2258
|
+
class Bootstrapper_state_everything_executed_func_start_app(AbstractCachingStateNode[bool]):
|
|
2259
|
+
|
|
2260
|
+
_parent_states = staticmethod(
|
|
2261
|
+
lambda: [
|
|
2262
|
+
EnvState.state_func_start_app_executed.name,
|
|
2263
|
+
]
|
|
2264
|
+
)
|
|
2265
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2266
|
+
|
|
2267
|
+
def _eval_state_once(self) -> ValueType:
|
|
2268
|
+
state_func_start_app_executed: bool = self.eval_parent_state(EnvState.state_func_start_app_executed.name)
|
|
2269
|
+
return state_func_start_app_executed
|
|
2270
|
+
|
|
2271
|
+
|
|
2272
|
+
# noinspection PyPep8Naming
|
|
2273
|
+
@conditional_factory
|
|
2274
|
+
class Bootstrapper_state_everything_executed_func_call_lib(AbstractCachingStateNode[bool]):
|
|
2275
|
+
|
|
2276
|
+
_parent_states = staticmethod(
|
|
2277
|
+
lambda: [
|
|
2278
|
+
EnvState.state_func_call_lib_executed.name,
|
|
2279
|
+
]
|
|
2280
|
+
)
|
|
2281
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2282
|
+
|
|
2283
|
+
def _eval_state_once(self) -> ValueType:
|
|
2284
|
+
state_func_call_lib_executed: bool = self.eval_parent_state(EnvState.state_func_call_lib_executed.name)
|
|
2285
|
+
return state_func_call_lib_executed
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
# noinspection PyPep8Naming
|
|
2289
|
+
class Factory_state_everything_executed(NodeFactory[StateStride]):
|
|
2290
|
+
"""
|
|
2291
|
+
This is a special node - it traverses ALL nodes.
|
|
2292
|
+
"""
|
|
2293
|
+
|
|
2294
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2295
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2296
|
+
EntryFunc.func_boot_env,
|
|
2297
|
+
EntryFunc.func_run_main,
|
|
2298
|
+
]:
|
|
2299
|
+
return Bootstrapper_state_everything_executed_func_boot_env(self.env_ctx)
|
|
2300
|
+
elif self.env_ctx.graph_coordinates.entry_func == EntryFunc.func_start_app:
|
|
2301
|
+
return Bootstrapper_state_everything_executed_func_start_app(self.env_ctx)
|
|
2302
|
+
elif self.env_ctx.graph_coordinates.entry_func == EntryFunc.func_call_lib:
|
|
2303
|
+
return Bootstrapper_state_everything_executed_func_call_lib(self.env_ctx)
|
|
2304
|
+
else:
|
|
2305
|
+
raise RuntimeError(self.env_ctx.graph_coordinates.entry_func)
|
|
2306
|
+
|
|
2307
|
+
|
|
2159
2308
|
# noinspection PyPep8Naming
|
|
2160
2309
|
@trivial_factory
|
|
2161
2310
|
class Bootstrapper_state_input_start_id_var_loaded(AbstractCachingStateNode[str]):
|
|
@@ -2280,7 +2429,6 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_func_call_lib(AbstractC
|
|
|
2280
2429
|
class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(AbstractCachingStateNode[str]):
|
|
2281
2430
|
_parent_states = staticmethod(
|
|
2282
2431
|
lambda: [
|
|
2283
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2284
2432
|
EnvState.state_input_proto_code_file_abs_path_var_loaded.name,
|
|
2285
2433
|
EnvState.state_stride_py_arbitrary_reached.name,
|
|
2286
2434
|
]
|
|
@@ -2289,10 +2437,6 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2289
2437
|
|
|
2290
2438
|
def _eval_state_once(self) -> ValueType:
|
|
2291
2439
|
|
|
2292
|
-
state_stride_py_arbitrary_reached: StateStride = self.eval_parent_state(EnvState.state_stride_py_arbitrary_reached.name)
|
|
2293
|
-
|
|
2294
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2295
|
-
|
|
2296
2440
|
state_input_proto_code_file_abs_path_var_loaded: str | None = self.eval_parent_state(EnvState.state_input_proto_code_file_abs_path_var_loaded.name)
|
|
2297
2441
|
|
|
2298
2442
|
assert self.env_ctx.get_stride().value >= StateStride.stride_py_arbitrary.value
|
|
@@ -2306,7 +2450,10 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2306
2450
|
else:
|
|
2307
2451
|
log_python_context()
|
|
2308
2452
|
if os.environ.get(EnvVar.var_PROTOPRIMER_MOCKED_RESTART.value, None) is None:
|
|
2309
|
-
if
|
|
2453
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2454
|
+
EntryFunc.func_boot_env,
|
|
2455
|
+
EntryFunc.func_run_main,
|
|
2456
|
+
]:
|
|
2310
2457
|
if self.env_ctx.get_stride().value == StateStride.stride_py_arbitrary.value:
|
|
2311
2458
|
state_proto_code_file_abs_path_inited = os.path.abspath(__file__)
|
|
2312
2459
|
else:
|
|
@@ -2324,7 +2471,7 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2324
2471
|
if is_venv():
|
|
2325
2472
|
logger.warning(f"`sys.executable` [{sys.executable}] for [{StateStride.stride_py_required.name}] evaluated from config should ideally be outside `venv`")
|
|
2326
2473
|
else:
|
|
2327
|
-
#
|
|
2474
|
+
# Rely only on the `EnvVar.var_PROTOPRIMER_PROTO_CODE` env var:
|
|
2328
2475
|
assert state_input_proto_code_file_abs_path_var_loaded is not None
|
|
2329
2476
|
state_proto_code_file_abs_path_inited = state_input_proto_code_file_abs_path_var_loaded
|
|
2330
2477
|
else:
|
|
@@ -2402,8 +2549,6 @@ class Bootstrapper_state_primer_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2402
2549
|
|
|
2403
2550
|
_parent_states = staticmethod(
|
|
2404
2551
|
lambda: [
|
|
2405
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2406
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2407
2552
|
EnvState.state_proto_code_file_abs_path_inited.name,
|
|
2408
2553
|
EnvState.state_primer_conf_file_abs_path_inited.name,
|
|
2409
2554
|
]
|
|
@@ -2564,8 +2709,6 @@ class Bootstrapper_state_client_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2564
2709
|
|
|
2565
2710
|
_parent_states = staticmethod(
|
|
2566
2711
|
lambda: [
|
|
2567
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2568
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2569
2712
|
EnvState.state_global_conf_file_abs_path_inited.name,
|
|
2570
2713
|
]
|
|
2571
2714
|
)
|
|
@@ -2600,17 +2743,8 @@ class Bootstrapper_state_client_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2600
2743
|
|
|
2601
2744
|
|
|
2602
2745
|
# noinspection PyPep8Naming
|
|
2603
|
-
@
|
|
2604
|
-
class
|
|
2605
|
-
|
|
2606
|
-
_parent_states = staticmethod(
|
|
2607
|
-
lambda: [
|
|
2608
|
-
EnvState.state_args_parsed.name,
|
|
2609
|
-
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2610
|
-
EnvState.state_client_conf_file_data_loaded.name,
|
|
2611
|
-
]
|
|
2612
|
-
)
|
|
2613
|
-
_state_name = staticmethod(lambda: EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
2746
|
+
@conditional_factory
|
|
2747
|
+
class Base_state_selected_env_dir_rel_path(AbstractCachingStateNode[str]):
|
|
2614
2748
|
|
|
2615
2749
|
def _eval_state_once(self) -> ValueType:
|
|
2616
2750
|
|
|
@@ -2641,14 +2775,14 @@ class Bootstrapper_state_selected_env_dir_rel_path_inited(AbstractCachingStateNo
|
|
|
2641
2775
|
|
|
2642
2776
|
return state_selected_env_dir_rel_path_inited
|
|
2643
2777
|
|
|
2778
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2779
|
+
raise NotImplementedError()
|
|
2780
|
+
|
|
2644
2781
|
def _select_client_local_env_dir_any_path(self) -> str | None:
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
# NOTE: The value is only set for `SubCommand.command_boot`, otherwise, this default is used:
|
|
2650
|
-
None,
|
|
2651
|
-
)
|
|
2782
|
+
"""
|
|
2783
|
+
TODO: TODO_41_10_50_01.implement_env_selector.md
|
|
2784
|
+
"""
|
|
2785
|
+
env_conf_dir_any_path = self._select_env_conf_dir_any_path()
|
|
2652
2786
|
if env_conf_dir_any_path is None:
|
|
2653
2787
|
# Use the default env configured:
|
|
2654
2788
|
state_client_conf_file_data_loaded: dict = self.eval_parent_state(EnvState.state_client_conf_file_data_loaded.name)
|
|
@@ -2696,13 +2830,65 @@ class Bootstrapper_state_selected_env_dir_rel_path_inited(AbstractCachingStateNo
|
|
|
2696
2830
|
raise AssertionError(f"`{PathName.path_selected_env.value}` [{client_local_env_dir_any_path}] is relative to neither `{PathName.path_ref_root.value}` [{state_ref_root_dir_abs_path_inited}] nor curr dir [{os.getcwd()}].")
|
|
2697
2831
|
|
|
2698
2832
|
|
|
2833
|
+
# noinspection PyPep8Naming
|
|
2834
|
+
@conditional_factory
|
|
2835
|
+
class Bootstrapper_state_selected_env_dir_rel_path_inited_func_boot_env(Base_state_selected_env_dir_rel_path):
|
|
2836
|
+
|
|
2837
|
+
_parent_states = staticmethod(
|
|
2838
|
+
lambda: [
|
|
2839
|
+
EnvState.state_args_parsed.name,
|
|
2840
|
+
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2841
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
2842
|
+
]
|
|
2843
|
+
)
|
|
2844
|
+
_state_name = staticmethod(lambda: EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
2845
|
+
|
|
2846
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2847
|
+
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
2848
|
+
env_conf_dir_any_path: str | None = getattr(
|
|
2849
|
+
state_args_parsed,
|
|
2850
|
+
ParsedArg.name_selected_env_dir.value,
|
|
2851
|
+
# NOTE: The value is only set for `SubCommand.command_boot`, otherwise, this default is used:
|
|
2852
|
+
None,
|
|
2853
|
+
)
|
|
2854
|
+
return env_conf_dir_any_path
|
|
2855
|
+
|
|
2856
|
+
|
|
2857
|
+
# noinspection PyPep8Naming
|
|
2858
|
+
@conditional_factory
|
|
2859
|
+
class Bootstrapper_state_selected_env_dir_rel_path_inited_not_func_boot_env(Base_state_selected_env_dir_rel_path):
|
|
2860
|
+
|
|
2861
|
+
_parent_states = staticmethod(
|
|
2862
|
+
lambda: [
|
|
2863
|
+
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2864
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
2865
|
+
]
|
|
2866
|
+
)
|
|
2867
|
+
_state_name = staticmethod(lambda: EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
2868
|
+
|
|
2869
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2870
|
+
return None
|
|
2871
|
+
|
|
2872
|
+
|
|
2873
|
+
# noinspection PyPep8Naming
|
|
2874
|
+
class Factory_state_selected_env_dir_rel_path_inited(NodeFactory[StateStride]):
|
|
2875
|
+
|
|
2876
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2877
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2878
|
+
EntryFunc.func_boot_env,
|
|
2879
|
+
EntryFunc.func_run_main,
|
|
2880
|
+
]:
|
|
2881
|
+
return Bootstrapper_state_selected_env_dir_rel_path_inited_func_boot_env(self.env_ctx)
|
|
2882
|
+
else:
|
|
2883
|
+
return Bootstrapper_state_selected_env_dir_rel_path_inited_not_func_boot_env(self.env_ctx)
|
|
2884
|
+
|
|
2885
|
+
|
|
2699
2886
|
# noinspection PyPep8Naming
|
|
2700
2887
|
@trivial_factory
|
|
2701
2888
|
class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingStateNode[str]):
|
|
2702
2889
|
|
|
2703
2890
|
_parent_states = staticmethod(
|
|
2704
2891
|
lambda: [
|
|
2705
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2706
2892
|
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2707
2893
|
EnvState.state_client_conf_file_data_loaded.name,
|
|
2708
2894
|
EnvState.state_selected_env_dir_rel_path_inited.name,
|
|
@@ -2712,8 +2898,6 @@ class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingState
|
|
|
2712
2898
|
|
|
2713
2899
|
def _eval_state_once(self) -> ValueType:
|
|
2714
2900
|
|
|
2715
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2716
|
-
|
|
2717
2901
|
state_ref_root_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_ref_root_dir_abs_path_inited.name)
|
|
2718
2902
|
|
|
2719
2903
|
state_selected_env_dir_rel_path_inited: str | None = self.eval_parent_state(EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
@@ -2743,7 +2927,10 @@ class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingState
|
|
|
2743
2927
|
if os.path.exists(state_local_conf_symlink_abs_path_inited):
|
|
2744
2928
|
if os.path.islink(state_local_conf_symlink_abs_path_inited):
|
|
2745
2929
|
if os.path.isdir(state_local_conf_symlink_abs_path_inited):
|
|
2746
|
-
if
|
|
2930
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2931
|
+
EntryFunc.func_start_app,
|
|
2932
|
+
EntryFunc.func_call_lib,
|
|
2933
|
+
]:
|
|
2747
2934
|
# Nothing to do:
|
|
2748
2935
|
pass
|
|
2749
2936
|
else:
|
|
@@ -2803,8 +2990,6 @@ class Bootstrapper_state_env_conf_file_data_loaded(AbstractCachingStateNode[dict
|
|
|
2803
2990
|
|
|
2804
2991
|
_parent_states = staticmethod(
|
|
2805
2992
|
lambda: [
|
|
2806
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2807
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2808
2993
|
EnvState.state_local_conf_file_abs_path_inited.name,
|
|
2809
2994
|
]
|
|
2810
2995
|
)
|
|
@@ -3119,6 +3304,25 @@ class Bootstrapper_state_venv_driver_inited(AbstractOverriddenFieldCachingStateN
|
|
|
3119
3304
|
return state_venv_driver_inited
|
|
3120
3305
|
|
|
3121
3306
|
|
|
3307
|
+
# noinspection PyPep8Naming
|
|
3308
|
+
@trivial_factory
|
|
3309
|
+
class Bootstrapper_state_version_constraints_file_basename_inited(AbstractOverriddenFieldCachingStateNode[str]):
|
|
3310
|
+
|
|
3311
|
+
_parent_states = staticmethod(
|
|
3312
|
+
lambda: [
|
|
3313
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
3314
|
+
EnvState.state_env_conf_file_data_loaded.name,
|
|
3315
|
+
]
|
|
3316
|
+
)
|
|
3317
|
+
_state_name = staticmethod(lambda: EnvState.state_version_constraints_file_basename_inited.name)
|
|
3318
|
+
|
|
3319
|
+
def _eval_state_once(self) -> ValueType:
|
|
3320
|
+
return self._get_overridden_value_or_default(
|
|
3321
|
+
ConfField.field_version_constraints_file_basename.value,
|
|
3322
|
+
ConfConstEnv.default_version_constraints_file_basename,
|
|
3323
|
+
)
|
|
3324
|
+
|
|
3325
|
+
|
|
3122
3326
|
# noinspection PyPep8Naming
|
|
3123
3327
|
@trivial_factory
|
|
3124
3328
|
class Bootstrapper_state_project_descriptors_inited(AbstractOverriddenFieldCachingStateNode[list]):
|
|
@@ -3203,6 +3407,7 @@ class Bootstrapper_state_derived_conf_data_loaded(AbstractCachingStateNode[dict]
|
|
|
3203
3407
|
EnvState.state_local_tmp_dir_abs_path_inited.name,
|
|
3204
3408
|
EnvState.state_local_cache_dir_abs_path_inited.name,
|
|
3205
3409
|
EnvState.state_venv_driver_inited.name,
|
|
3410
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3206
3411
|
EnvState.state_project_descriptors_inited.name,
|
|
3207
3412
|
]
|
|
3208
3413
|
|
|
@@ -3271,7 +3476,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3271
3476
|
_parent_states = staticmethod(
|
|
3272
3477
|
lambda: [
|
|
3273
3478
|
EnvState.state_args_parsed.name,
|
|
3274
|
-
EnvState.
|
|
3479
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
3275
3480
|
EnvState.state_input_start_id_var_loaded.name,
|
|
3276
3481
|
EnvState.state_local_log_dir_abs_path_inited.name,
|
|
3277
3482
|
]
|
|
@@ -3284,7 +3489,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3284
3489
|
|
|
3285
3490
|
state_local_log_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_log_dir_abs_path_inited.name)
|
|
3286
3491
|
|
|
3287
|
-
|
|
3492
|
+
state_input_stderr_log_level_handler_configured: logging.Handler = self.eval_parent_state(EnvState.state_input_stderr_log_level_handler_configured.name)
|
|
3288
3493
|
|
|
3289
3494
|
script_path = sys.argv[0]
|
|
3290
3495
|
script_name = os.path.basename(script_path)
|
|
@@ -3292,7 +3497,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3292
3497
|
file_handler = _configure_primer_file_log_handler(
|
|
3293
3498
|
script_name,
|
|
3294
3499
|
state_input_start_id_var_loaded,
|
|
3295
|
-
|
|
3500
|
+
state_input_stderr_log_level_handler_configured,
|
|
3296
3501
|
state_local_log_dir_abs_path_inited,
|
|
3297
3502
|
)
|
|
3298
3503
|
|
|
@@ -3330,14 +3535,6 @@ class Bootstrapper_state_stride_py_required_reached_not_command_start(AbstractCa
|
|
|
3330
3535
|
if self.env_ctx.has_stride_reached(next_stride=state_stride_py_required_reached):
|
|
3331
3536
|
return self.env_ctx.set_max_stride(state_stride_py_required_reached)
|
|
3332
3537
|
|
|
3333
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
3334
|
-
|
|
3335
|
-
# TODO: Unused, but plugged in to form complete DAG: consider adding intermediate state to plug it in:
|
|
3336
|
-
state_default_file_log_handler_configured = self.eval_parent_state(EnvState.state_default_file_log_handler_configured.name)
|
|
3337
|
-
|
|
3338
|
-
# TODO: Unused, but plugged in to form complete DAG: consider adding intermediate state to plug it in:
|
|
3339
|
-
state_local_tmp_dir_abs_path_inited = self.eval_parent_state(EnvState.state_local_tmp_dir_abs_path_inited.name)
|
|
3340
|
-
|
|
3341
3538
|
state_input_start_id_var_loaded: str = self.eval_parent_state(EnvState.state_input_start_id_var_loaded.name)
|
|
3342
3539
|
|
|
3343
3540
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
@@ -3425,7 +3622,7 @@ class Factory_state_stride_py_required_reached(NodeFactory[StateStride]):
|
|
|
3425
3622
|
@trivial_factory
|
|
3426
3623
|
class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
3427
3624
|
"""
|
|
3428
|
-
Removes current `venv` dir and `
|
|
3625
|
+
Removes current `venv` dir and `version_constraints.txt` file (to trigger their re-creation subsequently).
|
|
3429
3626
|
"""
|
|
3430
3627
|
|
|
3431
3628
|
_parent_states = staticmethod(
|
|
@@ -3437,6 +3634,7 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3437
3634
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
3438
3635
|
EnvState.state_local_venv_dir_abs_path_inited.name,
|
|
3439
3636
|
EnvState.state_local_tmp_dir_abs_path_inited.name,
|
|
3637
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3440
3638
|
EnvState.state_stride_py_required_reached.name,
|
|
3441
3639
|
]
|
|
3442
3640
|
)
|
|
@@ -3444,8 +3642,6 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3444
3642
|
|
|
3445
3643
|
def _eval_state_once(self) -> ValueType:
|
|
3446
3644
|
|
|
3447
|
-
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
3448
|
-
|
|
3449
3645
|
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
3450
3646
|
|
|
3451
3647
|
if state_input_sub_command_arg_loaded == SubCommand.command_start:
|
|
@@ -3463,8 +3659,6 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3463
3659
|
state_stride_py_required_reached: StateStride = self.eval_parent_state(EnvState.state_stride_py_required_reached.name)
|
|
3464
3660
|
assert self.env_ctx.get_stride().value >= StateStride.stride_py_required.value
|
|
3465
3661
|
|
|
3466
|
-
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3467
|
-
|
|
3468
3662
|
# Reboot can only happen outside `venv` (to delete it):
|
|
3469
3663
|
if not (reboot_env and state_stride_py_required_reached == StateStride.stride_py_required):
|
|
3470
3664
|
return False
|
|
@@ -3489,9 +3683,10 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3489
3683
|
)
|
|
3490
3684
|
|
|
3491
3685
|
state_local_conf_symlink_abs_path_inited = self.eval_parent_state(EnvState.state_local_conf_symlink_abs_path_inited.name)
|
|
3686
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
3492
3687
|
constraints_txt_path = os.path.join(
|
|
3493
3688
|
state_local_conf_symlink_abs_path_inited,
|
|
3494
|
-
|
|
3689
|
+
state_version_constraints_file_basename_inited,
|
|
3495
3690
|
)
|
|
3496
3691
|
if os.path.exists(constraints_txt_path):
|
|
3497
3692
|
logger.info(f"removing version constraints file [{constraints_txt_path}]")
|
|
@@ -3597,8 +3792,6 @@ class Bootstrapper_state_stride_py_venv_reached(AbstractCachingStateNode[StateSt
|
|
|
3597
3792
|
|
|
3598
3793
|
state_input_start_id_var_loaded: str = self.eval_parent_state(EnvState.state_input_start_id_var_loaded.name)
|
|
3599
3794
|
|
|
3600
|
-
state_reboot_triggered: bool = self.eval_parent_state(EnvState.state_reboot_triggered.name)
|
|
3601
|
-
|
|
3602
3795
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3603
3796
|
|
|
3604
3797
|
state_selected_python_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_selected_python_file_abs_path_inited.name)
|
|
@@ -3666,6 +3859,7 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3666
3859
|
EnvState.state_input_sub_command_arg_loaded.name,
|
|
3667
3860
|
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
3668
3861
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
3862
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3669
3863
|
EnvState.state_project_descriptors_inited.name,
|
|
3670
3864
|
EnvState.state_install_specs_inited.name,
|
|
3671
3865
|
EnvState.state_venv_driver_prepared.name,
|
|
@@ -3701,6 +3895,8 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3701
3895
|
|
|
3702
3896
|
state_venv_driver_prepared: VenvDriverBase = self.eval_parent_state(EnvState.state_venv_driver_prepared.name)
|
|
3703
3897
|
|
|
3898
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
3899
|
+
|
|
3704
3900
|
reboot_env: bool = state_args_parsed.sub_command == SubCommand.command_reboot.value
|
|
3705
3901
|
|
|
3706
3902
|
do_install: bool = (
|
|
@@ -3714,7 +3910,7 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3714
3910
|
|
|
3715
3911
|
constraints_txt_path = os.path.join(
|
|
3716
3912
|
state_local_conf_symlink_abs_path_inited,
|
|
3717
|
-
|
|
3913
|
+
state_version_constraints_file_basename_inited,
|
|
3718
3914
|
)
|
|
3719
3915
|
if not os.path.exists(constraints_txt_path):
|
|
3720
3916
|
logger.info(f"creating empty constraints file [{constraints_txt_path}]")
|
|
@@ -3806,6 +4002,7 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3806
4002
|
lambda: [
|
|
3807
4003
|
EnvState.state_input_sub_command_arg_loaded.name,
|
|
3808
4004
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
4005
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3809
4006
|
EnvState.state_venv_driver_prepared.name,
|
|
3810
4007
|
EnvState.state_protoprimer_package_installed.name,
|
|
3811
4008
|
]
|
|
@@ -3818,7 +4015,7 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3818
4015
|
|
|
3819
4016
|
if state_input_sub_command_arg_loaded == SubCommand.command_start:
|
|
3820
4017
|
# The only reason for `EnvState.state_version_constraints_generated`
|
|
3821
|
-
# is to re-generate the `
|
|
4018
|
+
# is to re-generate the `version_constraints.txt` file based on `venv`.
|
|
3822
4019
|
# Skip it as `venv` is supposed to be ready in `SubCommand.command_start`:
|
|
3823
4020
|
return False
|
|
3824
4021
|
|
|
@@ -3831,11 +4028,13 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3831
4028
|
|
|
3832
4029
|
state_venv_driver_prepared: VenvDriverBase = self.eval_parent_state(EnvState.state_venv_driver_prepared.name)
|
|
3833
4030
|
|
|
4031
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
4032
|
+
|
|
3834
4033
|
state_venv_driver_prepared.pin_versions(
|
|
3835
4034
|
get_path_to_curr_python(),
|
|
3836
4035
|
os.path.join(
|
|
3837
4036
|
state_local_conf_symlink_abs_path_inited,
|
|
3838
|
-
|
|
4037
|
+
state_version_constraints_file_basename_inited,
|
|
3839
4038
|
),
|
|
3840
4039
|
)
|
|
3841
4040
|
|
|
@@ -3875,8 +4074,6 @@ class Bootstrapper_state_stride_deps_updated_reached(AbstractCachingStateNode[St
|
|
|
3875
4074
|
|
|
3876
4075
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3877
4076
|
|
|
3878
|
-
state_version_constraints_generated: bool = self.eval_parent_state(EnvState.state_version_constraints_generated.name)
|
|
3879
|
-
|
|
3880
4077
|
state_local_venv_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_venv_dir_abs_path_inited.name)
|
|
3881
4078
|
|
|
3882
4079
|
venv_path_to_python: str = os.path.join(
|
|
@@ -3915,7 +4112,6 @@ class Bootstrapper_state_proto_code_updated(AbstractCachingStateNode[bool]):
|
|
|
3915
4112
|
|
|
3916
4113
|
def _eval_state_once(self) -> ValueType:
|
|
3917
4114
|
|
|
3918
|
-
state_stride_deps_updated_reached: StateStride = self.eval_parent_state(EnvState.state_stride_deps_updated_reached.name)
|
|
3919
4115
|
assert self.env_ctx.get_stride().value >= StateStride.stride_deps_updated.value
|
|
3920
4116
|
|
|
3921
4117
|
if self.env_ctx.get_stride().value != StateStride.stride_deps_updated.value:
|
|
@@ -4002,15 +4198,11 @@ class Bootstrapper_state_stride_src_updated_reached(AbstractCachingStateNode[Sta
|
|
|
4002
4198
|
|
|
4003
4199
|
state_stride_src_updated_reached: StateStride = StateStride.stride_src_updated
|
|
4004
4200
|
|
|
4005
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
4006
|
-
|
|
4007
4201
|
if self.env_ctx.has_stride_reached(next_stride=state_stride_src_updated_reached):
|
|
4008
4202
|
return self.env_ctx.set_max_stride(state_stride_src_updated_reached)
|
|
4009
4203
|
|
|
4010
4204
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
4011
4205
|
|
|
4012
|
-
state_proto_code_updated: bool = self.eval_parent_state(EnvState.state_proto_code_updated.name)
|
|
4013
|
-
|
|
4014
4206
|
state_local_venv_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_venv_dir_abs_path_inited.name)
|
|
4015
4207
|
|
|
4016
4208
|
venv_path_to_python: str = os.path.join(
|
|
@@ -4101,16 +4293,24 @@ class EnvState(enum.Enum):
|
|
|
4101
4293
|
|
|
4102
4294
|
state_default_stderr_log_handler_configured = Bootstrapper_state_default_stderr_log_handler_configured
|
|
4103
4295
|
|
|
4104
|
-
state_args_parsed =
|
|
4296
|
+
state_args_parsed = Factory_state_args_parsed
|
|
4105
4297
|
|
|
4106
4298
|
state_input_stderr_log_level_eval_finalized = Bootstrapper_state_input_stderr_log_level_eval_finalized
|
|
4107
4299
|
|
|
4300
|
+
state_input_stderr_log_level_handler_configured = Bootstrapper_state_input_stderr_log_level_handler_configured
|
|
4301
|
+
|
|
4108
4302
|
state_input_sub_command_arg_loaded = Bootstrapper_state_input_sub_command_arg_loaded
|
|
4109
4303
|
|
|
4110
|
-
state_input_final_state_eval_finalized =
|
|
4304
|
+
state_input_final_state_eval_finalized = Factory_state_input_final_state_eval_finalized
|
|
4305
|
+
|
|
4306
|
+
state_func_boot_env_executed = Bootstrapper_state_func_boot_env_executed
|
|
4307
|
+
|
|
4308
|
+
state_func_start_app_executed = Bootstrapper_state_func_start_app_executed
|
|
4309
|
+
|
|
4310
|
+
state_func_call_lib_executed = Bootstrapper_state_func_call_lib_executed
|
|
4111
4311
|
|
|
4112
4312
|
# Special case: triggers everything:
|
|
4113
|
-
|
|
4313
|
+
state_everything_executed = Factory_state_everything_executed
|
|
4114
4314
|
|
|
4115
4315
|
state_input_start_id_var_loaded = Bootstrapper_state_input_start_id_var_loaded
|
|
4116
4316
|
|
|
@@ -4135,7 +4335,7 @@ class EnvState(enum.Enum):
|
|
|
4135
4335
|
# `ConfLeap.leap_client`:
|
|
4136
4336
|
state_client_conf_file_data_loaded = Bootstrapper_state_client_conf_file_data_loaded
|
|
4137
4337
|
|
|
4138
|
-
state_selected_env_dir_rel_path_inited =
|
|
4338
|
+
state_selected_env_dir_rel_path_inited = Factory_state_selected_env_dir_rel_path_inited
|
|
4139
4339
|
|
|
4140
4340
|
state_local_conf_symlink_abs_path_inited = Bootstrapper_state_local_conf_symlink_abs_path_inited
|
|
4141
4341
|
|
|
@@ -4165,6 +4365,8 @@ class EnvState(enum.Enum):
|
|
|
4165
4365
|
|
|
4166
4366
|
state_venv_driver_inited = Bootstrapper_state_venv_driver_inited
|
|
4167
4367
|
|
|
4368
|
+
state_version_constraints_file_basename_inited = Bootstrapper_state_version_constraints_file_basename_inited
|
|
4369
|
+
|
|
4168
4370
|
state_project_descriptors_inited = Bootstrapper_state_project_descriptors_inited
|
|
4169
4371
|
|
|
4170
4372
|
state_install_specs_inited = Bootstrapper_state_install_specs_inited
|
|
@@ -4209,11 +4411,8 @@ class TargetState(enum.Enum):
|
|
|
4209
4411
|
Special `EnvState`-s.
|
|
4210
4412
|
"""
|
|
4211
4413
|
|
|
4212
|
-
#
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
# A special state that triggers execution of the specific `SubCommand`:
|
|
4216
|
-
target_sub_command_executed = EnvState.state_sub_command_executed
|
|
4414
|
+
# A special state that triggers execution of everything else:
|
|
4415
|
+
target_everything_executed = EnvState.state_everything_executed
|
|
4217
4416
|
|
|
4218
4417
|
# FT_00_22_19_59.derived_config.md:
|
|
4219
4418
|
target_derived_config_loaded = EnvState.state_derived_conf_data_loaded
|
|
@@ -4329,14 +4528,13 @@ class MutableValue(Generic[ValueType]):
|
|
|
4329
4528
|
|
|
4330
4529
|
def set_curr_value(
|
|
4331
4530
|
self,
|
|
4332
|
-
state_node: StateNode
|
|
4531
|
+
state_node: StateNode,
|
|
4333
4532
|
curr_value: ValueType,
|
|
4334
4533
|
) -> None:
|
|
4335
4534
|
# TODO: Shell we also ensure that the `StateNode` using that `MutableValue` has necessary dependencies on write?
|
|
4336
4535
|
|
|
4337
4536
|
if self.curr_value is None:
|
|
4338
4537
|
raise AssertionError(f"`{MutableValue.__name__}` [{self.state_name}] cannot be set as it is not initialized yet.")
|
|
4339
|
-
state_name: str | None = None
|
|
4340
4538
|
self.curr_value = curr_value
|
|
4341
4539
|
logger.debug(f"`{self.__class__.__name__}` [{self.state_name}] `curr_value` after set [{self.curr_value}] in [{state_node.get_state_name()}]")
|
|
4342
4540
|
|
|
@@ -4614,40 +4812,53 @@ class _PrimerStderrLogFormatter(DefaultStderrLogFormatter):
|
|
|
4614
4812
|
}
|
|
4615
4813
|
|
|
4616
4814
|
|
|
4815
|
+
def _reconfigure_log_handler(
|
|
4816
|
+
formatter_class: type,
|
|
4817
|
+
new_formatter: logging.Formatter,
|
|
4818
|
+
log_level: int,
|
|
4819
|
+
) -> logging.Handler | None:
|
|
4820
|
+
for log_handler in logger.handlers:
|
|
4821
|
+
if isinstance(log_handler.formatter, formatter_class):
|
|
4822
|
+
# This covers both `_Primer*` (subclass) and `Default*` formatter variants.
|
|
4823
|
+
log_handler.setFormatter(new_formatter)
|
|
4824
|
+
log_handler.setLevel(log_level)
|
|
4825
|
+
# Remove `protoprimer`-specific filter if present:
|
|
4826
|
+
for handler_filter in list(log_handler.filters):
|
|
4827
|
+
if isinstance(handler_filter, StateStrideFilter):
|
|
4828
|
+
log_handler.removeFilter(handler_filter)
|
|
4829
|
+
return log_handler
|
|
4830
|
+
return None
|
|
4831
|
+
|
|
4832
|
+
|
|
4617
4833
|
def reconfigure_stderr_log_handler(log_level: int = logging.WARNING) -> logging.Handler | None:
|
|
4618
4834
|
"""
|
|
4619
4835
|
UC_81_50_97_17.reuse_logger.md
|
|
4620
4836
|
"""
|
|
4621
|
-
|
|
4622
4837
|
logger.setLevel(logging.NOTSET)
|
|
4838
|
+
return _reconfigure_log_handler(
|
|
4839
|
+
formatter_class=DefaultStderrLogFormatter,
|
|
4840
|
+
new_formatter=DefaultStderrLogFormatter(log_level),
|
|
4841
|
+
log_level=log_level,
|
|
4842
|
+
)
|
|
4623
4843
|
|
|
4624
|
-
# Check for existing primer handler (to replace its formatter):
|
|
4625
|
-
stderr_handler: logging.Handler
|
|
4626
|
-
for stderr_handler in logger.handlers:
|
|
4627
|
-
if isinstance(stderr_handler, logging.StreamHandler) and stderr_handler.stream is sys.stderr and isinstance(stderr_handler.formatter, DefaultStderrLogFormatter):
|
|
4628
|
-
# This covers both `_PrimerStderrLogFormatter` (subclass) and `DefaultStderrLogFormatter`.
|
|
4629
|
-
stderr_handler.setFormatter(DefaultStderrLogFormatter(log_level))
|
|
4630
|
-
stderr_handler.setLevel(log_level)
|
|
4631
|
-
|
|
4632
|
-
# Remove primer-specific filter if present:
|
|
4633
|
-
for f in list(stderr_handler.filters):
|
|
4634
|
-
if isinstance(f, StateStrideFilter):
|
|
4635
|
-
stderr_handler.removeFilter(f)
|
|
4636
|
-
|
|
4637
|
-
return stderr_handler
|
|
4638
4844
|
|
|
4845
|
+
def _find_existing_log_handler(
|
|
4846
|
+
handler_class: type[logging.StreamHandler],
|
|
4847
|
+
formatter_class: type,
|
|
4848
|
+
) -> logging.StreamHandler | None:
|
|
4849
|
+
"""
|
|
4850
|
+
Prevent duplicate handler (when `os.execv*` calls restart `main` again in tests).
|
|
4851
|
+
"""
|
|
4852
|
+
if os.environ.get(EnvVar.var_PROTOPRIMER_MOCKED_RESTART.value, None) is None:
|
|
4853
|
+
return None
|
|
4854
|
+
log_handler: logging.Handler
|
|
4855
|
+
for log_handler in logger.handlers:
|
|
4856
|
+
if isinstance(log_handler, handler_class):
|
|
4857
|
+
if isinstance(log_handler.formatter, formatter_class):
|
|
4858
|
+
return log_handler
|
|
4639
4859
|
return None
|
|
4640
4860
|
|
|
4641
4861
|
|
|
4642
|
-
def configure_default_stderr_log_handler(log_level: int = logging.WARNING) -> logging.Handler:
|
|
4643
|
-
logger.setLevel(logging.NOTSET)
|
|
4644
|
-
stderr_handler: logging.Handler = logging.StreamHandler(sys.stderr)
|
|
4645
|
-
stderr_handler.setFormatter(DefaultStderrLogFormatter(log_level))
|
|
4646
|
-
stderr_handler.setLevel(log_level)
|
|
4647
|
-
logger.addHandler(stderr_handler)
|
|
4648
|
-
return stderr_handler
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
4862
|
def _configure_primer_stderr_log_handler(state_input_stderr_log_level_var_loaded: int) -> logging.Handler:
|
|
4652
4863
|
"""
|
|
4653
4864
|
Implements for `stderr` log: FT_38_73_38_52.log_verbosity.md
|
|
@@ -4656,23 +4867,16 @@ def _configure_primer_stderr_log_handler(state_input_stderr_log_level_var_loaded
|
|
|
4656
4867
|
# Log everything (the filters are supposed to be set on output handlers instead):
|
|
4657
4868
|
logger.setLevel(logging.NOTSET)
|
|
4658
4869
|
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
# Select `stderr` handler:
|
|
4664
|
-
for handler_instance in logger.handlers:
|
|
4665
|
-
if isinstance(handler_instance, handler_class):
|
|
4666
|
-
if handler_instance.stream is sys.stderr:
|
|
4667
|
-
stderr_handler = handler_instance
|
|
4668
|
-
break
|
|
4870
|
+
stderr_handler: logging.StreamHandler | None = _find_existing_log_handler(
|
|
4871
|
+
logging.StreamHandler,
|
|
4872
|
+
_PrimerStderrLogFormatter,
|
|
4873
|
+
)
|
|
4669
4874
|
|
|
4670
4875
|
if stderr_handler is None:
|
|
4671
|
-
stderr_handler
|
|
4672
|
-
|
|
4876
|
+
stderr_handler = logging.StreamHandler(sys.stderr)
|
|
4877
|
+
assert stderr_handler is not None
|
|
4673
4878
|
stderr_handler.addFilter(StateStrideFilter())
|
|
4674
4879
|
stderr_handler.setFormatter(_PrimerStderrLogFormatter(state_input_stderr_log_level_var_loaded))
|
|
4675
|
-
|
|
4676
4880
|
logger.addHandler(stderr_handler)
|
|
4677
4881
|
|
|
4678
4882
|
stderr_handler.setLevel(state_input_stderr_log_level_var_loaded)
|
|
@@ -4683,41 +4887,17 @@ def reconfigure_file_log_handler(log_level: int = logging.INFO) -> logging.Handl
|
|
|
4683
4887
|
"""
|
|
4684
4888
|
UC_81_50_97_17.reuse_logger.md
|
|
4685
4889
|
"""
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
# This covers both `_PrimerFileLogFormatter` (subclass) and `DefaultFileLogFormatter`.
|
|
4692
|
-
file_handler.setFormatter(DefaultFileLogFormatter())
|
|
4693
|
-
file_handler.setLevel(log_level)
|
|
4694
|
-
|
|
4695
|
-
# Remove primer-specific filter if present:
|
|
4696
|
-
for handler_filter in list(file_handler.filters):
|
|
4697
|
-
if isinstance(handler_filter, StateStrideFilter):
|
|
4698
|
-
file_handler.removeFilter(handler_filter)
|
|
4699
|
-
|
|
4700
|
-
return file_handler
|
|
4701
|
-
|
|
4702
|
-
return None
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
def configure_default_file_log_handler(
|
|
4706
|
-
log_file_abs_path: str,
|
|
4707
|
-
log_level: int = logging.INFO,
|
|
4708
|
-
) -> logging.Handler:
|
|
4709
|
-
os.makedirs(os.path.dirname(log_file_abs_path), exist_ok=True)
|
|
4710
|
-
file_handler: logging.Handler = logging.FileHandler(log_file_abs_path)
|
|
4711
|
-
file_handler.setFormatter(DefaultFileLogFormatter())
|
|
4712
|
-
file_handler.setLevel(log_level)
|
|
4713
|
-
logger.addHandler(file_handler)
|
|
4714
|
-
return file_handler
|
|
4890
|
+
return _reconfigure_log_handler(
|
|
4891
|
+
formatter_class=DefaultFileLogFormatter,
|
|
4892
|
+
new_formatter=DefaultFileLogFormatter(),
|
|
4893
|
+
log_level=log_level,
|
|
4894
|
+
)
|
|
4715
4895
|
|
|
4716
4896
|
|
|
4717
4897
|
def _configure_primer_file_log_handler(
|
|
4718
4898
|
script_name: str,
|
|
4719
4899
|
state_input_start_id_var_loaded: str,
|
|
4720
|
-
|
|
4900
|
+
state_input_stderr_log_level_handler_configured: logging.Handler,
|
|
4721
4901
|
state_local_log_dir_abs_path_inited: str,
|
|
4722
4902
|
) -> logging.Handler:
|
|
4723
4903
|
"""
|
|
@@ -4733,33 +4913,37 @@ def _configure_primer_file_log_handler(
|
|
|
4733
4913
|
# TODO: Configure MAX file log level in the config file (NOTE: the higher the level the fewer the log entries):
|
|
4734
4914
|
file_log_level: int = logging.INFO
|
|
4735
4915
|
# Increase the log level at most to what is used by stderr:
|
|
4736
|
-
if
|
|
4737
|
-
file_log_level =
|
|
4916
|
+
if state_input_stderr_log_level_handler_configured.level < file_log_level:
|
|
4917
|
+
file_log_level = state_input_stderr_log_level_handler_configured.level
|
|
4738
4918
|
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4919
|
+
file_handler: logging.StreamHandler | None = _find_existing_log_handler(
|
|
4920
|
+
logging.FileHandler,
|
|
4921
|
+
_PrimerFileLogFormatter,
|
|
4742
4922
|
)
|
|
4743
4923
|
|
|
4744
|
-
if
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4924
|
+
if file_handler is None:
|
|
4925
|
+
os.makedirs(
|
|
4926
|
+
state_local_log_dir_abs_path_inited,
|
|
4927
|
+
exist_ok=True,
|
|
4928
|
+
)
|
|
4929
|
+
|
|
4930
|
+
if not os.path.exists(log_file_abs_path):
|
|
4931
|
+
# Explain missing logs to avoid confusion:
|
|
4932
|
+
write_text_file(
|
|
4933
|
+
log_file_abs_path,
|
|
4934
|
+
f"""
|
|
4749
4935
|
{ConfConstGeneral.log_section_delimiter} file log starts at [{StateStride.stride_py_arbitrary.name}] after its config is resolved {ConfConstGeneral.log_section_delimiter}
|
|
4750
4936
|
|
|
4751
4937
|
""",
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
file_handler: logging.Handler = logging.FileHandler(log_file_abs_path)
|
|
4755
|
-
file_handler.addFilter(StateStrideFilter())
|
|
4938
|
+
)
|
|
4756
4939
|
|
|
4757
|
-
|
|
4940
|
+
file_handler = logging.FileHandler(log_file_abs_path)
|
|
4941
|
+
assert file_handler is not None
|
|
4942
|
+
file_handler.addFilter(StateStrideFilter())
|
|
4943
|
+
file_handler.setFormatter(_PrimerFileLogFormatter())
|
|
4944
|
+
logger.addHandler(file_handler)
|
|
4758
4945
|
|
|
4759
4946
|
file_handler.setLevel(file_log_level)
|
|
4760
|
-
file_handler.setFormatter(file_formatter)
|
|
4761
|
-
|
|
4762
|
-
logger.addHandler(file_handler)
|
|
4763
4947
|
return file_handler
|
|
4764
4948
|
|
|
4765
4949
|
|
|
@@ -5197,7 +5381,7 @@ def select_python_file_abs_path(
|
|
|
5197
5381
|
try:
|
|
5198
5382
|
logger.debug(f"trying `python` version of `selected_python_abs_path` [{selected_python_abs_path}]")
|
|
5199
5383
|
python_version: tuple[int, int, int] = get_python_version(selected_python_abs_path)
|
|
5200
|
-
logger.
|
|
5384
|
+
logger.debug(f"`python` version of `selected_python_abs_path` [{selected_python_abs_path}] is [{python_version}]")
|
|
5201
5385
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
5202
5386
|
logger.warning(f"`python` in `selected_python_abs_path` [{selected_python_abs_path}] failed without returning its version")
|
|
5203
5387
|
selected_python_abs_path = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protoprimer
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.1.dev0
|
|
4
4
|
Summary: Escape the fragile mess of pre-venv shell scripts with a pure Python bootstrap wrapper: 🚀 ⏩ single-touch, zero-args, self-contained, no-deps, cross-platform, testable init logic using standard tools to run apps in a custom environment isolated per repository
|
|
5
5
|
Author-email: uvsmtid <uvsmtid@gmail.com>
|
|
6
6
|
License: MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{protoprimer-0.12.0.dev1 → protoprimer-0.12.1.dev0}/main/protoprimer.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|