protoprimer 0.12.0.dev1__tar.gz → 0.12.0.dev2__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.0.dev2}/PKG-INFO +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer/primer_kernel.py +415 -226
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer.egg-info/PKG-INFO +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/pyproject.toml +1 -1
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer/__init__.py +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer/proto_generator.py +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer.egg-info/SOURCES.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer.egg-info/dependency_links.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer.egg-info/requires.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/main/protoprimer.egg-info/top_level.txt +0 -0
- {protoprimer-0.12.0.dev1 → protoprimer-0.12.0.dev2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protoprimer
|
|
3
|
-
Version: 0.12.0.
|
|
3
|
+
Version: 0.12.0.dev2
|
|
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.0.
|
|
55
|
+
__version__ = "0.12.0.dev2"
|
|
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
|
|
|
@@ -645,6 +649,9 @@ class ConfField(enum.Enum):
|
|
|
645
649
|
|
|
646
650
|
field_install_specs = f"{ValueName.value_install_specs.value}"
|
|
647
651
|
|
|
652
|
+
# state_version_constraints_file_basename_inited:
|
|
653
|
+
field_version_constraints_file_basename = f"{ValueName.value_version_constraints.value}_{ValueName.value_file_basename.value}"
|
|
654
|
+
|
|
648
655
|
####################################################################################################################
|
|
649
656
|
|
|
650
657
|
# child of `field_project_descriptors`:
|
|
@@ -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:
|
|
@@ -1416,7 +1423,7 @@ class ConfConstEnv:
|
|
|
1416
1423
|
|
|
1417
1424
|
default_install_specs = []
|
|
1418
1425
|
|
|
1419
|
-
|
|
1426
|
+
default_version_constraints_file_basename = "constraints.txt"
|
|
1420
1427
|
|
|
1421
1428
|
# FT_84_11_73_28.supported_python_versions.md:
|
|
1422
1429
|
latest_known_python_version = "3.14"
|
|
@@ -1542,7 +1549,7 @@ def _create_child_argparser(parent_argparsers):
|
|
|
1542
1549
|
parser_check.set_defaults(sub_command=SubCommand.command_check.value)
|
|
1543
1550
|
|
|
1544
1551
|
child_argparser = CustomArgumentParser(
|
|
1545
|
-
description=
|
|
1552
|
+
description=f"The early [{PrimerRuntime.runtime_proto.value}] environment bootstrapper [{KeyWord.key_primer.value}].",
|
|
1546
1553
|
parents=parent_argparsers,
|
|
1547
1554
|
epilog=f"Version: {__version__} | {ConfConstGeneral.name_protoprimer_site_link} | {pathlib.Path(__file__).resolve()}",
|
|
1548
1555
|
)
|
|
@@ -1942,45 +1949,58 @@ class Bootstrapper_state_default_stderr_log_handler_configured(AbstractCachingSt
|
|
|
1942
1949
|
|
|
1943
1950
|
|
|
1944
1951
|
# noinspection PyPep8Naming
|
|
1945
|
-
@
|
|
1946
|
-
class
|
|
1952
|
+
@conditional_factory
|
|
1953
|
+
class Bootstrapper_state_args_parsed_func_boot_env(AbstractCachingStateNode[argparse.Namespace]):
|
|
1954
|
+
|
|
1955
|
+
_state_name = staticmethod(lambda: EnvState.state_args_parsed.name)
|
|
1956
|
+
|
|
1957
|
+
def _eval_state_once(self) -> ValueType:
|
|
1958
|
+
return parse_args()
|
|
1959
|
+
|
|
1960
|
+
|
|
1961
|
+
# noinspection PyPep8Naming
|
|
1962
|
+
@conditional_factory
|
|
1963
|
+
class Bootstrapper_state_args_parsed_not_func_boot_env(AbstractCachingStateNode[argparse.Namespace]):
|
|
1947
1964
|
|
|
1948
1965
|
_state_name = staticmethod(lambda: EnvState.state_args_parsed.name)
|
|
1949
1966
|
|
|
1950
1967
|
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
1968
|
# TODO: TODO_60_63_68_81.refactor_DAG_builder.md:
|
|
1956
1969
|
# This step should not be executed without need to parse args.
|
|
1957
1970
|
# 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
|
-
)
|
|
1971
|
+
# Pretend there is no args except `SubCommand.command_start`:
|
|
1972
|
+
state_args_parsed: argparse.Namespace = parse_args([])
|
|
1973
|
+
setattr(
|
|
1974
|
+
state_args_parsed,
|
|
1975
|
+
ParsedArg.name_sub_command.value,
|
|
1976
|
+
SubCommand.command_start.value,
|
|
1977
|
+
)
|
|
1969
1978
|
return state_args_parsed
|
|
1970
1979
|
|
|
1971
1980
|
|
|
1981
|
+
# noinspection PyPep8Naming
|
|
1982
|
+
class Factory_state_args_parsed(NodeFactory[StateStride]):
|
|
1983
|
+
|
|
1984
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
1985
|
+
# TODO: TODO_60_63_68_81.refactor_DAG_builder.md:
|
|
1986
|
+
# This step should not be executed without need to parse args.
|
|
1987
|
+
# Do not fake args. Just redesign dependency. No?
|
|
1988
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
1989
|
+
EntryFunc.func_boot_env,
|
|
1990
|
+
EntryFunc.func_run_main,
|
|
1991
|
+
]:
|
|
1992
|
+
return Bootstrapper_state_args_parsed_func_boot_env(self.env_ctx)
|
|
1993
|
+
else:
|
|
1994
|
+
return Bootstrapper_state_args_parsed_not_func_boot_env(self.env_ctx)
|
|
1995
|
+
|
|
1996
|
+
|
|
1972
1997
|
# noinspection PyPep8Naming
|
|
1973
1998
|
@trivial_factory
|
|
1974
1999
|
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
2000
|
|
|
1980
2001
|
_parent_states = staticmethod(
|
|
1981
2002
|
lambda: [
|
|
1982
2003
|
EnvState.state_input_stderr_log_level_var_loaded.name,
|
|
1983
|
-
EnvState.state_default_stderr_log_handler_configured.name,
|
|
1984
2004
|
EnvState.state_args_parsed.name,
|
|
1985
2005
|
]
|
|
1986
2006
|
)
|
|
@@ -1990,8 +2010,6 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
1990
2010
|
|
|
1991
2011
|
state_input_stderr_log_level_var_loaded: int = self.eval_parent_state(EnvState.state_input_stderr_log_level_var_loaded.name)
|
|
1992
2012
|
|
|
1993
|
-
state_default_stderr_logger_configured: logging.Handler = self.eval_parent_state(EnvState.state_default_stderr_log_handler_configured.name)
|
|
1994
|
-
|
|
1995
2013
|
parsed_args = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
1996
2014
|
stderr_log_level_quiet_count: int = getattr(
|
|
1997
2015
|
parsed_args,
|
|
@@ -2002,9 +2020,9 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
2002
2020
|
SyntaxArg.dest_verbose,
|
|
2003
2021
|
)
|
|
2004
2022
|
|
|
2005
|
-
|
|
2023
|
+
state_input_stderr_log_level_eval_finalized: int
|
|
2006
2024
|
if stderr_log_level_quiet_count == 0 and stderr_log_level_verbose_count == 0:
|
|
2007
|
-
|
|
2025
|
+
state_input_stderr_log_level_eval_finalized = state_input_stderr_log_level_var_loaded
|
|
2008
2026
|
else:
|
|
2009
2027
|
# FT_38_73_38_52.log_verbosity.md
|
|
2010
2028
|
# The base is the numeric value of `ConfConstInput.default_PROTOPRIMER_STDERR_LOG_LEVEL`.
|
|
@@ -2015,37 +2033,50 @@ class Bootstrapper_state_input_stderr_log_level_eval_finalized(AbstractCachingSt
|
|
|
2015
2033
|
|
|
2016
2034
|
relative_log_level = 10 * (stderr_log_level_quiet_count - stderr_log_level_verbose_count)
|
|
2017
2035
|
|
|
2018
|
-
|
|
2036
|
+
state_input_stderr_log_level_eval_finalized = base_log_level + relative_log_level
|
|
2019
2037
|
|
|
2020
|
-
if
|
|
2021
|
-
|
|
2038
|
+
if state_input_stderr_log_level_eval_finalized < logging.NOTSET:
|
|
2039
|
+
state_input_stderr_log_level_eval_finalized = logging.NOTSET
|
|
2040
|
+
|
|
2041
|
+
return state_input_stderr_log_level_eval_finalized
|
|
2022
2042
|
|
|
2023
|
-
# TODO: TODO_60_63_68_81.refactor_DAG_builder.md:
|
|
2024
|
-
# Evaluate `stderr_log_level_eval_finalized`
|
|
2025
|
-
# but do not configure anything for `start_app` and `lib_call`
|
|
2026
2043
|
|
|
2027
|
-
|
|
2044
|
+
# noinspection PyPep8Naming
|
|
2045
|
+
@trivial_factory
|
|
2046
|
+
class Bootstrapper_state_input_stderr_log_level_handler_configured(AbstractCachingStateNode[logging.Handler]):
|
|
2047
|
+
"""
|
|
2048
|
+
There is a narrow window between the default log level is set and this state is evaluated.
|
|
2049
|
+
To control the default log level, see `EnvVar.var_PROTOPRIMER_STDERR_LOG_LEVEL`.
|
|
2050
|
+
"""
|
|
2051
|
+
|
|
2052
|
+
_parent_states = staticmethod(
|
|
2053
|
+
lambda: [
|
|
2054
|
+
EnvState.state_default_stderr_log_handler_configured.name,
|
|
2055
|
+
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2056
|
+
]
|
|
2057
|
+
)
|
|
2058
|
+
_state_name = staticmethod(lambda: EnvState.state_input_stderr_log_level_handler_configured.name)
|
|
2059
|
+
|
|
2060
|
+
def _eval_state_once(self) -> ValueType:
|
|
2061
|
+
|
|
2062
|
+
state_default_stderr_logger_configured: logging.Handler = self.eval_parent_state(EnvState.state_default_stderr_log_handler_configured.name)
|
|
2063
|
+
|
|
2064
|
+
state_input_stderr_log_level_eval_finalized: int = self.eval_parent_state(EnvState.state_input_stderr_log_level_eval_finalized.name)
|
|
2065
|
+
|
|
2066
|
+
state_default_stderr_logger_configured.setLevel(state_input_stderr_log_level_eval_finalized)
|
|
2028
2067
|
assert isinstance(
|
|
2029
2068
|
state_default_stderr_logger_configured.formatter,
|
|
2030
2069
|
_PrimerStderrLogFormatter,
|
|
2031
2070
|
)
|
|
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)
|
|
2071
|
+
state_default_stderr_logger_configured.formatter.set_verbosity_level(state_input_stderr_log_level_eval_finalized)
|
|
2041
2072
|
|
|
2042
2073
|
# Remove stack trace for levels >= WARNING (it will only print the exception itself):
|
|
2043
|
-
if
|
|
2074
|
+
if state_input_stderr_log_level_eval_finalized >= logging.WARNING:
|
|
2044
2075
|
# Avoid changing that in tests - it changes the global state and causes many tests to fail unexpectedly:
|
|
2045
2076
|
if not is_test_run():
|
|
2046
2077
|
sys.tracebacklimit = 0
|
|
2047
2078
|
|
|
2048
|
-
return
|
|
2079
|
+
return state_default_stderr_logger_configured
|
|
2049
2080
|
|
|
2050
2081
|
|
|
2051
2082
|
# noinspection PyPep8Naming
|
|
@@ -2074,13 +2105,12 @@ class Bootstrapper_state_input_sub_command_arg_loaded(AbstractCachingStateNode[S
|
|
|
2074
2105
|
|
|
2075
2106
|
|
|
2076
2107
|
# noinspection PyPep8Naming
|
|
2077
|
-
@
|
|
2078
|
-
class
|
|
2108
|
+
@conditional_factory
|
|
2109
|
+
class Bootstrapper_state_input_final_state_eval_finalized_func_boot_env(AbstractCachingStateNode[str]):
|
|
2079
2110
|
|
|
2080
2111
|
_parent_states = staticmethod(
|
|
2081
2112
|
lambda: [
|
|
2082
2113
|
EnvState.state_args_parsed.name,
|
|
2083
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2084
2114
|
]
|
|
2085
2115
|
)
|
|
2086
2116
|
_state_name = staticmethod(lambda: EnvState.state_input_final_state_eval_finalized.name)
|
|
@@ -2088,8 +2118,6 @@ class Bootstrapper_state_input_final_state_eval_finalized(AbstractCachingStateNo
|
|
|
2088
2118
|
def _eval_state_once(self) -> ValueType:
|
|
2089
2119
|
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
2090
2120
|
|
|
2091
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2092
|
-
|
|
2093
2121
|
state_input_final_state_eval_finalized: str | None
|
|
2094
2122
|
state_input_final_state_eval_finalized = getattr(
|
|
2095
2123
|
state_args_parsed,
|
|
@@ -2107,33 +2135,55 @@ class Bootstrapper_state_input_final_state_eval_finalized(AbstractCachingStateNo
|
|
|
2107
2135
|
return state_input_final_state_eval_finalized
|
|
2108
2136
|
|
|
2109
2137
|
|
|
2138
|
+
# noinspection PyPep8Naming
|
|
2139
|
+
@conditional_factory
|
|
2140
|
+
class Bootstrapper_state_input_final_state_eval_finalized_not_func_boot_env(AbstractCachingStateNode[str]):
|
|
2141
|
+
|
|
2142
|
+
_parent_states = staticmethod(lambda: [])
|
|
2143
|
+
_state_name = staticmethod(lambda: EnvState.state_input_final_state_eval_finalized.name)
|
|
2144
|
+
|
|
2145
|
+
def _eval_state_once(self) -> ValueType:
|
|
2146
|
+
state_input_final_state_eval_finalized = self.env_ctx.final_state
|
|
2147
|
+
return state_input_final_state_eval_finalized
|
|
2148
|
+
|
|
2149
|
+
|
|
2150
|
+
# noinspection PyPep8Naming
|
|
2151
|
+
class Factory_state_input_final_state_eval_finalized(NodeFactory[StateStride]):
|
|
2152
|
+
|
|
2153
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2154
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2155
|
+
EntryFunc.func_boot_env,
|
|
2156
|
+
EntryFunc.func_run_main,
|
|
2157
|
+
]:
|
|
2158
|
+
return Bootstrapper_state_input_final_state_eval_finalized_func_boot_env(self.env_ctx)
|
|
2159
|
+
else:
|
|
2160
|
+
return Bootstrapper_state_input_final_state_eval_finalized_not_func_boot_env(self.env_ctx)
|
|
2161
|
+
|
|
2162
|
+
|
|
2110
2163
|
# noinspection PyPep8Naming
|
|
2111
2164
|
@trivial_factory
|
|
2112
|
-
class
|
|
2165
|
+
class Bootstrapper_state_func_boot_env_executed(AbstractCachingStateNode[bool]):
|
|
2113
2166
|
"""
|
|
2114
|
-
This is a special node - it traverses ALL nodes.
|
|
2167
|
+
This is a special node - it traverses ALL nodes for `EntryFunc` cases with parsed args.
|
|
2115
2168
|
|
|
2116
|
-
BUT: It does not depend on ALL nodes - instead,
|
|
2169
|
+
BUT: It does not depend on ALL nodes - instead, re-executes the graph with a new target.
|
|
2117
2170
|
"""
|
|
2118
2171
|
|
|
2119
2172
|
_parent_states = staticmethod(
|
|
2120
2173
|
lambda: [
|
|
2121
|
-
EnvState.
|
|
2174
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
2122
2175
|
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2123
2176
|
EnvState.state_input_final_state_eval_finalized.name,
|
|
2124
2177
|
]
|
|
2125
2178
|
)
|
|
2126
|
-
_state_name = staticmethod(lambda: EnvState.
|
|
2179
|
+
_state_name = staticmethod(lambda: EnvState.state_func_boot_env_executed.name)
|
|
2127
2180
|
|
|
2128
2181
|
def _eval_state_once(self) -> ValueType:
|
|
2129
2182
|
|
|
2130
|
-
|
|
2131
|
-
assert state_input_stderr_log_level_eval_finalized >= 0
|
|
2183
|
+
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2132
2184
|
|
|
2133
2185
|
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2134
2186
|
|
|
2135
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2136
|
-
|
|
2137
2187
|
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2138
2188
|
|
|
2139
2189
|
selected_strategy: RunStrategy
|
|
@@ -2156,6 +2206,111 @@ class Bootstrapper_state_sub_command_executed(AbstractCachingStateNode[bool]):
|
|
|
2156
2206
|
return True
|
|
2157
2207
|
|
|
2158
2208
|
|
|
2209
|
+
# noinspection PyPep8Naming
|
|
2210
|
+
@trivial_factory
|
|
2211
|
+
class Bootstrapper_state_func_start_app_executed(AbstractCachingStateNode[bool]):
|
|
2212
|
+
|
|
2213
|
+
_parent_states = staticmethod(
|
|
2214
|
+
lambda: [
|
|
2215
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
2216
|
+
EnvState.state_input_final_state_eval_finalized.name,
|
|
2217
|
+
]
|
|
2218
|
+
)
|
|
2219
|
+
_state_name = staticmethod(lambda: EnvState.state_func_start_app_executed.name)
|
|
2220
|
+
|
|
2221
|
+
def _eval_state_once(self) -> ValueType:
|
|
2222
|
+
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2223
|
+
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2224
|
+
state_node.eval_own_state()
|
|
2225
|
+
return True
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
# noinspection PyPep8Naming
|
|
2229
|
+
@trivial_factory
|
|
2230
|
+
class Bootstrapper_state_func_call_lib_executed(AbstractCachingStateNode[bool]):
|
|
2231
|
+
|
|
2232
|
+
_parent_states = staticmethod(
|
|
2233
|
+
lambda: [
|
|
2234
|
+
EnvState.state_input_final_state_eval_finalized.name,
|
|
2235
|
+
]
|
|
2236
|
+
)
|
|
2237
|
+
_state_name = staticmethod(lambda: EnvState.state_func_call_lib_executed.name)
|
|
2238
|
+
|
|
2239
|
+
def _eval_state_once(self) -> ValueType:
|
|
2240
|
+
state_input_final_state_eval_finalized: str = self.eval_parent_state(EnvState.state_input_final_state_eval_finalized.name)
|
|
2241
|
+
state_node: StateNode = self.env_ctx.state_graph.get_state_node(state_input_final_state_eval_finalized)
|
|
2242
|
+
state_node.eval_own_state()
|
|
2243
|
+
return True
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
# noinspection PyPep8Naming
|
|
2247
|
+
@conditional_factory
|
|
2248
|
+
class Bootstrapper_state_everything_executed_func_boot_env(AbstractCachingStateNode[bool]):
|
|
2249
|
+
|
|
2250
|
+
_parent_states = staticmethod(
|
|
2251
|
+
lambda: [
|
|
2252
|
+
EnvState.state_func_boot_env_executed.name,
|
|
2253
|
+
]
|
|
2254
|
+
)
|
|
2255
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2256
|
+
|
|
2257
|
+
def _eval_state_once(self) -> ValueType:
|
|
2258
|
+
state_func_boot_env_executed: bool = self.eval_parent_state(EnvState.state_func_boot_env_executed.name)
|
|
2259
|
+
return state_func_boot_env_executed
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
# noinspection PyPep8Naming
|
|
2263
|
+
@conditional_factory
|
|
2264
|
+
class Bootstrapper_state_everything_executed_func_start_app(AbstractCachingStateNode[bool]):
|
|
2265
|
+
|
|
2266
|
+
_parent_states = staticmethod(
|
|
2267
|
+
lambda: [
|
|
2268
|
+
EnvState.state_func_start_app_executed.name,
|
|
2269
|
+
]
|
|
2270
|
+
)
|
|
2271
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2272
|
+
|
|
2273
|
+
def _eval_state_once(self) -> ValueType:
|
|
2274
|
+
state_func_start_app_executed: bool = self.eval_parent_state(EnvState.state_func_start_app_executed.name)
|
|
2275
|
+
return state_func_start_app_executed
|
|
2276
|
+
|
|
2277
|
+
|
|
2278
|
+
# noinspection PyPep8Naming
|
|
2279
|
+
@conditional_factory
|
|
2280
|
+
class Bootstrapper_state_everything_executed_func_call_lib(AbstractCachingStateNode[bool]):
|
|
2281
|
+
|
|
2282
|
+
_parent_states = staticmethod(
|
|
2283
|
+
lambda: [
|
|
2284
|
+
EnvState.state_func_call_lib_executed.name,
|
|
2285
|
+
]
|
|
2286
|
+
)
|
|
2287
|
+
_state_name = staticmethod(lambda: EnvState.state_everything_executed.name)
|
|
2288
|
+
|
|
2289
|
+
def _eval_state_once(self) -> ValueType:
|
|
2290
|
+
state_func_call_lib_executed: bool = self.eval_parent_state(EnvState.state_func_call_lib_executed.name)
|
|
2291
|
+
return state_func_call_lib_executed
|
|
2292
|
+
|
|
2293
|
+
|
|
2294
|
+
# noinspection PyPep8Naming
|
|
2295
|
+
class Factory_state_everything_executed(NodeFactory[StateStride]):
|
|
2296
|
+
"""
|
|
2297
|
+
This is a special node - it traverses ALL nodes.
|
|
2298
|
+
"""
|
|
2299
|
+
|
|
2300
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2301
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2302
|
+
EntryFunc.func_boot_env,
|
|
2303
|
+
EntryFunc.func_run_main,
|
|
2304
|
+
]:
|
|
2305
|
+
return Bootstrapper_state_everything_executed_func_boot_env(self.env_ctx)
|
|
2306
|
+
elif self.env_ctx.graph_coordinates.entry_func == EntryFunc.func_start_app:
|
|
2307
|
+
return Bootstrapper_state_everything_executed_func_start_app(self.env_ctx)
|
|
2308
|
+
elif self.env_ctx.graph_coordinates.entry_func == EntryFunc.func_call_lib:
|
|
2309
|
+
return Bootstrapper_state_everything_executed_func_call_lib(self.env_ctx)
|
|
2310
|
+
else:
|
|
2311
|
+
raise RuntimeError(self.env_ctx.graph_coordinates.entry_func)
|
|
2312
|
+
|
|
2313
|
+
|
|
2159
2314
|
# noinspection PyPep8Naming
|
|
2160
2315
|
@trivial_factory
|
|
2161
2316
|
class Bootstrapper_state_input_start_id_var_loaded(AbstractCachingStateNode[str]):
|
|
@@ -2280,7 +2435,6 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_func_call_lib(AbstractC
|
|
|
2280
2435
|
class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(AbstractCachingStateNode[str]):
|
|
2281
2436
|
_parent_states = staticmethod(
|
|
2282
2437
|
lambda: [
|
|
2283
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2284
2438
|
EnvState.state_input_proto_code_file_abs_path_var_loaded.name,
|
|
2285
2439
|
EnvState.state_stride_py_arbitrary_reached.name,
|
|
2286
2440
|
]
|
|
@@ -2289,10 +2443,6 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2289
2443
|
|
|
2290
2444
|
def _eval_state_once(self) -> ValueType:
|
|
2291
2445
|
|
|
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
2446
|
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
2447
|
|
|
2298
2448
|
assert self.env_ctx.get_stride().value >= StateStride.stride_py_arbitrary.value
|
|
@@ -2306,7 +2456,10 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2306
2456
|
else:
|
|
2307
2457
|
log_python_context()
|
|
2308
2458
|
if os.environ.get(EnvVar.var_PROTOPRIMER_MOCKED_RESTART.value, None) is None:
|
|
2309
|
-
if
|
|
2459
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2460
|
+
EntryFunc.func_boot_env,
|
|
2461
|
+
EntryFunc.func_run_main,
|
|
2462
|
+
]:
|
|
2310
2463
|
if self.env_ctx.get_stride().value == StateStride.stride_py_arbitrary.value:
|
|
2311
2464
|
state_proto_code_file_abs_path_inited = os.path.abspath(__file__)
|
|
2312
2465
|
else:
|
|
@@ -2324,7 +2477,7 @@ class Bootstrapper_state_proto_code_file_abs_path_inited_not_func_call_lib(Abstr
|
|
|
2324
2477
|
if is_venv():
|
|
2325
2478
|
logger.warning(f"`sys.executable` [{sys.executable}] for [{StateStride.stride_py_required.name}] evaluated from config should ideally be outside `venv`")
|
|
2326
2479
|
else:
|
|
2327
|
-
#
|
|
2480
|
+
# Rely only on the `EnvVar.var_PROTOPRIMER_PROTO_CODE` env var:
|
|
2328
2481
|
assert state_input_proto_code_file_abs_path_var_loaded is not None
|
|
2329
2482
|
state_proto_code_file_abs_path_inited = state_input_proto_code_file_abs_path_var_loaded
|
|
2330
2483
|
else:
|
|
@@ -2402,8 +2555,6 @@ class Bootstrapper_state_primer_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2402
2555
|
|
|
2403
2556
|
_parent_states = staticmethod(
|
|
2404
2557
|
lambda: [
|
|
2405
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2406
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2407
2558
|
EnvState.state_proto_code_file_abs_path_inited.name,
|
|
2408
2559
|
EnvState.state_primer_conf_file_abs_path_inited.name,
|
|
2409
2560
|
]
|
|
@@ -2564,8 +2715,6 @@ class Bootstrapper_state_client_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2564
2715
|
|
|
2565
2716
|
_parent_states = staticmethod(
|
|
2566
2717
|
lambda: [
|
|
2567
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2568
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2569
2718
|
EnvState.state_global_conf_file_abs_path_inited.name,
|
|
2570
2719
|
]
|
|
2571
2720
|
)
|
|
@@ -2600,17 +2749,8 @@ class Bootstrapper_state_client_conf_file_data_loaded(AbstractCachingStateNode[d
|
|
|
2600
2749
|
|
|
2601
2750
|
|
|
2602
2751
|
# 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)
|
|
2752
|
+
@conditional_factory
|
|
2753
|
+
class Base_state_selected_env_dir_rel_path(AbstractCachingStateNode[str]):
|
|
2614
2754
|
|
|
2615
2755
|
def _eval_state_once(self) -> ValueType:
|
|
2616
2756
|
|
|
@@ -2641,14 +2781,11 @@ class Bootstrapper_state_selected_env_dir_rel_path_inited(AbstractCachingStateNo
|
|
|
2641
2781
|
|
|
2642
2782
|
return state_selected_env_dir_rel_path_inited
|
|
2643
2783
|
|
|
2784
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2785
|
+
raise NotImplementedError()
|
|
2786
|
+
|
|
2644
2787
|
def _select_client_local_env_dir_any_path(self) -> str | None:
|
|
2645
|
-
|
|
2646
|
-
env_conf_dir_any_path: str | None = getattr(
|
|
2647
|
-
state_args_parsed,
|
|
2648
|
-
ParsedArg.name_selected_env_dir.value,
|
|
2649
|
-
# NOTE: The value is only set for `SubCommand.command_boot`, otherwise, this default is used:
|
|
2650
|
-
None,
|
|
2651
|
-
)
|
|
2788
|
+
env_conf_dir_any_path = self._select_env_conf_dir_any_path()
|
|
2652
2789
|
if env_conf_dir_any_path is None:
|
|
2653
2790
|
# Use the default env configured:
|
|
2654
2791
|
state_client_conf_file_data_loaded: dict = self.eval_parent_state(EnvState.state_client_conf_file_data_loaded.name)
|
|
@@ -2696,13 +2833,68 @@ class Bootstrapper_state_selected_env_dir_rel_path_inited(AbstractCachingStateNo
|
|
|
2696
2833
|
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
2834
|
|
|
2698
2835
|
|
|
2836
|
+
# noinspection PyPep8Naming
|
|
2837
|
+
@conditional_factory
|
|
2838
|
+
class Bootstrapper_state_selected_env_dir_rel_path_inited_func_boot_env(Base_state_selected_env_dir_rel_path):
|
|
2839
|
+
|
|
2840
|
+
_parent_states = staticmethod(
|
|
2841
|
+
lambda: [
|
|
2842
|
+
EnvState.state_args_parsed.name,
|
|
2843
|
+
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2844
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
2845
|
+
]
|
|
2846
|
+
)
|
|
2847
|
+
_state_name = staticmethod(lambda: EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
2848
|
+
|
|
2849
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2850
|
+
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
2851
|
+
env_conf_dir_any_path: str | None = getattr(
|
|
2852
|
+
state_args_parsed,
|
|
2853
|
+
ParsedArg.name_selected_env_dir.value,
|
|
2854
|
+
# NOTE: The value is only set for `SubCommand.command_boot`, otherwise, this default is used:
|
|
2855
|
+
None,
|
|
2856
|
+
)
|
|
2857
|
+
return env_conf_dir_any_path
|
|
2858
|
+
|
|
2859
|
+
|
|
2860
|
+
# noinspection PyPep8Naming
|
|
2861
|
+
@conditional_factory
|
|
2862
|
+
class Bootstrapper_state_selected_env_dir_rel_path_inited_not_func_boot_env(Base_state_selected_env_dir_rel_path):
|
|
2863
|
+
|
|
2864
|
+
_parent_states = staticmethod(
|
|
2865
|
+
lambda: [
|
|
2866
|
+
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2867
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
2868
|
+
]
|
|
2869
|
+
)
|
|
2870
|
+
_state_name = staticmethod(lambda: EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
2871
|
+
|
|
2872
|
+
def _select_env_conf_dir_any_path(self) -> str | None:
|
|
2873
|
+
return None
|
|
2874
|
+
|
|
2875
|
+
|
|
2876
|
+
# noinspection PyPep8Naming
|
|
2877
|
+
class Factory_state_selected_env_dir_rel_path_inited(NodeFactory[StateStride]):
|
|
2878
|
+
"""
|
|
2879
|
+
This is a special node - it traverses ALL nodes.
|
|
2880
|
+
"""
|
|
2881
|
+
|
|
2882
|
+
def create_state_node(self) -> StateNode[ValueType]:
|
|
2883
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2884
|
+
EntryFunc.func_boot_env,
|
|
2885
|
+
EntryFunc.func_run_main,
|
|
2886
|
+
]:
|
|
2887
|
+
return Bootstrapper_state_selected_env_dir_rel_path_inited_func_boot_env(self.env_ctx)
|
|
2888
|
+
else:
|
|
2889
|
+
return Bootstrapper_state_selected_env_dir_rel_path_inited_not_func_boot_env(self.env_ctx)
|
|
2890
|
+
|
|
2891
|
+
|
|
2699
2892
|
# noinspection PyPep8Naming
|
|
2700
2893
|
@trivial_factory
|
|
2701
2894
|
class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingStateNode[str]):
|
|
2702
2895
|
|
|
2703
2896
|
_parent_states = staticmethod(
|
|
2704
2897
|
lambda: [
|
|
2705
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2706
2898
|
EnvState.state_ref_root_dir_abs_path_inited.name,
|
|
2707
2899
|
EnvState.state_client_conf_file_data_loaded.name,
|
|
2708
2900
|
EnvState.state_selected_env_dir_rel_path_inited.name,
|
|
@@ -2712,8 +2904,6 @@ class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingState
|
|
|
2712
2904
|
|
|
2713
2905
|
def _eval_state_once(self) -> ValueType:
|
|
2714
2906
|
|
|
2715
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
2716
|
-
|
|
2717
2907
|
state_ref_root_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_ref_root_dir_abs_path_inited.name)
|
|
2718
2908
|
|
|
2719
2909
|
state_selected_env_dir_rel_path_inited: str | None = self.eval_parent_state(EnvState.state_selected_env_dir_rel_path_inited.name)
|
|
@@ -2743,7 +2933,10 @@ class Bootstrapper_state_local_conf_symlink_abs_path_inited(AbstractCachingState
|
|
|
2743
2933
|
if os.path.exists(state_local_conf_symlink_abs_path_inited):
|
|
2744
2934
|
if os.path.islink(state_local_conf_symlink_abs_path_inited):
|
|
2745
2935
|
if os.path.isdir(state_local_conf_symlink_abs_path_inited):
|
|
2746
|
-
if
|
|
2936
|
+
if self.env_ctx.graph_coordinates.entry_func in [
|
|
2937
|
+
EntryFunc.func_start_app,
|
|
2938
|
+
EntryFunc.func_call_lib,
|
|
2939
|
+
]:
|
|
2747
2940
|
# Nothing to do:
|
|
2748
2941
|
pass
|
|
2749
2942
|
else:
|
|
@@ -2803,8 +2996,6 @@ class Bootstrapper_state_env_conf_file_data_loaded(AbstractCachingStateNode[dict
|
|
|
2803
2996
|
|
|
2804
2997
|
_parent_states = staticmethod(
|
|
2805
2998
|
lambda: [
|
|
2806
|
-
EnvState.state_input_stderr_log_level_eval_finalized.name,
|
|
2807
|
-
EnvState.state_input_sub_command_arg_loaded.name,
|
|
2808
2999
|
EnvState.state_local_conf_file_abs_path_inited.name,
|
|
2809
3000
|
]
|
|
2810
3001
|
)
|
|
@@ -3163,6 +3354,25 @@ class Bootstrapper_state_install_specs_inited(AbstractOverriddenFieldCachingStat
|
|
|
3163
3354
|
return install_specs
|
|
3164
3355
|
|
|
3165
3356
|
|
|
3357
|
+
# noinspection PyPep8Naming
|
|
3358
|
+
@trivial_factory
|
|
3359
|
+
class Bootstrapper_state_version_constraints_file_basename_inited(AbstractOverriddenFieldCachingStateNode[str]):
|
|
3360
|
+
|
|
3361
|
+
_parent_states = staticmethod(
|
|
3362
|
+
lambda: [
|
|
3363
|
+
EnvState.state_client_conf_file_data_loaded.name,
|
|
3364
|
+
EnvState.state_env_conf_file_data_loaded.name,
|
|
3365
|
+
]
|
|
3366
|
+
)
|
|
3367
|
+
_state_name = staticmethod(lambda: EnvState.state_version_constraints_file_basename_inited.name)
|
|
3368
|
+
|
|
3369
|
+
def _eval_state_once(self) -> ValueType:
|
|
3370
|
+
return self._get_overridden_value_or_default(
|
|
3371
|
+
ConfField.field_version_constraints_file_basename.value,
|
|
3372
|
+
ConfConstEnv.default_version_constraints_file_basename,
|
|
3373
|
+
)
|
|
3374
|
+
|
|
3375
|
+
|
|
3166
3376
|
# noinspection PyPep8Naming
|
|
3167
3377
|
@trivial_factory
|
|
3168
3378
|
class Bootstrapper_state_derived_conf_data_loaded(AbstractCachingStateNode[dict]):
|
|
@@ -3271,7 +3481,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3271
3481
|
_parent_states = staticmethod(
|
|
3272
3482
|
lambda: [
|
|
3273
3483
|
EnvState.state_args_parsed.name,
|
|
3274
|
-
EnvState.
|
|
3484
|
+
EnvState.state_input_stderr_log_level_handler_configured.name,
|
|
3275
3485
|
EnvState.state_input_start_id_var_loaded.name,
|
|
3276
3486
|
EnvState.state_local_log_dir_abs_path_inited.name,
|
|
3277
3487
|
]
|
|
@@ -3284,7 +3494,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3284
3494
|
|
|
3285
3495
|
state_local_log_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_log_dir_abs_path_inited.name)
|
|
3286
3496
|
|
|
3287
|
-
|
|
3497
|
+
state_input_stderr_log_level_handler_configured: logging.Handler = self.eval_parent_state(EnvState.state_input_stderr_log_level_handler_configured.name)
|
|
3288
3498
|
|
|
3289
3499
|
script_path = sys.argv[0]
|
|
3290
3500
|
script_name = os.path.basename(script_path)
|
|
@@ -3292,7 +3502,7 @@ class Bootstrapper_state_default_file_log_handler_configured(AbstractCachingStat
|
|
|
3292
3502
|
file_handler = _configure_primer_file_log_handler(
|
|
3293
3503
|
script_name,
|
|
3294
3504
|
state_input_start_id_var_loaded,
|
|
3295
|
-
|
|
3505
|
+
state_input_stderr_log_level_handler_configured,
|
|
3296
3506
|
state_local_log_dir_abs_path_inited,
|
|
3297
3507
|
)
|
|
3298
3508
|
|
|
@@ -3330,14 +3540,6 @@ class Bootstrapper_state_stride_py_required_reached_not_command_start(AbstractCa
|
|
|
3330
3540
|
if self.env_ctx.has_stride_reached(next_stride=state_stride_py_required_reached):
|
|
3331
3541
|
return self.env_ctx.set_max_stride(state_stride_py_required_reached)
|
|
3332
3542
|
|
|
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
3543
|
state_input_start_id_var_loaded: str = self.eval_parent_state(EnvState.state_input_start_id_var_loaded.name)
|
|
3342
3544
|
|
|
3343
3545
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
@@ -3425,7 +3627,7 @@ class Factory_state_stride_py_required_reached(NodeFactory[StateStride]):
|
|
|
3425
3627
|
@trivial_factory
|
|
3426
3628
|
class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
3427
3629
|
"""
|
|
3428
|
-
Removes current `venv` dir and `
|
|
3630
|
+
Removes current `venv` dir and `version_constraints.txt` file (to trigger their re-creation subsequently).
|
|
3429
3631
|
"""
|
|
3430
3632
|
|
|
3431
3633
|
_parent_states = staticmethod(
|
|
@@ -3437,6 +3639,7 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3437
3639
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
3438
3640
|
EnvState.state_local_venv_dir_abs_path_inited.name,
|
|
3439
3641
|
EnvState.state_local_tmp_dir_abs_path_inited.name,
|
|
3642
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3440
3643
|
EnvState.state_stride_py_required_reached.name,
|
|
3441
3644
|
]
|
|
3442
3645
|
)
|
|
@@ -3444,8 +3647,6 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3444
3647
|
|
|
3445
3648
|
def _eval_state_once(self) -> ValueType:
|
|
3446
3649
|
|
|
3447
|
-
state_args_parsed: argparse.Namespace = self.eval_parent_state(EnvState.state_args_parsed.name)
|
|
3448
|
-
|
|
3449
3650
|
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
3450
3651
|
|
|
3451
3652
|
if state_input_sub_command_arg_loaded == SubCommand.command_start:
|
|
@@ -3463,8 +3664,6 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3463
3664
|
state_stride_py_required_reached: StateStride = self.eval_parent_state(EnvState.state_stride_py_required_reached.name)
|
|
3464
3665
|
assert self.env_ctx.get_stride().value >= StateStride.stride_py_required.value
|
|
3465
3666
|
|
|
3466
|
-
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3467
|
-
|
|
3468
3667
|
# Reboot can only happen outside `venv` (to delete it):
|
|
3469
3668
|
if not (reboot_env and state_stride_py_required_reached == StateStride.stride_py_required):
|
|
3470
3669
|
return False
|
|
@@ -3489,9 +3688,10 @@ class Bootstrapper_state_reboot_triggered(AbstractCachingStateNode[bool]):
|
|
|
3489
3688
|
)
|
|
3490
3689
|
|
|
3491
3690
|
state_local_conf_symlink_abs_path_inited = self.eval_parent_state(EnvState.state_local_conf_symlink_abs_path_inited.name)
|
|
3691
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
3492
3692
|
constraints_txt_path = os.path.join(
|
|
3493
3693
|
state_local_conf_symlink_abs_path_inited,
|
|
3494
|
-
|
|
3694
|
+
state_version_constraints_file_basename_inited,
|
|
3495
3695
|
)
|
|
3496
3696
|
if os.path.exists(constraints_txt_path):
|
|
3497
3697
|
logger.info(f"removing version constraints file [{constraints_txt_path}]")
|
|
@@ -3597,8 +3797,6 @@ class Bootstrapper_state_stride_py_venv_reached(AbstractCachingStateNode[StateSt
|
|
|
3597
3797
|
|
|
3598
3798
|
state_input_start_id_var_loaded: str = self.eval_parent_state(EnvState.state_input_start_id_var_loaded.name)
|
|
3599
3799
|
|
|
3600
|
-
state_reboot_triggered: bool = self.eval_parent_state(EnvState.state_reboot_triggered.name)
|
|
3601
|
-
|
|
3602
3800
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3603
3801
|
|
|
3604
3802
|
state_selected_python_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_selected_python_file_abs_path_inited.name)
|
|
@@ -3668,6 +3866,7 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3668
3866
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
3669
3867
|
EnvState.state_project_descriptors_inited.name,
|
|
3670
3868
|
EnvState.state_install_specs_inited.name,
|
|
3869
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3671
3870
|
EnvState.state_venv_driver_prepared.name,
|
|
3672
3871
|
EnvState.state_stride_py_venv_reached.name,
|
|
3673
3872
|
]
|
|
@@ -3701,6 +3900,8 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3701
3900
|
|
|
3702
3901
|
state_venv_driver_prepared: VenvDriverBase = self.eval_parent_state(EnvState.state_venv_driver_prepared.name)
|
|
3703
3902
|
|
|
3903
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
3904
|
+
|
|
3704
3905
|
reboot_env: bool = state_args_parsed.sub_command == SubCommand.command_reboot.value
|
|
3705
3906
|
|
|
3706
3907
|
do_install: bool = (
|
|
@@ -3714,7 +3915,7 @@ class Bootstrapper_state_protoprimer_package_installed(AbstractCachingStateNode[
|
|
|
3714
3915
|
|
|
3715
3916
|
constraints_txt_path = os.path.join(
|
|
3716
3917
|
state_local_conf_symlink_abs_path_inited,
|
|
3717
|
-
|
|
3918
|
+
state_version_constraints_file_basename_inited,
|
|
3718
3919
|
)
|
|
3719
3920
|
if not os.path.exists(constraints_txt_path):
|
|
3720
3921
|
logger.info(f"creating empty constraints file [{constraints_txt_path}]")
|
|
@@ -3806,6 +4007,7 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3806
4007
|
lambda: [
|
|
3807
4008
|
EnvState.state_input_sub_command_arg_loaded.name,
|
|
3808
4009
|
EnvState.state_local_conf_symlink_abs_path_inited.name,
|
|
4010
|
+
EnvState.state_version_constraints_file_basename_inited.name,
|
|
3809
4011
|
EnvState.state_venv_driver_prepared.name,
|
|
3810
4012
|
EnvState.state_protoprimer_package_installed.name,
|
|
3811
4013
|
]
|
|
@@ -3818,7 +4020,7 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3818
4020
|
|
|
3819
4021
|
if state_input_sub_command_arg_loaded == SubCommand.command_start:
|
|
3820
4022
|
# The only reason for `EnvState.state_version_constraints_generated`
|
|
3821
|
-
# is to re-generate the `
|
|
4023
|
+
# is to re-generate the `version_constraints.txt` file based on `venv`.
|
|
3822
4024
|
# Skip it as `venv` is supposed to be ready in `SubCommand.command_start`:
|
|
3823
4025
|
return False
|
|
3824
4026
|
|
|
@@ -3831,11 +4033,13 @@ class Bootstrapper_state_version_constraints_generated(AbstractCachingStateNode[
|
|
|
3831
4033
|
|
|
3832
4034
|
state_venv_driver_prepared: VenvDriverBase = self.eval_parent_state(EnvState.state_venv_driver_prepared.name)
|
|
3833
4035
|
|
|
4036
|
+
state_version_constraints_file_basename_inited: str = self.eval_parent_state(EnvState.state_version_constraints_file_basename_inited.name)
|
|
4037
|
+
|
|
3834
4038
|
state_venv_driver_prepared.pin_versions(
|
|
3835
4039
|
get_path_to_curr_python(),
|
|
3836
4040
|
os.path.join(
|
|
3837
4041
|
state_local_conf_symlink_abs_path_inited,
|
|
3838
|
-
|
|
4042
|
+
state_version_constraints_file_basename_inited,
|
|
3839
4043
|
),
|
|
3840
4044
|
)
|
|
3841
4045
|
|
|
@@ -3875,8 +4079,6 @@ class Bootstrapper_state_stride_deps_updated_reached(AbstractCachingStateNode[St
|
|
|
3875
4079
|
|
|
3876
4080
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
3877
4081
|
|
|
3878
|
-
state_version_constraints_generated: bool = self.eval_parent_state(EnvState.state_version_constraints_generated.name)
|
|
3879
|
-
|
|
3880
4082
|
state_local_venv_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_venv_dir_abs_path_inited.name)
|
|
3881
4083
|
|
|
3882
4084
|
venv_path_to_python: str = os.path.join(
|
|
@@ -3915,7 +4117,6 @@ class Bootstrapper_state_proto_code_updated(AbstractCachingStateNode[bool]):
|
|
|
3915
4117
|
|
|
3916
4118
|
def _eval_state_once(self) -> ValueType:
|
|
3917
4119
|
|
|
3918
|
-
state_stride_deps_updated_reached: StateStride = self.eval_parent_state(EnvState.state_stride_deps_updated_reached.name)
|
|
3919
4120
|
assert self.env_ctx.get_stride().value >= StateStride.stride_deps_updated.value
|
|
3920
4121
|
|
|
3921
4122
|
if self.env_ctx.get_stride().value != StateStride.stride_deps_updated.value:
|
|
@@ -4002,15 +4203,11 @@ class Bootstrapper_state_stride_src_updated_reached(AbstractCachingStateNode[Sta
|
|
|
4002
4203
|
|
|
4003
4204
|
state_stride_src_updated_reached: StateStride = StateStride.stride_src_updated
|
|
4004
4205
|
|
|
4005
|
-
state_input_sub_command_arg_loaded: SubCommand = self.eval_parent_state(EnvState.state_input_sub_command_arg_loaded.name)
|
|
4006
|
-
|
|
4007
4206
|
if self.env_ctx.has_stride_reached(next_stride=state_stride_src_updated_reached):
|
|
4008
4207
|
return self.env_ctx.set_max_stride(state_stride_src_updated_reached)
|
|
4009
4208
|
|
|
4010
4209
|
state_proto_code_file_abs_path_inited: str = self.eval_parent_state(EnvState.state_proto_code_file_abs_path_inited.name)
|
|
4011
4210
|
|
|
4012
|
-
state_proto_code_updated: bool = self.eval_parent_state(EnvState.state_proto_code_updated.name)
|
|
4013
|
-
|
|
4014
4211
|
state_local_venv_dir_abs_path_inited: str = self.eval_parent_state(EnvState.state_local_venv_dir_abs_path_inited.name)
|
|
4015
4212
|
|
|
4016
4213
|
venv_path_to_python: str = os.path.join(
|
|
@@ -4101,16 +4298,24 @@ class EnvState(enum.Enum):
|
|
|
4101
4298
|
|
|
4102
4299
|
state_default_stderr_log_handler_configured = Bootstrapper_state_default_stderr_log_handler_configured
|
|
4103
4300
|
|
|
4104
|
-
state_args_parsed =
|
|
4301
|
+
state_args_parsed = Factory_state_args_parsed
|
|
4105
4302
|
|
|
4106
4303
|
state_input_stderr_log_level_eval_finalized = Bootstrapper_state_input_stderr_log_level_eval_finalized
|
|
4107
4304
|
|
|
4305
|
+
state_input_stderr_log_level_handler_configured = Bootstrapper_state_input_stderr_log_level_handler_configured
|
|
4306
|
+
|
|
4108
4307
|
state_input_sub_command_arg_loaded = Bootstrapper_state_input_sub_command_arg_loaded
|
|
4109
4308
|
|
|
4110
|
-
state_input_final_state_eval_finalized =
|
|
4309
|
+
state_input_final_state_eval_finalized = Factory_state_input_final_state_eval_finalized
|
|
4310
|
+
|
|
4311
|
+
state_func_boot_env_executed = Bootstrapper_state_func_boot_env_executed
|
|
4312
|
+
|
|
4313
|
+
state_func_start_app_executed = Bootstrapper_state_func_start_app_executed
|
|
4314
|
+
|
|
4315
|
+
state_func_call_lib_executed = Bootstrapper_state_func_call_lib_executed
|
|
4111
4316
|
|
|
4112
4317
|
# Special case: triggers everything:
|
|
4113
|
-
|
|
4318
|
+
state_everything_executed = Factory_state_everything_executed
|
|
4114
4319
|
|
|
4115
4320
|
state_input_start_id_var_loaded = Bootstrapper_state_input_start_id_var_loaded
|
|
4116
4321
|
|
|
@@ -4135,7 +4340,7 @@ class EnvState(enum.Enum):
|
|
|
4135
4340
|
# `ConfLeap.leap_client`:
|
|
4136
4341
|
state_client_conf_file_data_loaded = Bootstrapper_state_client_conf_file_data_loaded
|
|
4137
4342
|
|
|
4138
|
-
state_selected_env_dir_rel_path_inited =
|
|
4343
|
+
state_selected_env_dir_rel_path_inited = Factory_state_selected_env_dir_rel_path_inited
|
|
4139
4344
|
|
|
4140
4345
|
state_local_conf_symlink_abs_path_inited = Bootstrapper_state_local_conf_symlink_abs_path_inited
|
|
4141
4346
|
|
|
@@ -4169,6 +4374,8 @@ class EnvState(enum.Enum):
|
|
|
4169
4374
|
|
|
4170
4375
|
state_install_specs_inited = Bootstrapper_state_install_specs_inited
|
|
4171
4376
|
|
|
4377
|
+
state_version_constraints_file_basename_inited = Bootstrapper_state_version_constraints_file_basename_inited
|
|
4378
|
+
|
|
4172
4379
|
# `ConfLeap.leap_derived`:
|
|
4173
4380
|
state_derived_conf_data_loaded = Bootstrapper_state_derived_conf_data_loaded
|
|
4174
4381
|
|
|
@@ -4209,11 +4416,8 @@ class TargetState(enum.Enum):
|
|
|
4209
4416
|
Special `EnvState`-s.
|
|
4210
4417
|
"""
|
|
4211
4418
|
|
|
4212
|
-
#
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
# A special state that triggers execution of the specific `SubCommand`:
|
|
4216
|
-
target_sub_command_executed = EnvState.state_sub_command_executed
|
|
4419
|
+
# A special state that triggers execution of everything else:
|
|
4420
|
+
target_everything_executed = EnvState.state_everything_executed
|
|
4217
4421
|
|
|
4218
4422
|
# FT_00_22_19_59.derived_config.md:
|
|
4219
4423
|
target_derived_config_loaded = EnvState.state_derived_conf_data_loaded
|
|
@@ -4329,14 +4533,13 @@ class MutableValue(Generic[ValueType]):
|
|
|
4329
4533
|
|
|
4330
4534
|
def set_curr_value(
|
|
4331
4535
|
self,
|
|
4332
|
-
state_node: StateNode
|
|
4536
|
+
state_node: StateNode,
|
|
4333
4537
|
curr_value: ValueType,
|
|
4334
4538
|
) -> None:
|
|
4335
4539
|
# TODO: Shell we also ensure that the `StateNode` using that `MutableValue` has necessary dependencies on write?
|
|
4336
4540
|
|
|
4337
4541
|
if self.curr_value is None:
|
|
4338
4542
|
raise AssertionError(f"`{MutableValue.__name__}` [{self.state_name}] cannot be set as it is not initialized yet.")
|
|
4339
|
-
state_name: str | None = None
|
|
4340
4543
|
self.curr_value = curr_value
|
|
4341
4544
|
logger.debug(f"`{self.__class__.__name__}` [{self.state_name}] `curr_value` after set [{self.curr_value}] in [{state_node.get_state_name()}]")
|
|
4342
4545
|
|
|
@@ -4614,40 +4817,53 @@ class _PrimerStderrLogFormatter(DefaultStderrLogFormatter):
|
|
|
4614
4817
|
}
|
|
4615
4818
|
|
|
4616
4819
|
|
|
4820
|
+
def _reconfigure_log_handler(
|
|
4821
|
+
formatter_class: type,
|
|
4822
|
+
new_formatter: logging.Formatter,
|
|
4823
|
+
log_level: int,
|
|
4824
|
+
) -> logging.Handler | None:
|
|
4825
|
+
for log_handler in logger.handlers:
|
|
4826
|
+
if isinstance(log_handler.formatter, formatter_class):
|
|
4827
|
+
# This covers both `_Primer*` (subclass) and `Default*` formatter variants.
|
|
4828
|
+
log_handler.setFormatter(new_formatter)
|
|
4829
|
+
log_handler.setLevel(log_level)
|
|
4830
|
+
# Remove `protoprimer`-specific filter if present:
|
|
4831
|
+
for handler_filter in list(log_handler.filters):
|
|
4832
|
+
if isinstance(handler_filter, StateStrideFilter):
|
|
4833
|
+
log_handler.removeFilter(handler_filter)
|
|
4834
|
+
return log_handler
|
|
4835
|
+
return None
|
|
4836
|
+
|
|
4837
|
+
|
|
4617
4838
|
def reconfigure_stderr_log_handler(log_level: int = logging.WARNING) -> logging.Handler | None:
|
|
4618
4839
|
"""
|
|
4619
4840
|
UC_81_50_97_17.reuse_logger.md
|
|
4620
4841
|
"""
|
|
4621
|
-
|
|
4622
4842
|
logger.setLevel(logging.NOTSET)
|
|
4843
|
+
return _reconfigure_log_handler(
|
|
4844
|
+
formatter_class=DefaultStderrLogFormatter,
|
|
4845
|
+
new_formatter=DefaultStderrLogFormatter(log_level),
|
|
4846
|
+
log_level=log_level,
|
|
4847
|
+
)
|
|
4623
4848
|
|
|
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
4849
|
|
|
4850
|
+
def _find_existing_log_handler(
|
|
4851
|
+
handler_class: type[logging.StreamHandler],
|
|
4852
|
+
formatter_class: type,
|
|
4853
|
+
) -> logging.StreamHandler | None:
|
|
4854
|
+
"""
|
|
4855
|
+
Prevent duplicate handler (when `os.execv*` calls restart `main` again in tests).
|
|
4856
|
+
"""
|
|
4857
|
+
if os.environ.get(EnvVar.var_PROTOPRIMER_MOCKED_RESTART.value, None) is None:
|
|
4858
|
+
return None
|
|
4859
|
+
log_handler: logging.Handler
|
|
4860
|
+
for log_handler in logger.handlers:
|
|
4861
|
+
if isinstance(log_handler, handler_class):
|
|
4862
|
+
if isinstance(log_handler.formatter, formatter_class):
|
|
4863
|
+
return log_handler
|
|
4639
4864
|
return None
|
|
4640
4865
|
|
|
4641
4866
|
|
|
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
4867
|
def _configure_primer_stderr_log_handler(state_input_stderr_log_level_var_loaded: int) -> logging.Handler:
|
|
4652
4868
|
"""
|
|
4653
4869
|
Implements for `stderr` log: FT_38_73_38_52.log_verbosity.md
|
|
@@ -4656,23 +4872,16 @@ def _configure_primer_stderr_log_handler(state_input_stderr_log_level_var_loaded
|
|
|
4656
4872
|
# Log everything (the filters are supposed to be set on output handlers instead):
|
|
4657
4873
|
logger.setLevel(logging.NOTSET)
|
|
4658
4874
|
|
|
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
|
|
4875
|
+
stderr_handler: logging.StreamHandler | None = _find_existing_log_handler(
|
|
4876
|
+
logging.StreamHandler,
|
|
4877
|
+
_PrimerStderrLogFormatter,
|
|
4878
|
+
)
|
|
4669
4879
|
|
|
4670
4880
|
if stderr_handler is None:
|
|
4671
|
-
stderr_handler
|
|
4672
|
-
|
|
4881
|
+
stderr_handler = logging.StreamHandler(sys.stderr)
|
|
4882
|
+
assert stderr_handler is not None
|
|
4673
4883
|
stderr_handler.addFilter(StateStrideFilter())
|
|
4674
4884
|
stderr_handler.setFormatter(_PrimerStderrLogFormatter(state_input_stderr_log_level_var_loaded))
|
|
4675
|
-
|
|
4676
4885
|
logger.addHandler(stderr_handler)
|
|
4677
4886
|
|
|
4678
4887
|
stderr_handler.setLevel(state_input_stderr_log_level_var_loaded)
|
|
@@ -4683,41 +4892,17 @@ def reconfigure_file_log_handler(log_level: int = logging.INFO) -> logging.Handl
|
|
|
4683
4892
|
"""
|
|
4684
4893
|
UC_81_50_97_17.reuse_logger.md
|
|
4685
4894
|
"""
|
|
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
|
|
4895
|
+
return _reconfigure_log_handler(
|
|
4896
|
+
formatter_class=DefaultFileLogFormatter,
|
|
4897
|
+
new_formatter=DefaultFileLogFormatter(),
|
|
4898
|
+
log_level=log_level,
|
|
4899
|
+
)
|
|
4715
4900
|
|
|
4716
4901
|
|
|
4717
4902
|
def _configure_primer_file_log_handler(
|
|
4718
4903
|
script_name: str,
|
|
4719
4904
|
state_input_start_id_var_loaded: str,
|
|
4720
|
-
|
|
4905
|
+
state_input_stderr_log_level_handler_configured: logging.Handler,
|
|
4721
4906
|
state_local_log_dir_abs_path_inited: str,
|
|
4722
4907
|
) -> logging.Handler:
|
|
4723
4908
|
"""
|
|
@@ -4733,33 +4918,37 @@ def _configure_primer_file_log_handler(
|
|
|
4733
4918
|
# TODO: Configure MAX file log level in the config file (NOTE: the higher the level the fewer the log entries):
|
|
4734
4919
|
file_log_level: int = logging.INFO
|
|
4735
4920
|
# Increase the log level at most to what is used by stderr:
|
|
4736
|
-
if
|
|
4737
|
-
file_log_level =
|
|
4921
|
+
if state_input_stderr_log_level_handler_configured.level < file_log_level:
|
|
4922
|
+
file_log_level = state_input_stderr_log_level_handler_configured.level
|
|
4738
4923
|
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4924
|
+
file_handler: logging.StreamHandler | None = _find_existing_log_handler(
|
|
4925
|
+
logging.FileHandler,
|
|
4926
|
+
_PrimerFileLogFormatter,
|
|
4742
4927
|
)
|
|
4743
4928
|
|
|
4744
|
-
if
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4929
|
+
if file_handler is None:
|
|
4930
|
+
os.makedirs(
|
|
4931
|
+
state_local_log_dir_abs_path_inited,
|
|
4932
|
+
exist_ok=True,
|
|
4933
|
+
)
|
|
4934
|
+
|
|
4935
|
+
if not os.path.exists(log_file_abs_path):
|
|
4936
|
+
# Explain missing logs to avoid confusion:
|
|
4937
|
+
write_text_file(
|
|
4938
|
+
log_file_abs_path,
|
|
4939
|
+
f"""
|
|
4749
4940
|
{ConfConstGeneral.log_section_delimiter} file log starts at [{StateStride.stride_py_arbitrary.name}] after its config is resolved {ConfConstGeneral.log_section_delimiter}
|
|
4750
4941
|
|
|
4751
4942
|
""",
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
file_handler: logging.Handler = logging.FileHandler(log_file_abs_path)
|
|
4755
|
-
file_handler.addFilter(StateStrideFilter())
|
|
4943
|
+
)
|
|
4756
4944
|
|
|
4757
|
-
|
|
4945
|
+
file_handler = logging.FileHandler(log_file_abs_path)
|
|
4946
|
+
assert file_handler is not None
|
|
4947
|
+
file_handler.addFilter(StateStrideFilter())
|
|
4948
|
+
file_handler.setFormatter(_PrimerFileLogFormatter())
|
|
4949
|
+
logger.addHandler(file_handler)
|
|
4758
4950
|
|
|
4759
4951
|
file_handler.setLevel(file_log_level)
|
|
4760
|
-
file_handler.setFormatter(file_formatter)
|
|
4761
|
-
|
|
4762
|
-
logger.addHandler(file_handler)
|
|
4763
4952
|
return file_handler
|
|
4764
4953
|
|
|
4765
4954
|
|
|
@@ -5197,7 +5386,7 @@ def select_python_file_abs_path(
|
|
|
5197
5386
|
try:
|
|
5198
5387
|
logger.debug(f"trying `python` version of `selected_python_abs_path` [{selected_python_abs_path}]")
|
|
5199
5388
|
python_version: tuple[int, int, int] = get_python_version(selected_python_abs_path)
|
|
5200
|
-
logger.
|
|
5389
|
+
logger.debug(f"`python` version of `selected_python_abs_path` [{selected_python_abs_path}] is [{python_version}]")
|
|
5201
5390
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
5202
5391
|
logger.warning(f"`python` in `selected_python_abs_path` [{selected_python_abs_path}] failed without returning its version")
|
|
5203
5392
|
selected_python_abs_path = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: protoprimer
|
|
3
|
-
Version: 0.12.0.
|
|
3
|
+
Version: 0.12.0.dev2
|
|
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.0.dev2}/main/protoprimer.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|