Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- lib/python3.12/site-packages/omegaconf/__init__.py +65 -0
- lib/python3.12/site-packages/omegaconf/_impl.py +101 -0
- lib/python3.12/site-packages/omegaconf/_utils.py +1039 -0
- lib/python3.12/site-packages/omegaconf/base.py +962 -0
- lib/python3.12/site-packages/omegaconf/basecontainer.py +916 -0
- lib/python3.12/site-packages/omegaconf/dictconfig.py +776 -0
- lib/python3.12/site-packages/omegaconf/errors.py +141 -0
- lib/python3.12/site-packages/omegaconf/grammar/__init__.py +0 -0
- lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarLexer.py +337 -0
- lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParser.py +1595 -0
- lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParserListener.py +156 -0
- lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParserVisitor.py +93 -0
- lib/python3.12/site-packages/omegaconf/grammar/gen/__init__.py +0 -0
- lib/python3.12/site-packages/omegaconf/grammar_parser.py +144 -0
- lib/python3.12/site-packages/omegaconf/grammar_visitor.py +392 -0
- lib/python3.12/site-packages/omegaconf/listconfig.py +679 -0
- lib/python3.12/site-packages/omegaconf/nodes.py +545 -0
- lib/python3.12/site-packages/omegaconf/omegaconf.py +1157 -0
- lib/python3.12/site-packages/omegaconf/py.typed +0 -0
- lib/python3.12/site-packages/omegaconf/version.py +13 -0
- lib/python3.12/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/batch.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/completion.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_label_model_grader.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_string_check_grader.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_string_check_grader_param.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_text_similarity_grader.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_text_similarity_grader_param.cpython-312.pyc +0 -0
- lib/python3.12/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc +0 -0
lib/python3.12/site-packages/omegaconf/__init__.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .base import Container, DictKeyType, Node, SCMode, UnionNode
|
| 2 |
+
from .dictconfig import DictConfig
|
| 3 |
+
from .errors import (
|
| 4 |
+
KeyValidationError,
|
| 5 |
+
MissingMandatoryValue,
|
| 6 |
+
ReadonlyConfigError,
|
| 7 |
+
UnsupportedValueType,
|
| 8 |
+
ValidationError,
|
| 9 |
+
)
|
| 10 |
+
from .listconfig import ListConfig
|
| 11 |
+
from .nodes import (
|
| 12 |
+
AnyNode,
|
| 13 |
+
BooleanNode,
|
| 14 |
+
BytesNode,
|
| 15 |
+
EnumNode,
|
| 16 |
+
FloatNode,
|
| 17 |
+
IntegerNode,
|
| 18 |
+
PathNode,
|
| 19 |
+
StringNode,
|
| 20 |
+
ValueNode,
|
| 21 |
+
)
|
| 22 |
+
from .omegaconf import (
|
| 23 |
+
II,
|
| 24 |
+
MISSING,
|
| 25 |
+
SI,
|
| 26 |
+
OmegaConf,
|
| 27 |
+
Resolver,
|
| 28 |
+
flag_override,
|
| 29 |
+
open_dict,
|
| 30 |
+
read_write,
|
| 31 |
+
)
|
| 32 |
+
from .version import __version__
|
| 33 |
+
|
| 34 |
+
__all__ = [
|
| 35 |
+
"__version__",
|
| 36 |
+
"MissingMandatoryValue",
|
| 37 |
+
"ValidationError",
|
| 38 |
+
"ReadonlyConfigError",
|
| 39 |
+
"UnsupportedValueType",
|
| 40 |
+
"KeyValidationError",
|
| 41 |
+
"Container",
|
| 42 |
+
"UnionNode",
|
| 43 |
+
"ListConfig",
|
| 44 |
+
"DictConfig",
|
| 45 |
+
"DictKeyType",
|
| 46 |
+
"OmegaConf",
|
| 47 |
+
"Resolver",
|
| 48 |
+
"SCMode",
|
| 49 |
+
"flag_override",
|
| 50 |
+
"read_write",
|
| 51 |
+
"open_dict",
|
| 52 |
+
"Node",
|
| 53 |
+
"ValueNode",
|
| 54 |
+
"AnyNode",
|
| 55 |
+
"IntegerNode",
|
| 56 |
+
"StringNode",
|
| 57 |
+
"BytesNode",
|
| 58 |
+
"PathNode",
|
| 59 |
+
"BooleanNode",
|
| 60 |
+
"EnumNode",
|
| 61 |
+
"FloatNode",
|
| 62 |
+
"MISSING",
|
| 63 |
+
"SI",
|
| 64 |
+
"II",
|
| 65 |
+
]
|
lib/python3.12/site-packages/omegaconf/_impl.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any
|
| 2 |
+
|
| 3 |
+
from omegaconf import MISSING, Container, DictConfig, ListConfig, Node, ValueNode
|
| 4 |
+
from omegaconf.errors import ConfigTypeError, InterpolationToMissingValueError
|
| 5 |
+
|
| 6 |
+
from ._utils import _DEFAULT_MARKER_, _get_value
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def _resolve_container_value(cfg: Container, key: Any) -> None:
|
| 10 |
+
node = cfg._get_child(key)
|
| 11 |
+
assert isinstance(node, Node)
|
| 12 |
+
if node._is_interpolation():
|
| 13 |
+
try:
|
| 14 |
+
resolved = node._dereference_node()
|
| 15 |
+
except InterpolationToMissingValueError:
|
| 16 |
+
node._set_value(MISSING)
|
| 17 |
+
else:
|
| 18 |
+
if isinstance(resolved, Container):
|
| 19 |
+
_resolve(resolved)
|
| 20 |
+
if isinstance(resolved, Container) and isinstance(node, ValueNode):
|
| 21 |
+
cfg[key] = resolved
|
| 22 |
+
else:
|
| 23 |
+
node._set_value(_get_value(resolved))
|
| 24 |
+
else:
|
| 25 |
+
_resolve(node)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def _resolve(cfg: Node) -> Node:
|
| 29 |
+
assert isinstance(cfg, Node)
|
| 30 |
+
if cfg._is_interpolation():
|
| 31 |
+
try:
|
| 32 |
+
resolved = cfg._dereference_node()
|
| 33 |
+
except InterpolationToMissingValueError:
|
| 34 |
+
cfg._set_value(MISSING)
|
| 35 |
+
else:
|
| 36 |
+
cfg._set_value(resolved._value())
|
| 37 |
+
|
| 38 |
+
if isinstance(cfg, DictConfig):
|
| 39 |
+
for k in cfg.keys():
|
| 40 |
+
_resolve_container_value(cfg, k)
|
| 41 |
+
|
| 42 |
+
elif isinstance(cfg, ListConfig):
|
| 43 |
+
for i in range(len(cfg)):
|
| 44 |
+
_resolve_container_value(cfg, i)
|
| 45 |
+
|
| 46 |
+
return cfg
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def select_value(
|
| 50 |
+
cfg: Container,
|
| 51 |
+
key: str,
|
| 52 |
+
*,
|
| 53 |
+
default: Any = _DEFAULT_MARKER_,
|
| 54 |
+
throw_on_resolution_failure: bool = True,
|
| 55 |
+
throw_on_missing: bool = False,
|
| 56 |
+
absolute_key: bool = False,
|
| 57 |
+
) -> Any:
|
| 58 |
+
node = select_node(
|
| 59 |
+
cfg=cfg,
|
| 60 |
+
key=key,
|
| 61 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 62 |
+
throw_on_missing=throw_on_missing,
|
| 63 |
+
absolute_key=absolute_key,
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
node_not_found = node is None
|
| 67 |
+
if node_not_found or node._is_missing():
|
| 68 |
+
if default is not _DEFAULT_MARKER_:
|
| 69 |
+
return default
|
| 70 |
+
else:
|
| 71 |
+
return None
|
| 72 |
+
|
| 73 |
+
return _get_value(node)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def select_node(
|
| 77 |
+
cfg: Container,
|
| 78 |
+
key: str,
|
| 79 |
+
*,
|
| 80 |
+
throw_on_resolution_failure: bool = True,
|
| 81 |
+
throw_on_missing: bool = False,
|
| 82 |
+
absolute_key: bool = False,
|
| 83 |
+
) -> Any:
|
| 84 |
+
try:
|
| 85 |
+
# for non relative keys, the interpretation can be:
|
| 86 |
+
# 1. relative to cfg
|
| 87 |
+
# 2. relative to the config root
|
| 88 |
+
# This is controlled by the absolute_key flag. By default, such keys are relative to cfg.
|
| 89 |
+
if not absolute_key and not key.startswith("."):
|
| 90 |
+
key = f".{key}"
|
| 91 |
+
|
| 92 |
+
cfg, key = cfg._resolve_key_and_root(key)
|
| 93 |
+
_root, _last_key, node = cfg._select_impl(
|
| 94 |
+
key,
|
| 95 |
+
throw_on_missing=throw_on_missing,
|
| 96 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 97 |
+
)
|
| 98 |
+
except ConfigTypeError:
|
| 99 |
+
return None
|
| 100 |
+
|
| 101 |
+
return node
|
lib/python3.12/site-packages/omegaconf/_utils.py
ADDED
|
@@ -0,0 +1,1039 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import os
|
| 3 |
+
import pathlib
|
| 4 |
+
import re
|
| 5 |
+
import string
|
| 6 |
+
import sys
|
| 7 |
+
import types
|
| 8 |
+
import warnings
|
| 9 |
+
from contextlib import contextmanager
|
| 10 |
+
from enum import Enum
|
| 11 |
+
from textwrap import dedent
|
| 12 |
+
from typing import (
|
| 13 |
+
Any,
|
| 14 |
+
Dict,
|
| 15 |
+
Iterator,
|
| 16 |
+
List,
|
| 17 |
+
Optional,
|
| 18 |
+
Tuple,
|
| 19 |
+
Type,
|
| 20 |
+
Union,
|
| 21 |
+
get_type_hints,
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
import yaml
|
| 25 |
+
|
| 26 |
+
from .errors import (
|
| 27 |
+
ConfigIndexError,
|
| 28 |
+
ConfigTypeError,
|
| 29 |
+
ConfigValueError,
|
| 30 |
+
GrammarParseError,
|
| 31 |
+
OmegaConfBaseException,
|
| 32 |
+
ValidationError,
|
| 33 |
+
)
|
| 34 |
+
from .grammar_parser import SIMPLE_INTERPOLATION_PATTERN, parse
|
| 35 |
+
|
| 36 |
+
try:
|
| 37 |
+
import dataclasses
|
| 38 |
+
|
| 39 |
+
except ImportError: # pragma: no cover
|
| 40 |
+
dataclasses = None # type: ignore # pragma: no cover
|
| 41 |
+
|
| 42 |
+
try:
|
| 43 |
+
import attr
|
| 44 |
+
|
| 45 |
+
except ImportError: # pragma: no cover
|
| 46 |
+
attr = None # type: ignore # pragma: no cover
|
| 47 |
+
|
| 48 |
+
NoneType: Type[None] = type(None)
|
| 49 |
+
|
| 50 |
+
BUILTIN_VALUE_TYPES: Tuple[Type[Any], ...] = (
|
| 51 |
+
int,
|
| 52 |
+
float,
|
| 53 |
+
bool,
|
| 54 |
+
str,
|
| 55 |
+
bytes,
|
| 56 |
+
NoneType,
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
# Regexprs to match key paths like: a.b, a[b], ..a[c].d, etc.
|
| 60 |
+
# We begin by matching the head (in these examples: a, a, ..a).
|
| 61 |
+
# This can be read as "dots followed by any character but `.` or `[`"
|
| 62 |
+
# Note that a key starting with brackets, like [a], is purposedly *not*
|
| 63 |
+
# matched here and will instead be handled in the next regex below (this
|
| 64 |
+
# is to keep this regex simple).
|
| 65 |
+
KEY_PATH_HEAD = re.compile(r"(\.)*[^.[]*")
|
| 66 |
+
# Then we match other keys. The following expression matches one key and can
|
| 67 |
+
# be read as a choice between two syntaxes:
|
| 68 |
+
# - `.` followed by anything except `.` or `[` (ex: .b, .d)
|
| 69 |
+
# - `[` followed by anything then `]` (ex: [b], [c])
|
| 70 |
+
KEY_PATH_OTHER = re.compile(r"\.([^.[]*)|\[(.*?)\]")
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
# source: https://yaml.org/type/bool.html
|
| 74 |
+
YAML_BOOL_TYPES = [
|
| 75 |
+
"y",
|
| 76 |
+
"Y",
|
| 77 |
+
"yes",
|
| 78 |
+
"Yes",
|
| 79 |
+
"YES",
|
| 80 |
+
"n",
|
| 81 |
+
"N",
|
| 82 |
+
"no",
|
| 83 |
+
"No",
|
| 84 |
+
"NO",
|
| 85 |
+
"true",
|
| 86 |
+
"True",
|
| 87 |
+
"TRUE",
|
| 88 |
+
"false",
|
| 89 |
+
"False",
|
| 90 |
+
"FALSE",
|
| 91 |
+
"on",
|
| 92 |
+
"On",
|
| 93 |
+
"ON",
|
| 94 |
+
"off",
|
| 95 |
+
"Off",
|
| 96 |
+
"OFF",
|
| 97 |
+
]
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class Marker:
|
| 101 |
+
def __init__(self, desc: str):
|
| 102 |
+
self.desc = desc
|
| 103 |
+
|
| 104 |
+
def __repr__(self) -> str:
|
| 105 |
+
return self.desc
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
# To be used as default value when `None` is not an option.
|
| 109 |
+
_DEFAULT_MARKER_: Any = Marker("_DEFAULT_MARKER_")
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
class OmegaConfDumper(yaml.Dumper): # type: ignore
|
| 113 |
+
str_representer_added = False
|
| 114 |
+
|
| 115 |
+
@staticmethod
|
| 116 |
+
def str_representer(dumper: yaml.Dumper, data: str) -> yaml.ScalarNode:
|
| 117 |
+
with_quotes = yaml_is_bool(data) or is_int(data) or is_float(data)
|
| 118 |
+
return dumper.represent_scalar(
|
| 119 |
+
yaml.resolver.BaseResolver.DEFAULT_SCALAR_TAG,
|
| 120 |
+
data,
|
| 121 |
+
style=("'" if with_quotes else None),
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def get_omega_conf_dumper() -> Type[OmegaConfDumper]:
|
| 126 |
+
if not OmegaConfDumper.str_representer_added:
|
| 127 |
+
OmegaConfDumper.add_representer(str, OmegaConfDumper.str_representer)
|
| 128 |
+
OmegaConfDumper.str_representer_added = True
|
| 129 |
+
return OmegaConfDumper
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def yaml_is_bool(b: str) -> bool:
|
| 133 |
+
return b in YAML_BOOL_TYPES
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def get_yaml_loader() -> Any:
|
| 137 |
+
class OmegaConfLoader(yaml.SafeLoader): # type: ignore
|
| 138 |
+
def construct_mapping(self, node: yaml.Node, deep: bool = False) -> Any:
|
| 139 |
+
keys = set()
|
| 140 |
+
for key_node, value_node in node.value:
|
| 141 |
+
if key_node.tag != yaml.resolver.BaseResolver.DEFAULT_SCALAR_TAG:
|
| 142 |
+
continue
|
| 143 |
+
if key_node.value in keys:
|
| 144 |
+
raise yaml.constructor.ConstructorError(
|
| 145 |
+
"while constructing a mapping",
|
| 146 |
+
node.start_mark,
|
| 147 |
+
f"found duplicate key {key_node.value}",
|
| 148 |
+
key_node.start_mark,
|
| 149 |
+
)
|
| 150 |
+
keys.add(key_node.value)
|
| 151 |
+
return super().construct_mapping(node, deep=deep)
|
| 152 |
+
|
| 153 |
+
loader = OmegaConfLoader
|
| 154 |
+
loader.add_implicit_resolver(
|
| 155 |
+
"tag:yaml.org,2002:float",
|
| 156 |
+
re.compile(
|
| 157 |
+
"""^(?:
|
| 158 |
+
[-+]?[0-9]+(?:_[0-9]+)*\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
|
| 159 |
+
|[-+]?[0-9]+(?:_[0-9]+)*(?:[eE][-+]?[0-9]+)
|
| 160 |
+
|\\.[0-9]+(?:_[0-9]+)*(?:[eE][-+][0-9]+)?
|
| 161 |
+
|[-+]?[0-9]+(?:_[0-9]+)*(?::[0-5]?[0-9])+\\.[0-9_]*
|
| 162 |
+
|[-+]?\\.(?:inf|Inf|INF)
|
| 163 |
+
|\\.(?:nan|NaN|NAN))$""",
|
| 164 |
+
re.X,
|
| 165 |
+
),
|
| 166 |
+
list("-+0123456789."),
|
| 167 |
+
)
|
| 168 |
+
loader.yaml_implicit_resolvers = {
|
| 169 |
+
key: [
|
| 170 |
+
(tag, regexp)
|
| 171 |
+
for tag, regexp in resolvers
|
| 172 |
+
if tag != "tag:yaml.org,2002:timestamp"
|
| 173 |
+
]
|
| 174 |
+
for key, resolvers in loader.yaml_implicit_resolvers.items()
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
loader.add_constructor(
|
| 178 |
+
"tag:yaml.org,2002:python/object/apply:pathlib.Path",
|
| 179 |
+
lambda loader, node: pathlib.Path(*loader.construct_sequence(node)),
|
| 180 |
+
)
|
| 181 |
+
loader.add_constructor(
|
| 182 |
+
"tag:yaml.org,2002:python/object/apply:pathlib.PosixPath",
|
| 183 |
+
lambda loader, node: pathlib.PosixPath(*loader.construct_sequence(node)),
|
| 184 |
+
)
|
| 185 |
+
loader.add_constructor(
|
| 186 |
+
"tag:yaml.org,2002:python/object/apply:pathlib.WindowsPath",
|
| 187 |
+
lambda loader, node: pathlib.WindowsPath(*loader.construct_sequence(node)),
|
| 188 |
+
)
|
| 189 |
+
|
| 190 |
+
return loader
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
def _get_class(path: str) -> type:
|
| 194 |
+
from importlib import import_module
|
| 195 |
+
|
| 196 |
+
module_path, _, class_name = path.rpartition(".")
|
| 197 |
+
mod = import_module(module_path)
|
| 198 |
+
try:
|
| 199 |
+
klass: type = getattr(mod, class_name)
|
| 200 |
+
except AttributeError:
|
| 201 |
+
raise ImportError(f"Class {class_name} is not in module {module_path}")
|
| 202 |
+
return klass
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def is_union_annotation(type_: Any) -> bool:
|
| 206 |
+
if sys.version_info >= (3, 10): # pragma: no cover
|
| 207 |
+
if isinstance(type_, types.UnionType):
|
| 208 |
+
return True
|
| 209 |
+
return getattr(type_, "__origin__", None) is Union
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
def _resolve_optional(type_: Any) -> Tuple[bool, Any]:
|
| 213 |
+
"""Check whether `type_` is equivalent to `typing.Optional[T]` for some T."""
|
| 214 |
+
if is_union_annotation(type_):
|
| 215 |
+
args = type_.__args__
|
| 216 |
+
if NoneType in args:
|
| 217 |
+
optional = True
|
| 218 |
+
args = tuple(a for a in args if a is not NoneType)
|
| 219 |
+
else:
|
| 220 |
+
optional = False
|
| 221 |
+
if len(args) == 1:
|
| 222 |
+
return optional, args[0]
|
| 223 |
+
elif len(args) >= 2:
|
| 224 |
+
return optional, Union[args]
|
| 225 |
+
else:
|
| 226 |
+
assert False
|
| 227 |
+
|
| 228 |
+
if type_ is Any:
|
| 229 |
+
return True, Any
|
| 230 |
+
|
| 231 |
+
if type_ in (None, NoneType):
|
| 232 |
+
return True, NoneType
|
| 233 |
+
|
| 234 |
+
return False, type_
|
| 235 |
+
|
| 236 |
+
|
| 237 |
+
def _is_optional(obj: Any, key: Optional[Union[int, str]] = None) -> bool:
|
| 238 |
+
"""Check `obj` metadata to see if the given node is optional."""
|
| 239 |
+
from .base import Container, Node
|
| 240 |
+
|
| 241 |
+
if key is not None:
|
| 242 |
+
assert isinstance(obj, Container)
|
| 243 |
+
obj = obj._get_node(key)
|
| 244 |
+
assert isinstance(obj, Node)
|
| 245 |
+
return obj._is_optional()
|
| 246 |
+
|
| 247 |
+
|
| 248 |
+
def _resolve_forward(type_: Type[Any], module: str) -> Type[Any]:
|
| 249 |
+
import typing # lgtm [py/import-and-import-from]
|
| 250 |
+
|
| 251 |
+
forward = typing.ForwardRef if hasattr(typing, "ForwardRef") else typing._ForwardRef # type: ignore
|
| 252 |
+
if type(type_) is forward:
|
| 253 |
+
return _get_class(f"{module}.{type_.__forward_arg__}")
|
| 254 |
+
else:
|
| 255 |
+
if is_dict_annotation(type_):
|
| 256 |
+
kt, vt = get_dict_key_value_types(type_)
|
| 257 |
+
if kt is not None:
|
| 258 |
+
kt = _resolve_forward(kt, module=module)
|
| 259 |
+
if vt is not None:
|
| 260 |
+
vt = _resolve_forward(vt, module=module)
|
| 261 |
+
return Dict[kt, vt] # type: ignore
|
| 262 |
+
if is_list_annotation(type_):
|
| 263 |
+
et = get_list_element_type(type_)
|
| 264 |
+
if et is not None:
|
| 265 |
+
et = _resolve_forward(et, module=module)
|
| 266 |
+
return List[et] # type: ignore
|
| 267 |
+
if is_tuple_annotation(type_):
|
| 268 |
+
its = get_tuple_item_types(type_)
|
| 269 |
+
its = tuple(_resolve_forward(it, module=module) for it in its)
|
| 270 |
+
return Tuple[its] # type: ignore
|
| 271 |
+
|
| 272 |
+
return type_
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
def extract_dict_subclass_data(obj: Any, parent: Any) -> Optional[Dict[str, Any]]:
|
| 276 |
+
"""Check if obj is an instance of a subclass of Dict. If so, extract the Dict keys/values."""
|
| 277 |
+
from omegaconf.omegaconf import _maybe_wrap
|
| 278 |
+
|
| 279 |
+
is_type = isinstance(obj, type)
|
| 280 |
+
obj_type = obj if is_type else type(obj)
|
| 281 |
+
subclasses_dict = is_dict_subclass(obj_type)
|
| 282 |
+
|
| 283 |
+
if subclasses_dict:
|
| 284 |
+
warnings.warn(
|
| 285 |
+
f"Class `{obj_type.__name__}` subclasses `Dict`."
|
| 286 |
+
+ " Subclassing `Dict` in Structured Config classes is deprecated,"
|
| 287 |
+
+ " see github.com/omry/omegaconf/issues/663",
|
| 288 |
+
UserWarning,
|
| 289 |
+
stacklevel=9,
|
| 290 |
+
)
|
| 291 |
+
|
| 292 |
+
if is_type:
|
| 293 |
+
return None
|
| 294 |
+
elif subclasses_dict:
|
| 295 |
+
dict_subclass_data = {}
|
| 296 |
+
key_type, element_type = get_dict_key_value_types(obj_type)
|
| 297 |
+
for name, value in obj.items():
|
| 298 |
+
is_optional, type_ = _resolve_optional(element_type)
|
| 299 |
+
type_ = _resolve_forward(type_, obj.__module__)
|
| 300 |
+
try:
|
| 301 |
+
dict_subclass_data[name] = _maybe_wrap(
|
| 302 |
+
ref_type=type_,
|
| 303 |
+
is_optional=is_optional,
|
| 304 |
+
key=name,
|
| 305 |
+
value=value,
|
| 306 |
+
parent=parent,
|
| 307 |
+
)
|
| 308 |
+
except ValidationError as ex:
|
| 309 |
+
format_and_raise(
|
| 310 |
+
node=None, key=name, value=value, cause=ex, msg=str(ex)
|
| 311 |
+
)
|
| 312 |
+
return dict_subclass_data
|
| 313 |
+
else:
|
| 314 |
+
return None
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
def get_attr_class_fields(obj: Any) -> List["attr.Attribute[Any]"]:
|
| 318 |
+
is_type = isinstance(obj, type)
|
| 319 |
+
obj_type = obj if is_type else type(obj)
|
| 320 |
+
fields = attr.fields_dict(obj_type).values()
|
| 321 |
+
return [f for f in fields if f.metadata.get("omegaconf_ignore") is not True]
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
def get_attr_data(obj: Any, allow_objects: Optional[bool] = None) -> Dict[str, Any]:
|
| 325 |
+
from omegaconf.omegaconf import OmegaConf, _maybe_wrap
|
| 326 |
+
|
| 327 |
+
flags = {"allow_objects": allow_objects} if allow_objects is not None else {}
|
| 328 |
+
|
| 329 |
+
from omegaconf import MISSING
|
| 330 |
+
|
| 331 |
+
d = {}
|
| 332 |
+
is_type = isinstance(obj, type)
|
| 333 |
+
obj_type = obj if is_type else type(obj)
|
| 334 |
+
dummy_parent = OmegaConf.create({}, flags=flags)
|
| 335 |
+
dummy_parent._metadata.object_type = obj_type
|
| 336 |
+
resolved_hints = get_type_hints(obj_type)
|
| 337 |
+
|
| 338 |
+
for attrib in get_attr_class_fields(obj):
|
| 339 |
+
name = attrib.name
|
| 340 |
+
is_optional, type_ = _resolve_optional(resolved_hints[name])
|
| 341 |
+
type_ = _resolve_forward(type_, obj.__module__)
|
| 342 |
+
if not is_type:
|
| 343 |
+
value = getattr(obj, name)
|
| 344 |
+
else:
|
| 345 |
+
value = attrib.default
|
| 346 |
+
if value == attr.NOTHING:
|
| 347 |
+
value = MISSING
|
| 348 |
+
if is_union_annotation(type_) and not is_supported_union_annotation(type_):
|
| 349 |
+
e = ConfigValueError(
|
| 350 |
+
f"Unions of containers are not supported:\n{name}: {type_str(type_)}"
|
| 351 |
+
)
|
| 352 |
+
format_and_raise(node=None, key=None, value=value, cause=e, msg=str(e))
|
| 353 |
+
|
| 354 |
+
try:
|
| 355 |
+
d[name] = _maybe_wrap(
|
| 356 |
+
ref_type=type_,
|
| 357 |
+
is_optional=is_optional,
|
| 358 |
+
key=name,
|
| 359 |
+
value=value,
|
| 360 |
+
parent=dummy_parent,
|
| 361 |
+
)
|
| 362 |
+
except (ValidationError, GrammarParseError) as ex:
|
| 363 |
+
format_and_raise(
|
| 364 |
+
node=dummy_parent, key=name, value=value, cause=ex, msg=str(ex)
|
| 365 |
+
)
|
| 366 |
+
d[name]._set_parent(None)
|
| 367 |
+
dict_subclass_data = extract_dict_subclass_data(obj=obj, parent=dummy_parent)
|
| 368 |
+
if dict_subclass_data is not None:
|
| 369 |
+
d.update(dict_subclass_data)
|
| 370 |
+
return d
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def get_dataclass_fields(obj: Any) -> List["dataclasses.Field[Any]"]:
|
| 374 |
+
fields = dataclasses.fields(obj)
|
| 375 |
+
return [f for f in fields if f.metadata.get("omegaconf_ignore") is not True]
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
def get_dataclass_data(
|
| 379 |
+
obj: Any, allow_objects: Optional[bool] = None
|
| 380 |
+
) -> Dict[str, Any]:
|
| 381 |
+
from omegaconf.omegaconf import MISSING, OmegaConf, _maybe_wrap
|
| 382 |
+
|
| 383 |
+
flags = {"allow_objects": allow_objects} if allow_objects is not None else {}
|
| 384 |
+
d = {}
|
| 385 |
+
is_type = isinstance(obj, type)
|
| 386 |
+
obj_type = get_type_of(obj)
|
| 387 |
+
dummy_parent = OmegaConf.create({}, flags=flags)
|
| 388 |
+
dummy_parent._metadata.object_type = obj_type
|
| 389 |
+
resolved_hints = get_type_hints(obj_type)
|
| 390 |
+
for field in get_dataclass_fields(obj):
|
| 391 |
+
name = field.name
|
| 392 |
+
is_optional, type_ = _resolve_optional(resolved_hints[field.name])
|
| 393 |
+
type_ = _resolve_forward(type_, obj.__module__)
|
| 394 |
+
has_default = field.default != dataclasses.MISSING
|
| 395 |
+
has_default_factory = field.default_factory != dataclasses.MISSING
|
| 396 |
+
|
| 397 |
+
if not is_type:
|
| 398 |
+
value = getattr(obj, name)
|
| 399 |
+
else:
|
| 400 |
+
if has_default:
|
| 401 |
+
value = field.default
|
| 402 |
+
elif has_default_factory:
|
| 403 |
+
value = field.default_factory() # type: ignore
|
| 404 |
+
else:
|
| 405 |
+
value = MISSING
|
| 406 |
+
|
| 407 |
+
if is_union_annotation(type_) and not is_supported_union_annotation(type_):
|
| 408 |
+
e = ConfigValueError(
|
| 409 |
+
f"Unions of containers are not supported:\n{name}: {type_str(type_)}"
|
| 410 |
+
)
|
| 411 |
+
format_and_raise(node=None, key=None, value=value, cause=e, msg=str(e))
|
| 412 |
+
try:
|
| 413 |
+
d[name] = _maybe_wrap(
|
| 414 |
+
ref_type=type_,
|
| 415 |
+
is_optional=is_optional,
|
| 416 |
+
key=name,
|
| 417 |
+
value=value,
|
| 418 |
+
parent=dummy_parent,
|
| 419 |
+
)
|
| 420 |
+
except (ValidationError, GrammarParseError) as ex:
|
| 421 |
+
format_and_raise(
|
| 422 |
+
node=dummy_parent, key=name, value=value, cause=ex, msg=str(ex)
|
| 423 |
+
)
|
| 424 |
+
d[name]._set_parent(None)
|
| 425 |
+
dict_subclass_data = extract_dict_subclass_data(obj=obj, parent=dummy_parent)
|
| 426 |
+
if dict_subclass_data is not None:
|
| 427 |
+
d.update(dict_subclass_data)
|
| 428 |
+
return d
|
| 429 |
+
|
| 430 |
+
|
| 431 |
+
def is_dataclass(obj: Any) -> bool:
|
| 432 |
+
from omegaconf.base import Node
|
| 433 |
+
|
| 434 |
+
if dataclasses is None or isinstance(obj, Node):
|
| 435 |
+
return False
|
| 436 |
+
return dataclasses.is_dataclass(obj)
|
| 437 |
+
|
| 438 |
+
|
| 439 |
+
def is_attr_class(obj: Any) -> bool:
|
| 440 |
+
from omegaconf.base import Node
|
| 441 |
+
|
| 442 |
+
if attr is None or isinstance(obj, Node):
|
| 443 |
+
return False
|
| 444 |
+
return attr.has(obj)
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
def is_structured_config(obj: Any) -> bool:
|
| 448 |
+
return is_attr_class(obj) or is_dataclass(obj)
|
| 449 |
+
|
| 450 |
+
|
| 451 |
+
def is_dataclass_frozen(type_: Any) -> bool:
|
| 452 |
+
return type_.__dataclass_params__.frozen # type: ignore
|
| 453 |
+
|
| 454 |
+
|
| 455 |
+
def is_attr_frozen(type_: type) -> bool:
|
| 456 |
+
# This is very hacky and probably fragile as well.
|
| 457 |
+
# Unfortunately currently there isn't an official API in attr that can detect that.
|
| 458 |
+
# noinspection PyProtectedMember
|
| 459 |
+
return type_.__setattr__ == attr._make._frozen_setattrs # type: ignore
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
def get_type_of(class_or_object: Any) -> Type[Any]:
|
| 463 |
+
type_ = class_or_object
|
| 464 |
+
if not isinstance(type_, type):
|
| 465 |
+
type_ = type(class_or_object)
|
| 466 |
+
assert isinstance(type_, type)
|
| 467 |
+
return type_
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
def is_structured_config_frozen(obj: Any) -> bool:
|
| 471 |
+
type_ = get_type_of(obj)
|
| 472 |
+
|
| 473 |
+
if is_dataclass(type_):
|
| 474 |
+
return is_dataclass_frozen(type_)
|
| 475 |
+
if is_attr_class(type_):
|
| 476 |
+
return is_attr_frozen(type_)
|
| 477 |
+
return False
|
| 478 |
+
|
| 479 |
+
|
| 480 |
+
def get_structured_config_init_field_names(obj: Any) -> List[str]:
|
| 481 |
+
fields: Union[List["dataclasses.Field[Any]"], List["attr.Attribute[Any]"]]
|
| 482 |
+
if is_dataclass(obj):
|
| 483 |
+
fields = get_dataclass_fields(obj)
|
| 484 |
+
elif is_attr_class(obj):
|
| 485 |
+
fields = get_attr_class_fields(obj)
|
| 486 |
+
else:
|
| 487 |
+
raise ValueError(f"Unsupported type: {type(obj).__name__}")
|
| 488 |
+
return [f.name for f in fields if f.init]
|
| 489 |
+
|
| 490 |
+
|
| 491 |
+
def get_structured_config_data(
|
| 492 |
+
obj: Any, allow_objects: Optional[bool] = None
|
| 493 |
+
) -> Dict[str, Any]:
|
| 494 |
+
if is_dataclass(obj):
|
| 495 |
+
return get_dataclass_data(obj, allow_objects=allow_objects)
|
| 496 |
+
elif is_attr_class(obj):
|
| 497 |
+
return get_attr_data(obj, allow_objects=allow_objects)
|
| 498 |
+
else:
|
| 499 |
+
raise ValueError(f"Unsupported type: {type(obj).__name__}")
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
class ValueKind(Enum):
|
| 503 |
+
VALUE = 0
|
| 504 |
+
MANDATORY_MISSING = 1
|
| 505 |
+
INTERPOLATION = 2
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
def _is_missing_value(value: Any) -> bool:
|
| 509 |
+
from omegaconf import Node
|
| 510 |
+
|
| 511 |
+
if isinstance(value, Node):
|
| 512 |
+
value = value._value()
|
| 513 |
+
return _is_missing_literal(value)
|
| 514 |
+
|
| 515 |
+
|
| 516 |
+
def _is_missing_literal(value: Any) -> bool:
|
| 517 |
+
# Uses literal '???' instead of the MISSING const for performance reasons.
|
| 518 |
+
return isinstance(value, str) and value == "???"
|
| 519 |
+
|
| 520 |
+
|
| 521 |
+
def _is_none(
|
| 522 |
+
value: Any, resolve: bool = False, throw_on_resolution_failure: bool = True
|
| 523 |
+
) -> bool:
|
| 524 |
+
from omegaconf import Node
|
| 525 |
+
|
| 526 |
+
if not isinstance(value, Node):
|
| 527 |
+
return value is None
|
| 528 |
+
|
| 529 |
+
if resolve:
|
| 530 |
+
value = value._maybe_dereference_node(
|
| 531 |
+
throw_on_resolution_failure=throw_on_resolution_failure
|
| 532 |
+
)
|
| 533 |
+
if not throw_on_resolution_failure and value is None:
|
| 534 |
+
# Resolution failure: consider that it is *not* None.
|
| 535 |
+
return False
|
| 536 |
+
assert isinstance(value, Node)
|
| 537 |
+
|
| 538 |
+
return value._is_none()
|
| 539 |
+
|
| 540 |
+
|
| 541 |
+
def get_value_kind(
|
| 542 |
+
value: Any, strict_interpolation_validation: bool = False
|
| 543 |
+
) -> ValueKind:
|
| 544 |
+
"""
|
| 545 |
+
Determine the kind of a value
|
| 546 |
+
Examples:
|
| 547 |
+
VALUE: "10", "20", True
|
| 548 |
+
MANDATORY_MISSING: "???"
|
| 549 |
+
INTERPOLATION: "${foo.bar}", "${foo.${bar}}", "${foo:bar}", "[${foo}, ${bar}]",
|
| 550 |
+
"ftp://${host}/path", "${foo:${bar}, [true], {'baz': ${baz}}}"
|
| 551 |
+
|
| 552 |
+
:param value: Input to classify.
|
| 553 |
+
:param strict_interpolation_validation: If `True`, then when `value` is a string
|
| 554 |
+
containing "${", it is parsed to validate the interpolation syntax. If `False`,
|
| 555 |
+
this parsing step is skipped: this is more efficient, but will not detect errors.
|
| 556 |
+
"""
|
| 557 |
+
|
| 558 |
+
if _is_missing_value(value):
|
| 559 |
+
return ValueKind.MANDATORY_MISSING
|
| 560 |
+
|
| 561 |
+
if _is_interpolation(value, strict_interpolation_validation):
|
| 562 |
+
return ValueKind.INTERPOLATION
|
| 563 |
+
|
| 564 |
+
return ValueKind.VALUE
|
| 565 |
+
|
| 566 |
+
|
| 567 |
+
def _is_interpolation(v: Any, strict_interpolation_validation: bool = False) -> bool:
|
| 568 |
+
from omegaconf import Node
|
| 569 |
+
|
| 570 |
+
if isinstance(v, Node):
|
| 571 |
+
v = v._value()
|
| 572 |
+
|
| 573 |
+
if isinstance(v, str) and _is_interpolation_string(
|
| 574 |
+
v, strict_interpolation_validation
|
| 575 |
+
):
|
| 576 |
+
return True
|
| 577 |
+
return False
|
| 578 |
+
|
| 579 |
+
|
| 580 |
+
def _is_interpolation_string(value: str, strict_interpolation_validation: bool) -> bool:
|
| 581 |
+
# We identify potential interpolations by the presence of "${" in the string.
|
| 582 |
+
# Note that escaped interpolations (ex: "esc: \${bar}") are identified as
|
| 583 |
+
# interpolations: this is intended, since they must be processed as interpolations
|
| 584 |
+
# for the string to be properly un-escaped.
|
| 585 |
+
# Keep in mind that invalid interpolations will only be detected when
|
| 586 |
+
# `strict_interpolation_validation` is True.
|
| 587 |
+
if "${" in value:
|
| 588 |
+
if strict_interpolation_validation:
|
| 589 |
+
# First try the cheap regex matching that detects common interpolations.
|
| 590 |
+
if SIMPLE_INTERPOLATION_PATTERN.match(value) is None:
|
| 591 |
+
# If no match, do the more expensive grammar parsing to detect errors.
|
| 592 |
+
parse(value)
|
| 593 |
+
return True
|
| 594 |
+
return False
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
def _is_special(value: Any) -> bool:
|
| 598 |
+
"""Special values are None, MISSING, and interpolation."""
|
| 599 |
+
return _is_none(value) or get_value_kind(value) in (
|
| 600 |
+
ValueKind.MANDATORY_MISSING,
|
| 601 |
+
ValueKind.INTERPOLATION,
|
| 602 |
+
)
|
| 603 |
+
|
| 604 |
+
|
| 605 |
+
def is_float(st: str) -> bool:
|
| 606 |
+
try:
|
| 607 |
+
float(st)
|
| 608 |
+
return True
|
| 609 |
+
except ValueError:
|
| 610 |
+
return False
|
| 611 |
+
|
| 612 |
+
|
| 613 |
+
def is_int(st: str) -> bool:
|
| 614 |
+
try:
|
| 615 |
+
int(st)
|
| 616 |
+
return True
|
| 617 |
+
except ValueError:
|
| 618 |
+
return False
|
| 619 |
+
|
| 620 |
+
|
| 621 |
+
def is_primitive_list(obj: Any) -> bool:
|
| 622 |
+
return isinstance(obj, (list, tuple))
|
| 623 |
+
|
| 624 |
+
|
| 625 |
+
def is_primitive_dict(obj: Any) -> bool:
|
| 626 |
+
t = get_type_of(obj)
|
| 627 |
+
return t is dict
|
| 628 |
+
|
| 629 |
+
|
| 630 |
+
def is_dict_annotation(type_: Any) -> bool:
|
| 631 |
+
if type_ in (dict, Dict):
|
| 632 |
+
return True
|
| 633 |
+
origin = getattr(type_, "__origin__", None)
|
| 634 |
+
# type_dict is a bit hard to detect.
|
| 635 |
+
# this support is tentative, if it eventually causes issues in other areas it may be dropped.
|
| 636 |
+
if sys.version_info < (3, 7, 0): # pragma: no cover
|
| 637 |
+
typed_dict = hasattr(type_, "__base__") and type_.__base__ == Dict
|
| 638 |
+
return origin is Dict or type_ is Dict or typed_dict
|
| 639 |
+
else: # pragma: no cover
|
| 640 |
+
typed_dict = hasattr(type_, "__base__") and type_.__base__ == dict
|
| 641 |
+
return origin is dict or typed_dict
|
| 642 |
+
|
| 643 |
+
|
| 644 |
+
def is_list_annotation(type_: Any) -> bool:
|
| 645 |
+
if type_ in (list, List):
|
| 646 |
+
return True
|
| 647 |
+
origin = getattr(type_, "__origin__", None)
|
| 648 |
+
if sys.version_info < (3, 7, 0):
|
| 649 |
+
return origin is List or type_ is List # pragma: no cover
|
| 650 |
+
else:
|
| 651 |
+
return origin is list # pragma: no cover
|
| 652 |
+
|
| 653 |
+
|
| 654 |
+
def is_tuple_annotation(type_: Any) -> bool:
|
| 655 |
+
if type_ in (tuple, Tuple):
|
| 656 |
+
return True
|
| 657 |
+
origin = getattr(type_, "__origin__", None)
|
| 658 |
+
if sys.version_info < (3, 7, 0):
|
| 659 |
+
return origin is Tuple or type_ is Tuple # pragma: no cover
|
| 660 |
+
else:
|
| 661 |
+
return origin is tuple # pragma: no cover
|
| 662 |
+
|
| 663 |
+
|
| 664 |
+
def is_supported_union_annotation(obj: Any) -> bool:
|
| 665 |
+
"""Currently only primitive types are supported in Unions, e.g. Union[int, str]"""
|
| 666 |
+
if not is_union_annotation(obj):
|
| 667 |
+
return False
|
| 668 |
+
args = obj.__args__
|
| 669 |
+
return all(is_primitive_type_annotation(arg) for arg in args)
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
def is_dict_subclass(type_: Any) -> bool:
|
| 673 |
+
return type_ is not None and isinstance(type_, type) and issubclass(type_, Dict)
|
| 674 |
+
|
| 675 |
+
|
| 676 |
+
def is_dict(obj: Any) -> bool:
|
| 677 |
+
return is_primitive_dict(obj) or is_dict_annotation(obj) or is_dict_subclass(obj)
|
| 678 |
+
|
| 679 |
+
|
| 680 |
+
def is_primitive_container(obj: Any) -> bool:
|
| 681 |
+
return is_primitive_list(obj) or is_primitive_dict(obj)
|
| 682 |
+
|
| 683 |
+
|
| 684 |
+
def get_list_element_type(ref_type: Optional[Type[Any]]) -> Any:
|
| 685 |
+
args = getattr(ref_type, "__args__", None)
|
| 686 |
+
if ref_type is not List and args is not None and args[0]:
|
| 687 |
+
element_type = args[0]
|
| 688 |
+
else:
|
| 689 |
+
element_type = Any
|
| 690 |
+
return element_type
|
| 691 |
+
|
| 692 |
+
|
| 693 |
+
def get_tuple_item_types(ref_type: Type[Any]) -> Tuple[Any, ...]:
|
| 694 |
+
args = getattr(ref_type, "__args__", None)
|
| 695 |
+
if args in (None, ()):
|
| 696 |
+
args = (Any, ...)
|
| 697 |
+
assert isinstance(args, tuple)
|
| 698 |
+
return args
|
| 699 |
+
|
| 700 |
+
|
| 701 |
+
def get_dict_key_value_types(ref_type: Any) -> Tuple[Any, Any]:
|
| 702 |
+
args = getattr(ref_type, "__args__", None)
|
| 703 |
+
if args is None:
|
| 704 |
+
bases = getattr(ref_type, "__orig_bases__", None)
|
| 705 |
+
if bases is not None and len(bases) > 0:
|
| 706 |
+
args = getattr(bases[0], "__args__", None)
|
| 707 |
+
|
| 708 |
+
key_type: Any
|
| 709 |
+
element_type: Any
|
| 710 |
+
if ref_type is None or ref_type == Dict:
|
| 711 |
+
key_type = Any
|
| 712 |
+
element_type = Any
|
| 713 |
+
else:
|
| 714 |
+
if args is not None:
|
| 715 |
+
key_type = args[0]
|
| 716 |
+
element_type = args[1]
|
| 717 |
+
else:
|
| 718 |
+
key_type = Any
|
| 719 |
+
element_type = Any
|
| 720 |
+
|
| 721 |
+
return key_type, element_type
|
| 722 |
+
|
| 723 |
+
|
| 724 |
+
def is_valid_value_annotation(type_: Any) -> bool:
|
| 725 |
+
_, type_ = _resolve_optional(type_)
|
| 726 |
+
return (
|
| 727 |
+
type_ is Any
|
| 728 |
+
or is_primitive_type_annotation(type_)
|
| 729 |
+
or is_structured_config(type_)
|
| 730 |
+
or is_container_annotation(type_)
|
| 731 |
+
or is_supported_union_annotation(type_)
|
| 732 |
+
)
|
| 733 |
+
|
| 734 |
+
|
| 735 |
+
def _valid_dict_key_annotation_type(type_: Any) -> bool:
|
| 736 |
+
from omegaconf import DictKeyType
|
| 737 |
+
|
| 738 |
+
return type_ is None or type_ is Any or issubclass(type_, DictKeyType.__args__) # type: ignore
|
| 739 |
+
|
| 740 |
+
|
| 741 |
+
def is_primitive_type_annotation(type_: Any) -> bool:
|
| 742 |
+
type_ = get_type_of(type_)
|
| 743 |
+
return issubclass(type_, (Enum, pathlib.Path)) or type_ in BUILTIN_VALUE_TYPES
|
| 744 |
+
|
| 745 |
+
|
| 746 |
+
def _get_value(value: Any) -> Any:
|
| 747 |
+
from .base import Container, UnionNode
|
| 748 |
+
from .nodes import ValueNode
|
| 749 |
+
|
| 750 |
+
if isinstance(value, ValueNode):
|
| 751 |
+
return value._value()
|
| 752 |
+
elif isinstance(value, Container):
|
| 753 |
+
boxed = value._value()
|
| 754 |
+
if boxed is None or _is_missing_literal(boxed) or _is_interpolation(boxed):
|
| 755 |
+
return boxed
|
| 756 |
+
elif isinstance(value, UnionNode):
|
| 757 |
+
boxed = value._value()
|
| 758 |
+
if boxed is None or _is_missing_literal(boxed) or _is_interpolation(boxed):
|
| 759 |
+
return boxed
|
| 760 |
+
else:
|
| 761 |
+
return _get_value(boxed) # pass through value of boxed node
|
| 762 |
+
|
| 763 |
+
# return primitives and regular OmegaConf Containers as is
|
| 764 |
+
return value
|
| 765 |
+
|
| 766 |
+
|
| 767 |
+
def get_type_hint(obj: Any, key: Any = None) -> Optional[Type[Any]]:
|
| 768 |
+
from omegaconf import Container, Node
|
| 769 |
+
|
| 770 |
+
if isinstance(obj, Container):
|
| 771 |
+
if key is not None:
|
| 772 |
+
obj = obj._get_node(key)
|
| 773 |
+
else:
|
| 774 |
+
if key is not None:
|
| 775 |
+
raise ValueError("Key must only be provided when obj is a container")
|
| 776 |
+
|
| 777 |
+
if isinstance(obj, Node):
|
| 778 |
+
ref_type = obj._metadata.ref_type
|
| 779 |
+
if obj._is_optional() and ref_type is not Any:
|
| 780 |
+
return Optional[ref_type] # type: ignore
|
| 781 |
+
else:
|
| 782 |
+
return ref_type
|
| 783 |
+
else:
|
| 784 |
+
return Any # type: ignore
|
| 785 |
+
|
| 786 |
+
|
| 787 |
+
def _raise(ex: Exception, cause: Exception) -> None:
|
| 788 |
+
# Set the environment variable OC_CAUSE=1 to get a stacktrace that includes the
|
| 789 |
+
# causing exception.
|
| 790 |
+
env_var = os.environ["OC_CAUSE"] if "OC_CAUSE" in os.environ else None
|
| 791 |
+
debugging = sys.gettrace() is not None
|
| 792 |
+
full_backtrace = (debugging and not env_var == "0") or (env_var == "1")
|
| 793 |
+
if full_backtrace:
|
| 794 |
+
ex.__cause__ = cause
|
| 795 |
+
else:
|
| 796 |
+
ex.__cause__ = None
|
| 797 |
+
raise ex.with_traceback(sys.exc_info()[2]) # set env var OC_CAUSE=1 for full trace
|
| 798 |
+
|
| 799 |
+
|
| 800 |
+
def format_and_raise(
|
| 801 |
+
node: Any,
|
| 802 |
+
key: Any,
|
| 803 |
+
value: Any,
|
| 804 |
+
msg: str,
|
| 805 |
+
cause: Exception,
|
| 806 |
+
type_override: Any = None,
|
| 807 |
+
) -> None:
|
| 808 |
+
from omegaconf import OmegaConf
|
| 809 |
+
from omegaconf.base import Node
|
| 810 |
+
|
| 811 |
+
if isinstance(cause, AssertionError):
|
| 812 |
+
raise
|
| 813 |
+
|
| 814 |
+
if isinstance(cause, OmegaConfBaseException) and cause._initialized:
|
| 815 |
+
ex = cause
|
| 816 |
+
if type_override is not None:
|
| 817 |
+
ex = type_override(str(cause))
|
| 818 |
+
ex.__dict__ = copy.deepcopy(cause.__dict__)
|
| 819 |
+
_raise(ex, cause)
|
| 820 |
+
|
| 821 |
+
object_type: Optional[Type[Any]]
|
| 822 |
+
object_type_str: Optional[str] = None
|
| 823 |
+
ref_type: Optional[Type[Any]]
|
| 824 |
+
ref_type_str: Optional[str]
|
| 825 |
+
|
| 826 |
+
child_node: Optional[Node] = None
|
| 827 |
+
if node is None:
|
| 828 |
+
full_key = key if key is not None else ""
|
| 829 |
+
object_type = None
|
| 830 |
+
ref_type = None
|
| 831 |
+
ref_type_str = None
|
| 832 |
+
else:
|
| 833 |
+
if key is not None and not node._is_none():
|
| 834 |
+
child_node = node._get_node(key, validate_access=False)
|
| 835 |
+
|
| 836 |
+
try:
|
| 837 |
+
full_key = node._get_full_key(key=key)
|
| 838 |
+
except Exception as exc:
|
| 839 |
+
# Since we are handling an exception, raising a different one here would
|
| 840 |
+
# be misleading. Instead, we display it in the key.
|
| 841 |
+
full_key = f"<unresolvable due to {type(exc).__name__}: {exc}>"
|
| 842 |
+
|
| 843 |
+
object_type = OmegaConf.get_type(node)
|
| 844 |
+
object_type_str = type_str(object_type)
|
| 845 |
+
|
| 846 |
+
ref_type = get_type_hint(node)
|
| 847 |
+
ref_type_str = type_str(ref_type)
|
| 848 |
+
|
| 849 |
+
msg = string.Template(msg).safe_substitute(
|
| 850 |
+
REF_TYPE=ref_type_str,
|
| 851 |
+
OBJECT_TYPE=object_type_str,
|
| 852 |
+
KEY=key,
|
| 853 |
+
FULL_KEY=full_key,
|
| 854 |
+
VALUE=value,
|
| 855 |
+
VALUE_TYPE=type_str(type(value), include_module_name=True),
|
| 856 |
+
KEY_TYPE=f"{type(key).__name__}",
|
| 857 |
+
)
|
| 858 |
+
|
| 859 |
+
if ref_type not in (None, Any):
|
| 860 |
+
template = dedent(
|
| 861 |
+
"""\
|
| 862 |
+
$MSG
|
| 863 |
+
full_key: $FULL_KEY
|
| 864 |
+
reference_type=$REF_TYPE
|
| 865 |
+
object_type=$OBJECT_TYPE"""
|
| 866 |
+
)
|
| 867 |
+
else:
|
| 868 |
+
template = dedent(
|
| 869 |
+
"""\
|
| 870 |
+
$MSG
|
| 871 |
+
full_key: $FULL_KEY
|
| 872 |
+
object_type=$OBJECT_TYPE"""
|
| 873 |
+
)
|
| 874 |
+
s = string.Template(template=template)
|
| 875 |
+
|
| 876 |
+
message = s.substitute(
|
| 877 |
+
REF_TYPE=ref_type_str, OBJECT_TYPE=object_type_str, MSG=msg, FULL_KEY=full_key
|
| 878 |
+
)
|
| 879 |
+
exception_type = type(cause) if type_override is None else type_override
|
| 880 |
+
if exception_type == TypeError:
|
| 881 |
+
exception_type = ConfigTypeError
|
| 882 |
+
elif exception_type == IndexError:
|
| 883 |
+
exception_type = ConfigIndexError
|
| 884 |
+
|
| 885 |
+
ex = exception_type(f"{message}")
|
| 886 |
+
if issubclass(exception_type, OmegaConfBaseException):
|
| 887 |
+
ex._initialized = True
|
| 888 |
+
ex.msg = message
|
| 889 |
+
ex.parent_node = node
|
| 890 |
+
ex.child_node = child_node
|
| 891 |
+
ex.key = key
|
| 892 |
+
ex.full_key = full_key
|
| 893 |
+
ex.value = value
|
| 894 |
+
ex.object_type = object_type
|
| 895 |
+
ex.object_type_str = object_type_str
|
| 896 |
+
ex.ref_type = ref_type
|
| 897 |
+
ex.ref_type_str = ref_type_str
|
| 898 |
+
|
| 899 |
+
_raise(ex, cause)
|
| 900 |
+
|
| 901 |
+
|
| 902 |
+
def type_str(t: Any, include_module_name: bool = False) -> str:
|
| 903 |
+
is_optional, t = _resolve_optional(t)
|
| 904 |
+
if t is NoneType:
|
| 905 |
+
return str(t.__name__)
|
| 906 |
+
if t is Any:
|
| 907 |
+
return "Any"
|
| 908 |
+
if t is ...:
|
| 909 |
+
return "..."
|
| 910 |
+
|
| 911 |
+
if hasattr(t, "__name__"):
|
| 912 |
+
name = str(t.__name__)
|
| 913 |
+
elif getattr(t, "_name", None) is not None: # pragma: no cover
|
| 914 |
+
name = str(t._name)
|
| 915 |
+
elif getattr(t, "__origin__", None) is not None: # pragma: no cover
|
| 916 |
+
name = type_str(t.__origin__)
|
| 917 |
+
else:
|
| 918 |
+
name = str(t)
|
| 919 |
+
if name.startswith("typing."): # pragma: no cover
|
| 920 |
+
name = name[len("typing.") :]
|
| 921 |
+
|
| 922 |
+
args = getattr(t, "__args__", None)
|
| 923 |
+
if args is not None:
|
| 924 |
+
args = ", ".join(
|
| 925 |
+
[type_str(t, include_module_name=include_module_name) for t in t.__args__]
|
| 926 |
+
)
|
| 927 |
+
ret = f"{name}[{args}]"
|
| 928 |
+
else:
|
| 929 |
+
ret = name
|
| 930 |
+
if include_module_name:
|
| 931 |
+
if (
|
| 932 |
+
hasattr(t, "__module__")
|
| 933 |
+
and t.__module__ != "builtins"
|
| 934 |
+
and t.__module__ != "typing"
|
| 935 |
+
and not t.__module__.startswith("omegaconf.")
|
| 936 |
+
):
|
| 937 |
+
module_prefix = str(t.__module__) + "."
|
| 938 |
+
else:
|
| 939 |
+
module_prefix = ""
|
| 940 |
+
ret = module_prefix + ret
|
| 941 |
+
if is_optional:
|
| 942 |
+
return f"Optional[{ret}]"
|
| 943 |
+
else:
|
| 944 |
+
return ret
|
| 945 |
+
|
| 946 |
+
|
| 947 |
+
def _ensure_container(target: Any, flags: Optional[Dict[str, bool]] = None) -> Any:
|
| 948 |
+
from omegaconf import OmegaConf
|
| 949 |
+
|
| 950 |
+
if is_primitive_container(target):
|
| 951 |
+
assert isinstance(target, (list, dict))
|
| 952 |
+
target = OmegaConf.create(target, flags=flags)
|
| 953 |
+
elif is_structured_config(target):
|
| 954 |
+
target = OmegaConf.structured(target, flags=flags)
|
| 955 |
+
elif not OmegaConf.is_config(target):
|
| 956 |
+
raise ValueError(
|
| 957 |
+
"Invalid input. Supports one of "
|
| 958 |
+
+ "[dict,list,DictConfig,ListConfig,dataclass,dataclass instance,attr class,attr class instance]"
|
| 959 |
+
)
|
| 960 |
+
|
| 961 |
+
return target
|
| 962 |
+
|
| 963 |
+
|
| 964 |
+
def is_generic_list(type_: Any) -> bool:
|
| 965 |
+
"""
|
| 966 |
+
Checks if a type is a generic list, for example:
|
| 967 |
+
list returns False
|
| 968 |
+
typing.List returns False
|
| 969 |
+
typing.List[T] returns True
|
| 970 |
+
|
| 971 |
+
:param type_: variable type
|
| 972 |
+
:return: bool
|
| 973 |
+
"""
|
| 974 |
+
return is_list_annotation(type_) and get_list_element_type(type_) is not None
|
| 975 |
+
|
| 976 |
+
|
| 977 |
+
def is_generic_dict(type_: Any) -> bool:
|
| 978 |
+
"""
|
| 979 |
+
Checks if a type is a generic dict, for example:
|
| 980 |
+
list returns False
|
| 981 |
+
typing.List returns False
|
| 982 |
+
typing.List[T] returns True
|
| 983 |
+
|
| 984 |
+
:param type_: variable type
|
| 985 |
+
:return: bool
|
| 986 |
+
"""
|
| 987 |
+
return is_dict_annotation(type_) and len(get_dict_key_value_types(type_)) > 0
|
| 988 |
+
|
| 989 |
+
|
| 990 |
+
def is_container_annotation(type_: Any) -> bool:
|
| 991 |
+
return is_list_annotation(type_) or is_dict_annotation(type_)
|
| 992 |
+
|
| 993 |
+
|
| 994 |
+
def split_key(key: str) -> List[str]:
|
| 995 |
+
"""
|
| 996 |
+
Split a full key path into its individual components.
|
| 997 |
+
|
| 998 |
+
This is similar to `key.split(".")` but also works with the getitem syntax:
|
| 999 |
+
"a.b" -> ["a", "b"]
|
| 1000 |
+
"a[b]" -> ["a", "b"]
|
| 1001 |
+
".a.b[c].d" -> ["", "a", "b", "c", "d"]
|
| 1002 |
+
"[a].b" -> ["a", "b"]
|
| 1003 |
+
"""
|
| 1004 |
+
# Obtain the first part of the key (in docstring examples: a, a, .a, '')
|
| 1005 |
+
first = KEY_PATH_HEAD.match(key)
|
| 1006 |
+
assert first is not None
|
| 1007 |
+
first_stop = first.span()[1]
|
| 1008 |
+
|
| 1009 |
+
# `tokens` will contain all elements composing the key.
|
| 1010 |
+
tokens = key[0:first_stop].split(".")
|
| 1011 |
+
|
| 1012 |
+
# Optimization in case `key` has no other component: we are done.
|
| 1013 |
+
if first_stop == len(key):
|
| 1014 |
+
return tokens
|
| 1015 |
+
|
| 1016 |
+
if key[first_stop] == "[" and not tokens[-1]:
|
| 1017 |
+
# This is a special case where the first key starts with brackets, e.g.
|
| 1018 |
+
# [a] or ..[a]. In that case there is an extra "" in `tokens` that we
|
| 1019 |
+
# need to get rid of:
|
| 1020 |
+
# [a] -> tokens = [""] but we would like []
|
| 1021 |
+
# ..[a] -> tokens = ["", "", ""] but we would like ["", ""]
|
| 1022 |
+
tokens.pop()
|
| 1023 |
+
|
| 1024 |
+
# Identify other key elements (in docstring examples: b, b, b/c/d, b)
|
| 1025 |
+
others = KEY_PATH_OTHER.findall(key[first_stop:])
|
| 1026 |
+
|
| 1027 |
+
# There are two groups in the `KEY_PATH_OTHER` regex: one for keys starting
|
| 1028 |
+
# with a dot (.b, .d) and one for keys starting with a bracket ([b], [c]).
|
| 1029 |
+
# Only one group can be non-empty.
|
| 1030 |
+
tokens += [dot_key if dot_key else bracket_key for dot_key, bracket_key in others]
|
| 1031 |
+
|
| 1032 |
+
return tokens
|
| 1033 |
+
|
| 1034 |
+
|
| 1035 |
+
# Similar to Python 3.7+'s `contextlib.nullcontext` (which should be used instead,
|
| 1036 |
+
# once support for Python 3.6 is dropped).
|
| 1037 |
+
@contextmanager
|
| 1038 |
+
def nullcontext(enter_result: Any = None) -> Iterator[Any]:
|
| 1039 |
+
yield enter_result
|
lib/python3.12/site-packages/omegaconf/base.py
ADDED
|
@@ -0,0 +1,962 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import sys
|
| 3 |
+
from abc import ABC, abstractmethod
|
| 4 |
+
from collections import defaultdict
|
| 5 |
+
from dataclasses import dataclass, field
|
| 6 |
+
from enum import Enum
|
| 7 |
+
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Type, Union
|
| 8 |
+
|
| 9 |
+
from antlr4 import ParserRuleContext
|
| 10 |
+
|
| 11 |
+
from ._utils import (
|
| 12 |
+
_DEFAULT_MARKER_,
|
| 13 |
+
NoneType,
|
| 14 |
+
ValueKind,
|
| 15 |
+
_get_value,
|
| 16 |
+
_is_interpolation,
|
| 17 |
+
_is_missing_value,
|
| 18 |
+
_is_special,
|
| 19 |
+
format_and_raise,
|
| 20 |
+
get_value_kind,
|
| 21 |
+
is_union_annotation,
|
| 22 |
+
is_valid_value_annotation,
|
| 23 |
+
split_key,
|
| 24 |
+
type_str,
|
| 25 |
+
)
|
| 26 |
+
from .errors import (
|
| 27 |
+
ConfigKeyError,
|
| 28 |
+
ConfigTypeError,
|
| 29 |
+
InterpolationKeyError,
|
| 30 |
+
InterpolationResolutionError,
|
| 31 |
+
InterpolationToMissingValueError,
|
| 32 |
+
InterpolationValidationError,
|
| 33 |
+
MissingMandatoryValue,
|
| 34 |
+
UnsupportedInterpolationType,
|
| 35 |
+
ValidationError,
|
| 36 |
+
)
|
| 37 |
+
from .grammar.gen.OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 38 |
+
from .grammar_parser import parse
|
| 39 |
+
from .grammar_visitor import GrammarVisitor
|
| 40 |
+
|
| 41 |
+
DictKeyType = Union[str, bytes, int, Enum, float, bool]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
@dataclass
|
| 45 |
+
class Metadata:
|
| 46 |
+
|
| 47 |
+
ref_type: Union[Type[Any], Any]
|
| 48 |
+
|
| 49 |
+
object_type: Union[Type[Any], Any]
|
| 50 |
+
|
| 51 |
+
optional: bool
|
| 52 |
+
|
| 53 |
+
key: Any
|
| 54 |
+
|
| 55 |
+
# Flags have 3 modes:
|
| 56 |
+
# unset : inherit from parent (None if no parent specifies)
|
| 57 |
+
# set to true: flag is true
|
| 58 |
+
# set to false: flag is false
|
| 59 |
+
flags: Optional[Dict[str, bool]] = None
|
| 60 |
+
|
| 61 |
+
# If True, when checking the value of a flag, if the flag is not set None is returned
|
| 62 |
+
# otherwise, the parent node is queried.
|
| 63 |
+
flags_root: bool = False
|
| 64 |
+
|
| 65 |
+
resolver_cache: Dict[str, Any] = field(default_factory=lambda: defaultdict(dict))
|
| 66 |
+
|
| 67 |
+
def __post_init__(self) -> None:
|
| 68 |
+
if self.flags is None:
|
| 69 |
+
self.flags = {}
|
| 70 |
+
|
| 71 |
+
@property
|
| 72 |
+
def type_hint(self) -> Union[Type[Any], Any]:
|
| 73 |
+
"""Compute `type_hint` from `self.optional` and `self.ref_type`"""
|
| 74 |
+
# For compatibility with pickled OmegaConf objects created using older
|
| 75 |
+
# versions of OmegaConf, we store `ref_type` and `object_type`
|
| 76 |
+
# separately (rather than storing `type_hint` directly).
|
| 77 |
+
if self.optional:
|
| 78 |
+
return Optional[self.ref_type]
|
| 79 |
+
else:
|
| 80 |
+
return self.ref_type
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
@dataclass
|
| 84 |
+
class ContainerMetadata(Metadata):
|
| 85 |
+
key_type: Any = None
|
| 86 |
+
element_type: Any = None
|
| 87 |
+
|
| 88 |
+
def __post_init__(self) -> None:
|
| 89 |
+
if self.ref_type is None:
|
| 90 |
+
self.ref_type = Any
|
| 91 |
+
assert self.key_type is Any or isinstance(self.key_type, type)
|
| 92 |
+
if self.element_type is not None:
|
| 93 |
+
if not is_valid_value_annotation(self.element_type):
|
| 94 |
+
raise ValidationError(
|
| 95 |
+
f"Unsupported value type: '{type_str(self.element_type, include_module_name=True)}'"
|
| 96 |
+
)
|
| 97 |
+
|
| 98 |
+
if self.flags is None:
|
| 99 |
+
self.flags = {}
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
class Node(ABC):
|
| 103 |
+
_metadata: Metadata
|
| 104 |
+
|
| 105 |
+
_parent: Optional["Box"]
|
| 106 |
+
_flags_cache: Optional[Dict[str, Optional[bool]]]
|
| 107 |
+
|
| 108 |
+
def __init__(self, parent: Optional["Box"], metadata: Metadata):
|
| 109 |
+
self.__dict__["_metadata"] = metadata
|
| 110 |
+
self.__dict__["_parent"] = parent
|
| 111 |
+
self.__dict__["_flags_cache"] = None
|
| 112 |
+
|
| 113 |
+
def __getstate__(self) -> Dict[str, Any]:
|
| 114 |
+
# Overridden to ensure that the flags cache is cleared on serialization.
|
| 115 |
+
state_dict = copy.copy(self.__dict__)
|
| 116 |
+
del state_dict["_flags_cache"]
|
| 117 |
+
return state_dict
|
| 118 |
+
|
| 119 |
+
def __setstate__(self, state_dict: Dict[str, Any]) -> None:
|
| 120 |
+
self.__dict__.update(state_dict)
|
| 121 |
+
self.__dict__["_flags_cache"] = None
|
| 122 |
+
|
| 123 |
+
def _set_parent(self, parent: Optional["Box"]) -> None:
|
| 124 |
+
assert parent is None or isinstance(parent, Box)
|
| 125 |
+
self.__dict__["_parent"] = parent
|
| 126 |
+
self._invalidate_flags_cache()
|
| 127 |
+
|
| 128 |
+
def _invalidate_flags_cache(self) -> None:
|
| 129 |
+
self.__dict__["_flags_cache"] = None
|
| 130 |
+
|
| 131 |
+
def _get_parent(self) -> Optional["Box"]:
|
| 132 |
+
parent = self.__dict__["_parent"]
|
| 133 |
+
assert parent is None or isinstance(parent, Box)
|
| 134 |
+
return parent
|
| 135 |
+
|
| 136 |
+
def _get_parent_container(self) -> Optional["Container"]:
|
| 137 |
+
"""
|
| 138 |
+
Like _get_parent, but returns the grandparent
|
| 139 |
+
in the case where `self` is wrapped by a UnionNode.
|
| 140 |
+
"""
|
| 141 |
+
parent = self.__dict__["_parent"]
|
| 142 |
+
assert parent is None or isinstance(parent, Box)
|
| 143 |
+
|
| 144 |
+
if isinstance(parent, UnionNode):
|
| 145 |
+
grandparent = parent.__dict__["_parent"]
|
| 146 |
+
assert grandparent is None or isinstance(grandparent, Container)
|
| 147 |
+
return grandparent
|
| 148 |
+
else:
|
| 149 |
+
assert parent is None or isinstance(parent, Container)
|
| 150 |
+
return parent
|
| 151 |
+
|
| 152 |
+
def _set_flag(
|
| 153 |
+
self,
|
| 154 |
+
flags: Union[List[str], str],
|
| 155 |
+
values: Union[List[Optional[bool]], Optional[bool]],
|
| 156 |
+
) -> "Node":
|
| 157 |
+
if isinstance(flags, str):
|
| 158 |
+
flags = [flags]
|
| 159 |
+
|
| 160 |
+
if values is None or isinstance(values, bool):
|
| 161 |
+
values = [values]
|
| 162 |
+
|
| 163 |
+
if len(values) == 1:
|
| 164 |
+
values = len(flags) * values
|
| 165 |
+
|
| 166 |
+
if len(flags) != len(values):
|
| 167 |
+
raise ValueError("Inconsistent lengths of input flag names and values")
|
| 168 |
+
|
| 169 |
+
for idx, flag in enumerate(flags):
|
| 170 |
+
value = values[idx]
|
| 171 |
+
if value is None:
|
| 172 |
+
assert self._metadata.flags is not None
|
| 173 |
+
if flag in self._metadata.flags:
|
| 174 |
+
del self._metadata.flags[flag]
|
| 175 |
+
else:
|
| 176 |
+
assert self._metadata.flags is not None
|
| 177 |
+
self._metadata.flags[flag] = value
|
| 178 |
+
self._invalidate_flags_cache()
|
| 179 |
+
return self
|
| 180 |
+
|
| 181 |
+
def _get_node_flag(self, flag: str) -> Optional[bool]:
|
| 182 |
+
"""
|
| 183 |
+
:param flag: flag to inspect
|
| 184 |
+
:return: the state of the flag on this node.
|
| 185 |
+
"""
|
| 186 |
+
assert self._metadata.flags is not None
|
| 187 |
+
return self._metadata.flags.get(flag)
|
| 188 |
+
|
| 189 |
+
def _get_flag(self, flag: str) -> Optional[bool]:
|
| 190 |
+
cache = self.__dict__["_flags_cache"]
|
| 191 |
+
if cache is None:
|
| 192 |
+
cache = self.__dict__["_flags_cache"] = {}
|
| 193 |
+
|
| 194 |
+
ret = cache.get(flag, _DEFAULT_MARKER_)
|
| 195 |
+
if ret is _DEFAULT_MARKER_:
|
| 196 |
+
ret = self._get_flag_no_cache(flag)
|
| 197 |
+
cache[flag] = ret
|
| 198 |
+
assert ret is None or isinstance(ret, bool)
|
| 199 |
+
return ret
|
| 200 |
+
|
| 201 |
+
def _get_flag_no_cache(self, flag: str) -> Optional[bool]:
|
| 202 |
+
"""
|
| 203 |
+
Returns True if this config node flag is set
|
| 204 |
+
A flag is set if node.set_flag(True) was called
|
| 205 |
+
or one if it's parents is flag is set
|
| 206 |
+
:return:
|
| 207 |
+
"""
|
| 208 |
+
flags = self._metadata.flags
|
| 209 |
+
assert flags is not None
|
| 210 |
+
if flag in flags and flags[flag] is not None:
|
| 211 |
+
return flags[flag]
|
| 212 |
+
|
| 213 |
+
if self._is_flags_root():
|
| 214 |
+
return None
|
| 215 |
+
|
| 216 |
+
parent = self._get_parent()
|
| 217 |
+
if parent is None:
|
| 218 |
+
return None
|
| 219 |
+
else:
|
| 220 |
+
# noinspection PyProtectedMember
|
| 221 |
+
return parent._get_flag(flag)
|
| 222 |
+
|
| 223 |
+
def _format_and_raise(
|
| 224 |
+
self,
|
| 225 |
+
key: Any,
|
| 226 |
+
value: Any,
|
| 227 |
+
cause: Exception,
|
| 228 |
+
msg: Optional[str] = None,
|
| 229 |
+
type_override: Any = None,
|
| 230 |
+
) -> None:
|
| 231 |
+
format_and_raise(
|
| 232 |
+
node=self,
|
| 233 |
+
key=key,
|
| 234 |
+
value=value,
|
| 235 |
+
msg=str(cause) if msg is None else msg,
|
| 236 |
+
cause=cause,
|
| 237 |
+
type_override=type_override,
|
| 238 |
+
)
|
| 239 |
+
assert False
|
| 240 |
+
|
| 241 |
+
@abstractmethod
|
| 242 |
+
def _get_full_key(self, key: Optional[Union[DictKeyType, int]]) -> str:
|
| 243 |
+
...
|
| 244 |
+
|
| 245 |
+
def _dereference_node(self) -> "Node":
|
| 246 |
+
node = self._dereference_node_impl(throw_on_resolution_failure=True)
|
| 247 |
+
assert node is not None
|
| 248 |
+
return node
|
| 249 |
+
|
| 250 |
+
def _maybe_dereference_node(
|
| 251 |
+
self,
|
| 252 |
+
throw_on_resolution_failure: bool = False,
|
| 253 |
+
memo: Optional[Set[int]] = None,
|
| 254 |
+
) -> Optional["Node"]:
|
| 255 |
+
return self._dereference_node_impl(
|
| 256 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 257 |
+
memo=memo,
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
def _dereference_node_impl(
|
| 261 |
+
self,
|
| 262 |
+
throw_on_resolution_failure: bool,
|
| 263 |
+
memo: Optional[Set[int]] = None,
|
| 264 |
+
) -> Optional["Node"]:
|
| 265 |
+
if not self._is_interpolation():
|
| 266 |
+
return self
|
| 267 |
+
|
| 268 |
+
parent = self._get_parent_container()
|
| 269 |
+
if parent is None:
|
| 270 |
+
if throw_on_resolution_failure:
|
| 271 |
+
raise InterpolationResolutionError(
|
| 272 |
+
"Cannot resolve interpolation for a node without a parent"
|
| 273 |
+
)
|
| 274 |
+
return None
|
| 275 |
+
assert parent is not None
|
| 276 |
+
key = self._key()
|
| 277 |
+
return parent._resolve_interpolation_from_parse_tree(
|
| 278 |
+
parent=parent,
|
| 279 |
+
key=key,
|
| 280 |
+
value=self,
|
| 281 |
+
parse_tree=parse(_get_value(self)),
|
| 282 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 283 |
+
memo=memo,
|
| 284 |
+
)
|
| 285 |
+
|
| 286 |
+
def _get_root(self) -> "Container":
|
| 287 |
+
root: Optional[Box] = self._get_parent()
|
| 288 |
+
if root is None:
|
| 289 |
+
assert isinstance(self, Container)
|
| 290 |
+
return self
|
| 291 |
+
assert root is not None and isinstance(root, Box)
|
| 292 |
+
while root._get_parent() is not None:
|
| 293 |
+
root = root._get_parent()
|
| 294 |
+
assert root is not None and isinstance(root, Box)
|
| 295 |
+
assert root is not None and isinstance(root, Container)
|
| 296 |
+
return root
|
| 297 |
+
|
| 298 |
+
def _is_missing(self) -> bool:
|
| 299 |
+
"""
|
| 300 |
+
Check if the node's value is `???` (does *not* resolve interpolations).
|
| 301 |
+
"""
|
| 302 |
+
return _is_missing_value(self)
|
| 303 |
+
|
| 304 |
+
def _is_none(self) -> bool:
|
| 305 |
+
"""
|
| 306 |
+
Check if the node's value is `None` (does *not* resolve interpolations).
|
| 307 |
+
"""
|
| 308 |
+
return self._value() is None
|
| 309 |
+
|
| 310 |
+
@abstractmethod
|
| 311 |
+
def __eq__(self, other: Any) -> bool:
|
| 312 |
+
...
|
| 313 |
+
|
| 314 |
+
@abstractmethod
|
| 315 |
+
def __ne__(self, other: Any) -> bool:
|
| 316 |
+
...
|
| 317 |
+
|
| 318 |
+
@abstractmethod
|
| 319 |
+
def __hash__(self) -> int:
|
| 320 |
+
...
|
| 321 |
+
|
| 322 |
+
@abstractmethod
|
| 323 |
+
def _value(self) -> Any:
|
| 324 |
+
...
|
| 325 |
+
|
| 326 |
+
@abstractmethod
|
| 327 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 328 |
+
...
|
| 329 |
+
|
| 330 |
+
@abstractmethod
|
| 331 |
+
def _is_optional(self) -> bool:
|
| 332 |
+
...
|
| 333 |
+
|
| 334 |
+
@abstractmethod
|
| 335 |
+
def _is_interpolation(self) -> bool:
|
| 336 |
+
...
|
| 337 |
+
|
| 338 |
+
def _key(self) -> Any:
|
| 339 |
+
return self._metadata.key
|
| 340 |
+
|
| 341 |
+
def _set_key(self, key: Any) -> None:
|
| 342 |
+
self._metadata.key = key
|
| 343 |
+
|
| 344 |
+
def _is_flags_root(self) -> bool:
|
| 345 |
+
return self._metadata.flags_root
|
| 346 |
+
|
| 347 |
+
def _set_flags_root(self, flags_root: bool) -> None:
|
| 348 |
+
if self._metadata.flags_root != flags_root:
|
| 349 |
+
self._metadata.flags_root = flags_root
|
| 350 |
+
self._invalidate_flags_cache()
|
| 351 |
+
|
| 352 |
+
def _has_ref_type(self) -> bool:
|
| 353 |
+
return self._metadata.ref_type is not Any
|
| 354 |
+
|
| 355 |
+
|
| 356 |
+
class Box(Node):
|
| 357 |
+
"""
|
| 358 |
+
Base class for nodes that can contain other nodes.
|
| 359 |
+
Concrete subclasses include DictConfig, ListConfig, and UnionNode.
|
| 360 |
+
"""
|
| 361 |
+
|
| 362 |
+
_content: Any
|
| 363 |
+
|
| 364 |
+
def __init__(self, parent: Optional["Box"], metadata: Metadata):
|
| 365 |
+
super().__init__(parent=parent, metadata=metadata)
|
| 366 |
+
self.__dict__["_content"] = None
|
| 367 |
+
|
| 368 |
+
def __copy__(self) -> Any:
|
| 369 |
+
# real shallow copy is impossible because of the reference to the parent.
|
| 370 |
+
return copy.deepcopy(self)
|
| 371 |
+
|
| 372 |
+
def _re_parent(self) -> None:
|
| 373 |
+
from .dictconfig import DictConfig
|
| 374 |
+
from .listconfig import ListConfig
|
| 375 |
+
|
| 376 |
+
# update parents of first level Config nodes to self
|
| 377 |
+
|
| 378 |
+
if isinstance(self, DictConfig):
|
| 379 |
+
content = self.__dict__["_content"]
|
| 380 |
+
if isinstance(content, dict):
|
| 381 |
+
for _key, value in self.__dict__["_content"].items():
|
| 382 |
+
if value is not None:
|
| 383 |
+
value._set_parent(self)
|
| 384 |
+
if isinstance(value, Box):
|
| 385 |
+
value._re_parent()
|
| 386 |
+
elif isinstance(self, ListConfig):
|
| 387 |
+
content = self.__dict__["_content"]
|
| 388 |
+
if isinstance(content, list):
|
| 389 |
+
for item in self.__dict__["_content"]:
|
| 390 |
+
if item is not None:
|
| 391 |
+
item._set_parent(self)
|
| 392 |
+
if isinstance(item, Box):
|
| 393 |
+
item._re_parent()
|
| 394 |
+
elif isinstance(self, UnionNode):
|
| 395 |
+
content = self.__dict__["_content"]
|
| 396 |
+
if isinstance(content, Node):
|
| 397 |
+
content._set_parent(self)
|
| 398 |
+
if isinstance(content, Box): # pragma: no cover
|
| 399 |
+
# No coverage here as support for containers inside
|
| 400 |
+
# UnionNode is not yet implemented
|
| 401 |
+
content._re_parent()
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
class Container(Box):
|
| 405 |
+
"""
|
| 406 |
+
Container tagging interface
|
| 407 |
+
"""
|
| 408 |
+
|
| 409 |
+
_metadata: ContainerMetadata
|
| 410 |
+
|
| 411 |
+
@abstractmethod
|
| 412 |
+
def _get_child(
|
| 413 |
+
self,
|
| 414 |
+
key: Any,
|
| 415 |
+
validate_access: bool = True,
|
| 416 |
+
validate_key: bool = True,
|
| 417 |
+
throw_on_missing_value: bool = False,
|
| 418 |
+
throw_on_missing_key: bool = False,
|
| 419 |
+
) -> Union[Optional[Node], List[Optional[Node]]]:
|
| 420 |
+
...
|
| 421 |
+
|
| 422 |
+
@abstractmethod
|
| 423 |
+
def _get_node(
|
| 424 |
+
self,
|
| 425 |
+
key: Any,
|
| 426 |
+
validate_access: bool = True,
|
| 427 |
+
validate_key: bool = True,
|
| 428 |
+
throw_on_missing_value: bool = False,
|
| 429 |
+
throw_on_missing_key: bool = False,
|
| 430 |
+
) -> Union[Optional[Node], List[Optional[Node]]]:
|
| 431 |
+
...
|
| 432 |
+
|
| 433 |
+
@abstractmethod
|
| 434 |
+
def __delitem__(self, key: Any) -> None:
|
| 435 |
+
...
|
| 436 |
+
|
| 437 |
+
@abstractmethod
|
| 438 |
+
def __setitem__(self, key: Any, value: Any) -> None:
|
| 439 |
+
...
|
| 440 |
+
|
| 441 |
+
@abstractmethod
|
| 442 |
+
def __iter__(self) -> Iterator[Any]:
|
| 443 |
+
...
|
| 444 |
+
|
| 445 |
+
@abstractmethod
|
| 446 |
+
def __getitem__(self, key_or_index: Any) -> Any:
|
| 447 |
+
...
|
| 448 |
+
|
| 449 |
+
def _resolve_key_and_root(self, key: str) -> Tuple["Container", str]:
|
| 450 |
+
orig = key
|
| 451 |
+
if not key.startswith("."):
|
| 452 |
+
return self._get_root(), key
|
| 453 |
+
else:
|
| 454 |
+
root: Optional[Container] = self
|
| 455 |
+
assert key.startswith(".")
|
| 456 |
+
while True:
|
| 457 |
+
assert root is not None
|
| 458 |
+
key = key[1:]
|
| 459 |
+
if not key.startswith("."):
|
| 460 |
+
break
|
| 461 |
+
root = root._get_parent_container()
|
| 462 |
+
if root is None:
|
| 463 |
+
raise ConfigKeyError(f"Error resolving key '{orig}'")
|
| 464 |
+
|
| 465 |
+
return root, key
|
| 466 |
+
|
| 467 |
+
def _select_impl(
|
| 468 |
+
self,
|
| 469 |
+
key: str,
|
| 470 |
+
throw_on_missing: bool,
|
| 471 |
+
throw_on_resolution_failure: bool,
|
| 472 |
+
memo: Optional[Set[int]] = None,
|
| 473 |
+
) -> Tuple[Optional["Container"], Optional[str], Optional[Node]]:
|
| 474 |
+
"""
|
| 475 |
+
Select a value using dot separated key sequence
|
| 476 |
+
"""
|
| 477 |
+
from .omegaconf import _select_one
|
| 478 |
+
|
| 479 |
+
if key == "":
|
| 480 |
+
return self, "", self
|
| 481 |
+
|
| 482 |
+
split = split_key(key)
|
| 483 |
+
root: Optional[Container] = self
|
| 484 |
+
for i in range(len(split) - 1):
|
| 485 |
+
if root is None:
|
| 486 |
+
break
|
| 487 |
+
|
| 488 |
+
k = split[i]
|
| 489 |
+
ret, _ = _select_one(
|
| 490 |
+
c=root,
|
| 491 |
+
key=k,
|
| 492 |
+
throw_on_missing=throw_on_missing,
|
| 493 |
+
throw_on_type_error=throw_on_resolution_failure,
|
| 494 |
+
)
|
| 495 |
+
if isinstance(ret, Node):
|
| 496 |
+
ret = ret._maybe_dereference_node(
|
| 497 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 498 |
+
memo=memo,
|
| 499 |
+
)
|
| 500 |
+
|
| 501 |
+
if ret is not None and not isinstance(ret, Container):
|
| 502 |
+
parent_key = ".".join(split[0 : i + 1])
|
| 503 |
+
child_key = split[i + 1]
|
| 504 |
+
raise ConfigTypeError(
|
| 505 |
+
f"Error trying to access {key}: node `{parent_key}` "
|
| 506 |
+
f"is not a container and thus cannot contain `{child_key}`"
|
| 507 |
+
)
|
| 508 |
+
root = ret
|
| 509 |
+
|
| 510 |
+
if root is None:
|
| 511 |
+
return None, None, None
|
| 512 |
+
|
| 513 |
+
last_key = split[-1]
|
| 514 |
+
value, _ = _select_one(
|
| 515 |
+
c=root,
|
| 516 |
+
key=last_key,
|
| 517 |
+
throw_on_missing=throw_on_missing,
|
| 518 |
+
throw_on_type_error=throw_on_resolution_failure,
|
| 519 |
+
)
|
| 520 |
+
if value is None:
|
| 521 |
+
return root, last_key, None
|
| 522 |
+
|
| 523 |
+
if memo is not None:
|
| 524 |
+
vid = id(value)
|
| 525 |
+
if vid in memo:
|
| 526 |
+
raise InterpolationResolutionError("Recursive interpolation detected")
|
| 527 |
+
# push to memo "stack"
|
| 528 |
+
memo.add(vid)
|
| 529 |
+
|
| 530 |
+
try:
|
| 531 |
+
value = root._maybe_resolve_interpolation(
|
| 532 |
+
parent=root,
|
| 533 |
+
key=last_key,
|
| 534 |
+
value=value,
|
| 535 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 536 |
+
memo=memo,
|
| 537 |
+
)
|
| 538 |
+
finally:
|
| 539 |
+
if memo is not None:
|
| 540 |
+
# pop from memo "stack"
|
| 541 |
+
memo.remove(vid)
|
| 542 |
+
|
| 543 |
+
return root, last_key, value
|
| 544 |
+
|
| 545 |
+
def _resolve_interpolation_from_parse_tree(
|
| 546 |
+
self,
|
| 547 |
+
parent: Optional["Container"],
|
| 548 |
+
value: "Node",
|
| 549 |
+
key: Any,
|
| 550 |
+
parse_tree: OmegaConfGrammarParser.ConfigValueContext,
|
| 551 |
+
throw_on_resolution_failure: bool,
|
| 552 |
+
memo: Optional[Set[int]],
|
| 553 |
+
) -> Optional["Node"]:
|
| 554 |
+
"""
|
| 555 |
+
Resolve an interpolation.
|
| 556 |
+
|
| 557 |
+
This happens in two steps:
|
| 558 |
+
1. The parse tree is visited, which outputs either a `Node` (e.g.,
|
| 559 |
+
for node interpolations "${foo}"), a string (e.g., for string
|
| 560 |
+
interpolations "hello ${name}", or any other arbitrary value
|
| 561 |
+
(e.g., or custom interpolations "${foo:bar}").
|
| 562 |
+
2. This output is potentially validated and converted when the node
|
| 563 |
+
being resolved (`value`) is typed.
|
| 564 |
+
|
| 565 |
+
If an error occurs in one of the above steps, an `InterpolationResolutionError`
|
| 566 |
+
(or a subclass of it) is raised, *unless* `throw_on_resolution_failure` is set
|
| 567 |
+
to `False` (in which case the return value is `None`).
|
| 568 |
+
|
| 569 |
+
:param parent: Parent of the node being resolved.
|
| 570 |
+
:param value: Node being resolved.
|
| 571 |
+
:param key: The associated key in the parent.
|
| 572 |
+
:param parse_tree: The parse tree as obtained from `grammar_parser.parse()`.
|
| 573 |
+
:param throw_on_resolution_failure: If `False`, then exceptions raised during
|
| 574 |
+
the resolution of the interpolation are silenced, and instead `None` is
|
| 575 |
+
returned.
|
| 576 |
+
|
| 577 |
+
:return: A `Node` that contains the interpolation result. This may be an existing
|
| 578 |
+
node in the config (in the case of a node interpolation "${foo}"), or a new
|
| 579 |
+
node that is created to wrap the interpolated value. It is `None` if and only if
|
| 580 |
+
`throw_on_resolution_failure` is `False` and an error occurs during resolution.
|
| 581 |
+
"""
|
| 582 |
+
|
| 583 |
+
try:
|
| 584 |
+
resolved = self.resolve_parse_tree(
|
| 585 |
+
parse_tree=parse_tree, node=value, key=key, memo=memo
|
| 586 |
+
)
|
| 587 |
+
except InterpolationResolutionError:
|
| 588 |
+
if throw_on_resolution_failure:
|
| 589 |
+
raise
|
| 590 |
+
return None
|
| 591 |
+
|
| 592 |
+
return self._validate_and_convert_interpolation_result(
|
| 593 |
+
parent=parent,
|
| 594 |
+
value=value,
|
| 595 |
+
key=key,
|
| 596 |
+
resolved=resolved,
|
| 597 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 598 |
+
)
|
| 599 |
+
|
| 600 |
+
def _validate_and_convert_interpolation_result(
|
| 601 |
+
self,
|
| 602 |
+
parent: Optional["Container"],
|
| 603 |
+
value: "Node",
|
| 604 |
+
key: Any,
|
| 605 |
+
resolved: Any,
|
| 606 |
+
throw_on_resolution_failure: bool,
|
| 607 |
+
) -> Optional["Node"]:
|
| 608 |
+
from .nodes import AnyNode, InterpolationResultNode, ValueNode
|
| 609 |
+
|
| 610 |
+
# If the output is not a Node already (e.g., because it is the output of a
|
| 611 |
+
# custom resolver), then we will need to wrap it within a Node.
|
| 612 |
+
must_wrap = not isinstance(resolved, Node)
|
| 613 |
+
|
| 614 |
+
# If the node is typed, validate (and possibly convert) the result.
|
| 615 |
+
if isinstance(value, ValueNode) and not isinstance(value, AnyNode):
|
| 616 |
+
res_value = _get_value(resolved)
|
| 617 |
+
try:
|
| 618 |
+
conv_value = value.validate_and_convert(res_value)
|
| 619 |
+
except ValidationError as e:
|
| 620 |
+
if throw_on_resolution_failure:
|
| 621 |
+
self._format_and_raise(
|
| 622 |
+
key=key,
|
| 623 |
+
value=res_value,
|
| 624 |
+
cause=e,
|
| 625 |
+
msg=f"While dereferencing interpolation '{value}': {e}",
|
| 626 |
+
type_override=InterpolationValidationError,
|
| 627 |
+
)
|
| 628 |
+
return None
|
| 629 |
+
|
| 630 |
+
# If the converted value is of the same type, it means that no conversion
|
| 631 |
+
# was actually needed. As a result, we can keep the original `resolved`
|
| 632 |
+
# (and otherwise, the converted value must be wrapped into a new node).
|
| 633 |
+
if type(conv_value) != type(res_value):
|
| 634 |
+
must_wrap = True
|
| 635 |
+
resolved = conv_value
|
| 636 |
+
|
| 637 |
+
if must_wrap:
|
| 638 |
+
return InterpolationResultNode(value=resolved, key=key, parent=parent)
|
| 639 |
+
else:
|
| 640 |
+
assert isinstance(resolved, Node)
|
| 641 |
+
return resolved
|
| 642 |
+
|
| 643 |
+
def _validate_not_dereferencing_to_parent(self, node: Node, target: Node) -> None:
|
| 644 |
+
parent: Optional[Node] = node
|
| 645 |
+
while parent is not None:
|
| 646 |
+
if parent is target:
|
| 647 |
+
raise InterpolationResolutionError(
|
| 648 |
+
"Interpolation to parent node detected"
|
| 649 |
+
)
|
| 650 |
+
parent = parent._get_parent()
|
| 651 |
+
|
| 652 |
+
def _resolve_node_interpolation(
|
| 653 |
+
self, inter_key: str, memo: Optional[Set[int]]
|
| 654 |
+
) -> "Node":
|
| 655 |
+
"""A node interpolation is of the form `${foo.bar}`"""
|
| 656 |
+
try:
|
| 657 |
+
root_node, inter_key = self._resolve_key_and_root(inter_key)
|
| 658 |
+
except ConfigKeyError as exc:
|
| 659 |
+
raise InterpolationKeyError(
|
| 660 |
+
f"ConfigKeyError while resolving interpolation: {exc}"
|
| 661 |
+
).with_traceback(sys.exc_info()[2])
|
| 662 |
+
|
| 663 |
+
try:
|
| 664 |
+
parent, last_key, value = root_node._select_impl(
|
| 665 |
+
inter_key,
|
| 666 |
+
throw_on_missing=True,
|
| 667 |
+
throw_on_resolution_failure=True,
|
| 668 |
+
memo=memo,
|
| 669 |
+
)
|
| 670 |
+
except MissingMandatoryValue as exc:
|
| 671 |
+
raise InterpolationToMissingValueError(
|
| 672 |
+
f"MissingMandatoryValue while resolving interpolation: {exc}"
|
| 673 |
+
).with_traceback(sys.exc_info()[2])
|
| 674 |
+
|
| 675 |
+
if parent is None or value is None:
|
| 676 |
+
raise InterpolationKeyError(f"Interpolation key '{inter_key}' not found")
|
| 677 |
+
else:
|
| 678 |
+
self._validate_not_dereferencing_to_parent(node=self, target=value)
|
| 679 |
+
return value
|
| 680 |
+
|
| 681 |
+
def _evaluate_custom_resolver(
|
| 682 |
+
self,
|
| 683 |
+
key: Any,
|
| 684 |
+
node: Node,
|
| 685 |
+
inter_type: str,
|
| 686 |
+
inter_args: Tuple[Any, ...],
|
| 687 |
+
inter_args_str: Tuple[str, ...],
|
| 688 |
+
) -> Any:
|
| 689 |
+
from omegaconf import OmegaConf
|
| 690 |
+
|
| 691 |
+
resolver = OmegaConf._get_resolver(inter_type)
|
| 692 |
+
if resolver is not None:
|
| 693 |
+
root_node = self._get_root()
|
| 694 |
+
return resolver(
|
| 695 |
+
root_node,
|
| 696 |
+
self,
|
| 697 |
+
node,
|
| 698 |
+
inter_args,
|
| 699 |
+
inter_args_str,
|
| 700 |
+
)
|
| 701 |
+
else:
|
| 702 |
+
raise UnsupportedInterpolationType(
|
| 703 |
+
f"Unsupported interpolation type {inter_type}"
|
| 704 |
+
)
|
| 705 |
+
|
| 706 |
+
def _maybe_resolve_interpolation(
|
| 707 |
+
self,
|
| 708 |
+
parent: Optional["Container"],
|
| 709 |
+
key: Any,
|
| 710 |
+
value: Node,
|
| 711 |
+
throw_on_resolution_failure: bool,
|
| 712 |
+
memo: Optional[Set[int]] = None,
|
| 713 |
+
) -> Optional[Node]:
|
| 714 |
+
value_kind = get_value_kind(value)
|
| 715 |
+
if value_kind != ValueKind.INTERPOLATION:
|
| 716 |
+
return value
|
| 717 |
+
|
| 718 |
+
parse_tree = parse(_get_value(value))
|
| 719 |
+
return self._resolve_interpolation_from_parse_tree(
|
| 720 |
+
parent=parent,
|
| 721 |
+
value=value,
|
| 722 |
+
key=key,
|
| 723 |
+
parse_tree=parse_tree,
|
| 724 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 725 |
+
memo=memo if memo is not None else set(),
|
| 726 |
+
)
|
| 727 |
+
|
| 728 |
+
def resolve_parse_tree(
|
| 729 |
+
self,
|
| 730 |
+
parse_tree: ParserRuleContext,
|
| 731 |
+
node: Node,
|
| 732 |
+
memo: Optional[Set[int]] = None,
|
| 733 |
+
key: Optional[Any] = None,
|
| 734 |
+
) -> Any:
|
| 735 |
+
"""
|
| 736 |
+
Resolve a given parse tree into its value.
|
| 737 |
+
|
| 738 |
+
We make no assumption here on the type of the tree's root, so that the
|
| 739 |
+
return value may be of any type.
|
| 740 |
+
"""
|
| 741 |
+
|
| 742 |
+
def node_interpolation_callback(
|
| 743 |
+
inter_key: str, memo: Optional[Set[int]]
|
| 744 |
+
) -> Optional["Node"]:
|
| 745 |
+
return self._resolve_node_interpolation(inter_key=inter_key, memo=memo)
|
| 746 |
+
|
| 747 |
+
def resolver_interpolation_callback(
|
| 748 |
+
name: str, args: Tuple[Any, ...], args_str: Tuple[str, ...]
|
| 749 |
+
) -> Any:
|
| 750 |
+
return self._evaluate_custom_resolver(
|
| 751 |
+
key=key,
|
| 752 |
+
node=node,
|
| 753 |
+
inter_type=name,
|
| 754 |
+
inter_args=args,
|
| 755 |
+
inter_args_str=args_str,
|
| 756 |
+
)
|
| 757 |
+
|
| 758 |
+
visitor = GrammarVisitor(
|
| 759 |
+
node_interpolation_callback=node_interpolation_callback,
|
| 760 |
+
resolver_interpolation_callback=resolver_interpolation_callback,
|
| 761 |
+
memo=memo,
|
| 762 |
+
)
|
| 763 |
+
try:
|
| 764 |
+
return visitor.visit(parse_tree)
|
| 765 |
+
except InterpolationResolutionError:
|
| 766 |
+
raise
|
| 767 |
+
except Exception as exc:
|
| 768 |
+
# Other kinds of exceptions are wrapped in an `InterpolationResolutionError`.
|
| 769 |
+
raise InterpolationResolutionError(
|
| 770 |
+
f"{type(exc).__name__} raised while resolving interpolation: {exc}"
|
| 771 |
+
).with_traceback(sys.exc_info()[2])
|
| 772 |
+
|
| 773 |
+
def _invalidate_flags_cache(self) -> None:
|
| 774 |
+
from .dictconfig import DictConfig
|
| 775 |
+
from .listconfig import ListConfig
|
| 776 |
+
|
| 777 |
+
# invalidate subtree cache only if the cache is initialized in this node.
|
| 778 |
+
|
| 779 |
+
if self.__dict__["_flags_cache"] is not None:
|
| 780 |
+
self.__dict__["_flags_cache"] = None
|
| 781 |
+
if isinstance(self, DictConfig):
|
| 782 |
+
content = self.__dict__["_content"]
|
| 783 |
+
if isinstance(content, dict):
|
| 784 |
+
for value in self.__dict__["_content"].values():
|
| 785 |
+
value._invalidate_flags_cache()
|
| 786 |
+
elif isinstance(self, ListConfig):
|
| 787 |
+
content = self.__dict__["_content"]
|
| 788 |
+
if isinstance(content, list):
|
| 789 |
+
for item in self.__dict__["_content"]:
|
| 790 |
+
item._invalidate_flags_cache()
|
| 791 |
+
|
| 792 |
+
|
| 793 |
+
class SCMode(Enum):
|
| 794 |
+
DICT = 1 # Convert to plain dict
|
| 795 |
+
DICT_CONFIG = 2 # Keep as OmegaConf DictConfig
|
| 796 |
+
INSTANTIATE = 3 # Create a dataclass or attrs class instance
|
| 797 |
+
|
| 798 |
+
|
| 799 |
+
class UnionNode(Box):
|
| 800 |
+
"""
|
| 801 |
+
This class handles Union type hints. The `_content` attribute is either a
|
| 802 |
+
child node that is compatible with the given Union ref_type, or it is a
|
| 803 |
+
special value (None or MISSING or interpolation).
|
| 804 |
+
|
| 805 |
+
Much of the logic for e.g. value assignment and type validation is
|
| 806 |
+
delegated to the child node. As such, UnionNode functions as a
|
| 807 |
+
"pass-through" node. User apps and downstream libraries should not need to
|
| 808 |
+
know about UnionNode (assuming they only use OmegaConf's public API).
|
| 809 |
+
"""
|
| 810 |
+
|
| 811 |
+
_parent: Optional[Container]
|
| 812 |
+
_content: Union[Node, None, str]
|
| 813 |
+
|
| 814 |
+
def __init__(
|
| 815 |
+
self,
|
| 816 |
+
content: Any,
|
| 817 |
+
ref_type: Any,
|
| 818 |
+
is_optional: bool = True,
|
| 819 |
+
key: Any = None,
|
| 820 |
+
parent: Optional[Box] = None,
|
| 821 |
+
) -> None:
|
| 822 |
+
try:
|
| 823 |
+
if not is_union_annotation(ref_type): # pragma: no cover
|
| 824 |
+
msg = (
|
| 825 |
+
f"UnionNode got unexpected ref_type {ref_type}. Please file a bug"
|
| 826 |
+
+ " report at https://github.com/omry/omegaconf/issues"
|
| 827 |
+
)
|
| 828 |
+
raise AssertionError(msg)
|
| 829 |
+
if not isinstance(parent, (Container, NoneType)):
|
| 830 |
+
raise ConfigTypeError("Parent type is not omegaconf.Container")
|
| 831 |
+
super().__init__(
|
| 832 |
+
parent=parent,
|
| 833 |
+
metadata=Metadata(
|
| 834 |
+
ref_type=ref_type,
|
| 835 |
+
object_type=None,
|
| 836 |
+
optional=is_optional,
|
| 837 |
+
key=key,
|
| 838 |
+
flags={"convert": False},
|
| 839 |
+
),
|
| 840 |
+
)
|
| 841 |
+
self._set_value(content)
|
| 842 |
+
except Exception as ex:
|
| 843 |
+
format_and_raise(node=None, key=key, value=content, msg=str(ex), cause=ex)
|
| 844 |
+
|
| 845 |
+
def _get_full_key(self, key: Optional[Union[DictKeyType, int]]) -> str:
|
| 846 |
+
parent = self._get_parent()
|
| 847 |
+
if parent is None:
|
| 848 |
+
if self._metadata.key is None:
|
| 849 |
+
return ""
|
| 850 |
+
else:
|
| 851 |
+
return str(self._metadata.key)
|
| 852 |
+
else:
|
| 853 |
+
return parent._get_full_key(self._metadata.key)
|
| 854 |
+
|
| 855 |
+
def __eq__(self, other: Any) -> bool:
|
| 856 |
+
content = self.__dict__["_content"]
|
| 857 |
+
if isinstance(content, Node):
|
| 858 |
+
ret = content.__eq__(other)
|
| 859 |
+
elif isinstance(other, Node):
|
| 860 |
+
ret = other.__eq__(content)
|
| 861 |
+
else:
|
| 862 |
+
ret = content.__eq__(other)
|
| 863 |
+
assert isinstance(ret, (bool, type(NotImplemented)))
|
| 864 |
+
return ret
|
| 865 |
+
|
| 866 |
+
def __ne__(self, other: Any) -> bool:
|
| 867 |
+
x = self.__eq__(other)
|
| 868 |
+
if x is NotImplemented:
|
| 869 |
+
return NotImplemented
|
| 870 |
+
return not x
|
| 871 |
+
|
| 872 |
+
def __hash__(self) -> int:
|
| 873 |
+
return hash(self.__dict__["_content"])
|
| 874 |
+
|
| 875 |
+
def _value(self) -> Union[Node, None, str]:
|
| 876 |
+
content = self.__dict__["_content"]
|
| 877 |
+
assert isinstance(content, (Node, NoneType, str))
|
| 878 |
+
return content
|
| 879 |
+
|
| 880 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 881 |
+
previous_content = self.__dict__["_content"]
|
| 882 |
+
previous_metadata = self.__dict__["_metadata"]
|
| 883 |
+
try:
|
| 884 |
+
self._set_value_impl(value, flags)
|
| 885 |
+
except Exception as e:
|
| 886 |
+
self.__dict__["_content"] = previous_content
|
| 887 |
+
self.__dict__["_metadata"] = previous_metadata
|
| 888 |
+
raise e
|
| 889 |
+
|
| 890 |
+
def _set_value_impl(
|
| 891 |
+
self, value: Any, flags: Optional[Dict[str, bool]] = None
|
| 892 |
+
) -> None:
|
| 893 |
+
from omegaconf.omegaconf import _node_wrap
|
| 894 |
+
|
| 895 |
+
ref_type = self._metadata.ref_type
|
| 896 |
+
type_hint = self._metadata.type_hint
|
| 897 |
+
|
| 898 |
+
value = _get_value(value)
|
| 899 |
+
if _is_special(value):
|
| 900 |
+
assert isinstance(value, (str, NoneType))
|
| 901 |
+
if value is None:
|
| 902 |
+
if not self._is_optional():
|
| 903 |
+
raise ValidationError(
|
| 904 |
+
f"Value '$VALUE' is incompatible with type hint '{type_str(type_hint)}'"
|
| 905 |
+
)
|
| 906 |
+
self.__dict__["_content"] = value
|
| 907 |
+
elif isinstance(value, Container):
|
| 908 |
+
raise ValidationError(
|
| 909 |
+
f"Cannot assign container '$VALUE' of type '$VALUE_TYPE' to {type_str(type_hint)}"
|
| 910 |
+
)
|
| 911 |
+
else:
|
| 912 |
+
for candidate_ref_type in ref_type.__args__:
|
| 913 |
+
try:
|
| 914 |
+
self.__dict__["_content"] = _node_wrap(
|
| 915 |
+
value=value,
|
| 916 |
+
ref_type=candidate_ref_type,
|
| 917 |
+
is_optional=False,
|
| 918 |
+
key=None,
|
| 919 |
+
parent=self,
|
| 920 |
+
)
|
| 921 |
+
break
|
| 922 |
+
except ValidationError:
|
| 923 |
+
continue
|
| 924 |
+
else:
|
| 925 |
+
raise ValidationError(
|
| 926 |
+
f"Value '$VALUE' of type '$VALUE_TYPE' is incompatible with type hint '{type_str(type_hint)}'"
|
| 927 |
+
)
|
| 928 |
+
|
| 929 |
+
def _is_optional(self) -> bool:
|
| 930 |
+
return self.__dict__["_metadata"].optional is True
|
| 931 |
+
|
| 932 |
+
def _is_interpolation(self) -> bool:
|
| 933 |
+
return _is_interpolation(self.__dict__["_content"])
|
| 934 |
+
|
| 935 |
+
def __str__(self) -> str:
|
| 936 |
+
return str(self.__dict__["_content"])
|
| 937 |
+
|
| 938 |
+
def __repr__(self) -> str:
|
| 939 |
+
return repr(self.__dict__["_content"])
|
| 940 |
+
|
| 941 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "UnionNode":
|
| 942 |
+
res = object.__new__(type(self))
|
| 943 |
+
for key, value in self.__dict__.items():
|
| 944 |
+
if key not in ("_content", "_parent"):
|
| 945 |
+
res.__dict__[key] = copy.deepcopy(value, memo=memo)
|
| 946 |
+
|
| 947 |
+
src_content = self.__dict__["_content"]
|
| 948 |
+
if isinstance(src_content, Node):
|
| 949 |
+
old_parent = src_content.__dict__["_parent"]
|
| 950 |
+
try:
|
| 951 |
+
src_content.__dict__["_parent"] = None
|
| 952 |
+
content_copy = copy.deepcopy(src_content, memo=memo)
|
| 953 |
+
content_copy.__dict__["_parent"] = res
|
| 954 |
+
finally:
|
| 955 |
+
src_content.__dict__["_parent"] = old_parent
|
| 956 |
+
else:
|
| 957 |
+
# None and strings can be assigned as is
|
| 958 |
+
content_copy = src_content
|
| 959 |
+
|
| 960 |
+
res.__dict__["_content"] = content_copy
|
| 961 |
+
res.__dict__["_parent"] = self.__dict__["_parent"]
|
| 962 |
+
return res
|
lib/python3.12/site-packages/omegaconf/basecontainer.py
ADDED
|
@@ -0,0 +1,916 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import sys
|
| 3 |
+
from abc import ABC, abstractmethod
|
| 4 |
+
from enum import Enum
|
| 5 |
+
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Tuple, Union
|
| 6 |
+
|
| 7 |
+
import yaml
|
| 8 |
+
|
| 9 |
+
from ._utils import (
|
| 10 |
+
_DEFAULT_MARKER_,
|
| 11 |
+
ValueKind,
|
| 12 |
+
_ensure_container,
|
| 13 |
+
_get_value,
|
| 14 |
+
_is_interpolation,
|
| 15 |
+
_is_missing_value,
|
| 16 |
+
_is_none,
|
| 17 |
+
_is_special,
|
| 18 |
+
_resolve_optional,
|
| 19 |
+
get_structured_config_data,
|
| 20 |
+
get_type_hint,
|
| 21 |
+
get_value_kind,
|
| 22 |
+
get_yaml_loader,
|
| 23 |
+
is_container_annotation,
|
| 24 |
+
is_dict_annotation,
|
| 25 |
+
is_list_annotation,
|
| 26 |
+
is_primitive_dict,
|
| 27 |
+
is_primitive_type_annotation,
|
| 28 |
+
is_structured_config,
|
| 29 |
+
is_tuple_annotation,
|
| 30 |
+
is_union_annotation,
|
| 31 |
+
)
|
| 32 |
+
from .base import (
|
| 33 |
+
Box,
|
| 34 |
+
Container,
|
| 35 |
+
ContainerMetadata,
|
| 36 |
+
DictKeyType,
|
| 37 |
+
Node,
|
| 38 |
+
SCMode,
|
| 39 |
+
UnionNode,
|
| 40 |
+
)
|
| 41 |
+
from .errors import (
|
| 42 |
+
ConfigCycleDetectedException,
|
| 43 |
+
ConfigTypeError,
|
| 44 |
+
InterpolationResolutionError,
|
| 45 |
+
KeyValidationError,
|
| 46 |
+
MissingMandatoryValue,
|
| 47 |
+
OmegaConfBaseException,
|
| 48 |
+
ReadonlyConfigError,
|
| 49 |
+
ValidationError,
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
if TYPE_CHECKING:
|
| 53 |
+
from .dictconfig import DictConfig # pragma: no cover
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class BaseContainer(Container, ABC):
|
| 57 |
+
_resolvers: ClassVar[Dict[str, Any]] = {}
|
| 58 |
+
|
| 59 |
+
def __init__(self, parent: Optional[Box], metadata: ContainerMetadata):
|
| 60 |
+
if not (parent is None or isinstance(parent, Box)):
|
| 61 |
+
raise ConfigTypeError("Parent type is not omegaconf.Box")
|
| 62 |
+
super().__init__(parent=parent, metadata=metadata)
|
| 63 |
+
|
| 64 |
+
def _get_child(
|
| 65 |
+
self,
|
| 66 |
+
key: Any,
|
| 67 |
+
validate_access: bool = True,
|
| 68 |
+
validate_key: bool = True,
|
| 69 |
+
throw_on_missing_value: bool = False,
|
| 70 |
+
throw_on_missing_key: bool = False,
|
| 71 |
+
) -> Union[Optional[Node], List[Optional[Node]]]:
|
| 72 |
+
"""Like _get_node, passing through to the nearest concrete Node."""
|
| 73 |
+
child = self._get_node(
|
| 74 |
+
key=key,
|
| 75 |
+
validate_access=validate_access,
|
| 76 |
+
validate_key=validate_key,
|
| 77 |
+
throw_on_missing_value=throw_on_missing_value,
|
| 78 |
+
throw_on_missing_key=throw_on_missing_key,
|
| 79 |
+
)
|
| 80 |
+
if isinstance(child, UnionNode) and not _is_special(child):
|
| 81 |
+
value = child._value()
|
| 82 |
+
assert isinstance(value, Node) and not isinstance(value, UnionNode)
|
| 83 |
+
child = value
|
| 84 |
+
return child
|
| 85 |
+
|
| 86 |
+
def _resolve_with_default(
|
| 87 |
+
self,
|
| 88 |
+
key: Union[DictKeyType, int],
|
| 89 |
+
value: Node,
|
| 90 |
+
default_value: Any = _DEFAULT_MARKER_,
|
| 91 |
+
) -> Any:
|
| 92 |
+
"""returns the value with the specified key, like obj.key and obj['key']"""
|
| 93 |
+
if _is_missing_value(value):
|
| 94 |
+
if default_value is not _DEFAULT_MARKER_:
|
| 95 |
+
return default_value
|
| 96 |
+
raise MissingMandatoryValue("Missing mandatory value: $FULL_KEY")
|
| 97 |
+
|
| 98 |
+
resolved_node = self._maybe_resolve_interpolation(
|
| 99 |
+
parent=self,
|
| 100 |
+
key=key,
|
| 101 |
+
value=value,
|
| 102 |
+
throw_on_resolution_failure=True,
|
| 103 |
+
)
|
| 104 |
+
|
| 105 |
+
return _get_value(resolved_node)
|
| 106 |
+
|
| 107 |
+
def __str__(self) -> str:
|
| 108 |
+
return self.__repr__()
|
| 109 |
+
|
| 110 |
+
def __repr__(self) -> str:
|
| 111 |
+
if self.__dict__["_content"] is None:
|
| 112 |
+
return "None"
|
| 113 |
+
elif self._is_interpolation() or self._is_missing():
|
| 114 |
+
v = self.__dict__["_content"]
|
| 115 |
+
return f"'{v}'"
|
| 116 |
+
else:
|
| 117 |
+
return self.__dict__["_content"].__repr__() # type: ignore
|
| 118 |
+
|
| 119 |
+
# Support pickle
|
| 120 |
+
def __getstate__(self) -> Dict[str, Any]:
|
| 121 |
+
dict_copy = copy.copy(self.__dict__)
|
| 122 |
+
|
| 123 |
+
# no need to serialize the flags cache, it can be re-constructed later
|
| 124 |
+
dict_copy.pop("_flags_cache", None)
|
| 125 |
+
|
| 126 |
+
dict_copy["_metadata"] = copy.copy(dict_copy["_metadata"])
|
| 127 |
+
ref_type = self._metadata.ref_type
|
| 128 |
+
if is_container_annotation(ref_type):
|
| 129 |
+
if is_dict_annotation(ref_type):
|
| 130 |
+
dict_copy["_metadata"].ref_type = Dict
|
| 131 |
+
elif is_list_annotation(ref_type):
|
| 132 |
+
dict_copy["_metadata"].ref_type = List
|
| 133 |
+
else:
|
| 134 |
+
assert False
|
| 135 |
+
if sys.version_info < (3, 7): # pragma: no cover
|
| 136 |
+
element_type = self._metadata.element_type
|
| 137 |
+
if is_union_annotation(element_type):
|
| 138 |
+
raise OmegaConfBaseException(
|
| 139 |
+
"Serializing structured configs with `Union` element type requires python >= 3.7"
|
| 140 |
+
)
|
| 141 |
+
return dict_copy
|
| 142 |
+
|
| 143 |
+
# Support pickle
|
| 144 |
+
def __setstate__(self, d: Dict[str, Any]) -> None:
|
| 145 |
+
from omegaconf import DictConfig
|
| 146 |
+
from omegaconf._utils import is_generic_dict, is_generic_list
|
| 147 |
+
|
| 148 |
+
if isinstance(self, DictConfig):
|
| 149 |
+
key_type = d["_metadata"].key_type
|
| 150 |
+
|
| 151 |
+
# backward compatibility to load OmegaConf 2.0 configs
|
| 152 |
+
if key_type is None:
|
| 153 |
+
key_type = Any
|
| 154 |
+
d["_metadata"].key_type = key_type
|
| 155 |
+
|
| 156 |
+
element_type = d["_metadata"].element_type
|
| 157 |
+
|
| 158 |
+
# backward compatibility to load OmegaConf 2.0 configs
|
| 159 |
+
if element_type is None:
|
| 160 |
+
element_type = Any
|
| 161 |
+
d["_metadata"].element_type = element_type
|
| 162 |
+
|
| 163 |
+
ref_type = d["_metadata"].ref_type
|
| 164 |
+
if is_container_annotation(ref_type):
|
| 165 |
+
if is_generic_dict(ref_type):
|
| 166 |
+
d["_metadata"].ref_type = Dict[key_type, element_type] # type: ignore
|
| 167 |
+
elif is_generic_list(ref_type):
|
| 168 |
+
d["_metadata"].ref_type = List[element_type] # type: ignore
|
| 169 |
+
else:
|
| 170 |
+
assert False
|
| 171 |
+
|
| 172 |
+
d["_flags_cache"] = None
|
| 173 |
+
self.__dict__.update(d)
|
| 174 |
+
|
| 175 |
+
@abstractmethod
|
| 176 |
+
def __delitem__(self, key: Any) -> None:
|
| 177 |
+
...
|
| 178 |
+
|
| 179 |
+
def __len__(self) -> int:
|
| 180 |
+
if self._is_none() or self._is_missing() or self._is_interpolation():
|
| 181 |
+
return 0
|
| 182 |
+
content = self.__dict__["_content"]
|
| 183 |
+
return len(content)
|
| 184 |
+
|
| 185 |
+
def merge_with_cli(self) -> None:
|
| 186 |
+
args_list = sys.argv[1:]
|
| 187 |
+
self.merge_with_dotlist(args_list)
|
| 188 |
+
|
| 189 |
+
def merge_with_dotlist(self, dotlist: List[str]) -> None:
|
| 190 |
+
from omegaconf import OmegaConf
|
| 191 |
+
|
| 192 |
+
def fail() -> None:
|
| 193 |
+
raise ValueError("Input list must be a list or a tuple of strings")
|
| 194 |
+
|
| 195 |
+
if not isinstance(dotlist, (list, tuple)):
|
| 196 |
+
fail()
|
| 197 |
+
|
| 198 |
+
for arg in dotlist:
|
| 199 |
+
if not isinstance(arg, str):
|
| 200 |
+
fail()
|
| 201 |
+
|
| 202 |
+
idx = arg.find("=")
|
| 203 |
+
if idx == -1:
|
| 204 |
+
key = arg
|
| 205 |
+
value = None
|
| 206 |
+
else:
|
| 207 |
+
key = arg[0:idx]
|
| 208 |
+
value = arg[idx + 1 :]
|
| 209 |
+
value = yaml.load(value, Loader=get_yaml_loader())
|
| 210 |
+
|
| 211 |
+
OmegaConf.update(self, key, value)
|
| 212 |
+
|
| 213 |
+
def is_empty(self) -> bool:
|
| 214 |
+
"""return true if config is empty"""
|
| 215 |
+
return len(self.__dict__["_content"]) == 0
|
| 216 |
+
|
| 217 |
+
@staticmethod
|
| 218 |
+
def _to_content(
|
| 219 |
+
conf: Container,
|
| 220 |
+
resolve: bool,
|
| 221 |
+
throw_on_missing: bool,
|
| 222 |
+
enum_to_str: bool = False,
|
| 223 |
+
structured_config_mode: SCMode = SCMode.DICT,
|
| 224 |
+
) -> Union[None, Any, str, Dict[DictKeyType, Any], List[Any]]:
|
| 225 |
+
from omegaconf import MISSING, DictConfig, ListConfig
|
| 226 |
+
|
| 227 |
+
def convert(val: Node) -> Any:
|
| 228 |
+
value = val._value()
|
| 229 |
+
if enum_to_str and isinstance(value, Enum):
|
| 230 |
+
value = f"{value.name}"
|
| 231 |
+
|
| 232 |
+
return value
|
| 233 |
+
|
| 234 |
+
def get_node_value(key: Union[DictKeyType, int]) -> Any:
|
| 235 |
+
try:
|
| 236 |
+
node = conf._get_child(key, throw_on_missing_value=throw_on_missing)
|
| 237 |
+
except MissingMandatoryValue as e:
|
| 238 |
+
conf._format_and_raise(key=key, value=None, cause=e)
|
| 239 |
+
assert isinstance(node, Node)
|
| 240 |
+
if resolve:
|
| 241 |
+
try:
|
| 242 |
+
node = node._dereference_node()
|
| 243 |
+
except InterpolationResolutionError as e:
|
| 244 |
+
conf._format_and_raise(key=key, value=None, cause=e)
|
| 245 |
+
|
| 246 |
+
if isinstance(node, Container):
|
| 247 |
+
value = BaseContainer._to_content(
|
| 248 |
+
node,
|
| 249 |
+
resolve=resolve,
|
| 250 |
+
throw_on_missing=throw_on_missing,
|
| 251 |
+
enum_to_str=enum_to_str,
|
| 252 |
+
structured_config_mode=structured_config_mode,
|
| 253 |
+
)
|
| 254 |
+
else:
|
| 255 |
+
value = convert(node)
|
| 256 |
+
return value
|
| 257 |
+
|
| 258 |
+
if conf._is_none():
|
| 259 |
+
return None
|
| 260 |
+
elif conf._is_missing():
|
| 261 |
+
if throw_on_missing:
|
| 262 |
+
conf._format_and_raise(
|
| 263 |
+
key=None,
|
| 264 |
+
value=None,
|
| 265 |
+
cause=MissingMandatoryValue("Missing mandatory value"),
|
| 266 |
+
)
|
| 267 |
+
else:
|
| 268 |
+
return MISSING
|
| 269 |
+
elif not resolve and conf._is_interpolation():
|
| 270 |
+
inter = conf._value()
|
| 271 |
+
assert isinstance(inter, str)
|
| 272 |
+
return inter
|
| 273 |
+
|
| 274 |
+
if resolve:
|
| 275 |
+
_conf = conf._dereference_node()
|
| 276 |
+
assert isinstance(_conf, Container)
|
| 277 |
+
conf = _conf
|
| 278 |
+
|
| 279 |
+
if isinstance(conf, DictConfig):
|
| 280 |
+
if (
|
| 281 |
+
conf._metadata.object_type not in (dict, None)
|
| 282 |
+
and structured_config_mode == SCMode.DICT_CONFIG
|
| 283 |
+
):
|
| 284 |
+
return conf
|
| 285 |
+
if structured_config_mode == SCMode.INSTANTIATE and is_structured_config(
|
| 286 |
+
conf._metadata.object_type
|
| 287 |
+
):
|
| 288 |
+
return conf._to_object()
|
| 289 |
+
|
| 290 |
+
retdict: Dict[DictKeyType, Any] = {}
|
| 291 |
+
for key in conf.keys():
|
| 292 |
+
value = get_node_value(key)
|
| 293 |
+
if enum_to_str and isinstance(key, Enum):
|
| 294 |
+
key = f"{key.name}"
|
| 295 |
+
retdict[key] = value
|
| 296 |
+
return retdict
|
| 297 |
+
elif isinstance(conf, ListConfig):
|
| 298 |
+
retlist: List[Any] = []
|
| 299 |
+
for index in range(len(conf)):
|
| 300 |
+
item = get_node_value(index)
|
| 301 |
+
retlist.append(item)
|
| 302 |
+
|
| 303 |
+
return retlist
|
| 304 |
+
assert False
|
| 305 |
+
|
| 306 |
+
@staticmethod
|
| 307 |
+
def _map_merge(dest: "BaseContainer", src: "BaseContainer") -> None:
|
| 308 |
+
"""merge src into dest and return a new copy, does not modified input"""
|
| 309 |
+
from omegaconf import AnyNode, DictConfig, ValueNode
|
| 310 |
+
|
| 311 |
+
assert isinstance(dest, DictConfig)
|
| 312 |
+
assert isinstance(src, DictConfig)
|
| 313 |
+
src_type = src._metadata.object_type
|
| 314 |
+
src_ref_type = get_type_hint(src)
|
| 315 |
+
assert src_ref_type is not None
|
| 316 |
+
|
| 317 |
+
# If source DictConfig is:
|
| 318 |
+
# - None => set the destination DictConfig to None
|
| 319 |
+
# - an interpolation => set the destination DictConfig to be the same interpolation
|
| 320 |
+
if src._is_none() or src._is_interpolation():
|
| 321 |
+
dest._set_value(src._value())
|
| 322 |
+
_update_types(node=dest, ref_type=src_ref_type, object_type=src_type)
|
| 323 |
+
return
|
| 324 |
+
|
| 325 |
+
dest._validate_merge(value=src)
|
| 326 |
+
|
| 327 |
+
def expand(node: Container) -> None:
|
| 328 |
+
rt = node._metadata.ref_type
|
| 329 |
+
val: Any
|
| 330 |
+
if rt is not Any:
|
| 331 |
+
if is_dict_annotation(rt):
|
| 332 |
+
val = {}
|
| 333 |
+
elif is_list_annotation(rt) or is_tuple_annotation(rt):
|
| 334 |
+
val = []
|
| 335 |
+
else:
|
| 336 |
+
val = rt
|
| 337 |
+
elif isinstance(node, DictConfig):
|
| 338 |
+
val = {}
|
| 339 |
+
else:
|
| 340 |
+
assert False
|
| 341 |
+
|
| 342 |
+
node._set_value(val)
|
| 343 |
+
|
| 344 |
+
if (
|
| 345 |
+
src._is_missing()
|
| 346 |
+
and not dest._is_missing()
|
| 347 |
+
and is_structured_config(src_ref_type)
|
| 348 |
+
):
|
| 349 |
+
# Replace `src` with a prototype of its corresponding structured config
|
| 350 |
+
# whose fields are all missing (to avoid overwriting fields in `dest`).
|
| 351 |
+
assert src_type is None # src missing, so src's object_type should be None
|
| 352 |
+
src_type = src_ref_type
|
| 353 |
+
src = _create_structured_with_missing_fields(
|
| 354 |
+
ref_type=src_ref_type, object_type=src_type
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
if (dest._is_interpolation() or dest._is_missing()) and not src._is_missing():
|
| 358 |
+
expand(dest)
|
| 359 |
+
|
| 360 |
+
src_items = list(src) if not src._is_missing() else []
|
| 361 |
+
for key in src_items:
|
| 362 |
+
src_node = src._get_node(key, validate_access=False)
|
| 363 |
+
dest_node = dest._get_node(key, validate_access=False)
|
| 364 |
+
assert isinstance(src_node, Node)
|
| 365 |
+
assert dest_node is None or isinstance(dest_node, Node)
|
| 366 |
+
src_value = _get_value(src_node)
|
| 367 |
+
|
| 368 |
+
src_vk = get_value_kind(src_node)
|
| 369 |
+
src_node_missing = src_vk is ValueKind.MANDATORY_MISSING
|
| 370 |
+
|
| 371 |
+
if isinstance(dest_node, DictConfig):
|
| 372 |
+
dest_node._validate_merge(value=src_node)
|
| 373 |
+
|
| 374 |
+
if (
|
| 375 |
+
isinstance(dest_node, Container)
|
| 376 |
+
and dest_node._is_none()
|
| 377 |
+
and not src_node_missing
|
| 378 |
+
and not _is_none(src_node, resolve=True)
|
| 379 |
+
):
|
| 380 |
+
expand(dest_node)
|
| 381 |
+
|
| 382 |
+
if dest_node is not None and dest_node._is_interpolation():
|
| 383 |
+
target_node = dest_node._maybe_dereference_node()
|
| 384 |
+
if isinstance(target_node, Container):
|
| 385 |
+
dest[key] = target_node
|
| 386 |
+
dest_node = dest._get_node(key)
|
| 387 |
+
|
| 388 |
+
is_optional, et = _resolve_optional(dest._metadata.element_type)
|
| 389 |
+
if dest_node is None and is_structured_config(et) and not src_node_missing:
|
| 390 |
+
# merging into a new node. Use element_type as a base
|
| 391 |
+
dest[key] = DictConfig(
|
| 392 |
+
et, parent=dest, ref_type=et, is_optional=is_optional
|
| 393 |
+
)
|
| 394 |
+
dest_node = dest._get_node(key)
|
| 395 |
+
|
| 396 |
+
if dest_node is not None:
|
| 397 |
+
if isinstance(dest_node, BaseContainer):
|
| 398 |
+
if isinstance(src_node, BaseContainer):
|
| 399 |
+
dest_node._merge_with(src_node)
|
| 400 |
+
elif not src_node_missing:
|
| 401 |
+
dest.__setitem__(key, src_node)
|
| 402 |
+
else:
|
| 403 |
+
if isinstance(src_node, BaseContainer):
|
| 404 |
+
dest.__setitem__(key, src_node)
|
| 405 |
+
else:
|
| 406 |
+
assert isinstance(dest_node, (ValueNode, UnionNode))
|
| 407 |
+
assert isinstance(src_node, (ValueNode, UnionNode))
|
| 408 |
+
try:
|
| 409 |
+
if isinstance(dest_node, AnyNode):
|
| 410 |
+
if src_node_missing:
|
| 411 |
+
node = copy.copy(src_node)
|
| 412 |
+
# if src node is missing, use the value from the dest_node,
|
| 413 |
+
# but validate it against the type of the src node before assigment
|
| 414 |
+
node._set_value(dest_node._value())
|
| 415 |
+
else:
|
| 416 |
+
node = src_node
|
| 417 |
+
dest.__setitem__(key, node)
|
| 418 |
+
else:
|
| 419 |
+
if not src_node_missing:
|
| 420 |
+
dest_node._set_value(src_value)
|
| 421 |
+
|
| 422 |
+
except (ValidationError, ReadonlyConfigError) as e:
|
| 423 |
+
dest._format_and_raise(key=key, value=src_value, cause=e)
|
| 424 |
+
else:
|
| 425 |
+
from omegaconf import open_dict
|
| 426 |
+
|
| 427 |
+
if is_structured_config(src_type):
|
| 428 |
+
# verified to be compatible above in _validate_merge
|
| 429 |
+
with open_dict(dest):
|
| 430 |
+
dest[key] = src._get_node(key)
|
| 431 |
+
else:
|
| 432 |
+
dest[key] = src._get_node(key)
|
| 433 |
+
|
| 434 |
+
_update_types(node=dest, ref_type=src_ref_type, object_type=src_type)
|
| 435 |
+
|
| 436 |
+
# explicit flags on the source config are replacing the flag values in the destination
|
| 437 |
+
flags = src._metadata.flags
|
| 438 |
+
assert flags is not None
|
| 439 |
+
for flag, value in flags.items():
|
| 440 |
+
if value is not None:
|
| 441 |
+
dest._set_flag(flag, value)
|
| 442 |
+
|
| 443 |
+
@staticmethod
|
| 444 |
+
def _list_merge(dest: Any, src: Any) -> None:
|
| 445 |
+
from omegaconf import DictConfig, ListConfig, OmegaConf
|
| 446 |
+
|
| 447 |
+
assert isinstance(dest, ListConfig)
|
| 448 |
+
assert isinstance(src, ListConfig)
|
| 449 |
+
|
| 450 |
+
if src._is_none():
|
| 451 |
+
dest._set_value(None)
|
| 452 |
+
elif src._is_missing():
|
| 453 |
+
# do not change dest if src is MISSING.
|
| 454 |
+
if dest._metadata.element_type is Any:
|
| 455 |
+
dest._metadata.element_type = src._metadata.element_type
|
| 456 |
+
elif src._is_interpolation():
|
| 457 |
+
dest._set_value(src._value())
|
| 458 |
+
else:
|
| 459 |
+
temp_target = ListConfig(content=[], parent=dest._get_parent())
|
| 460 |
+
temp_target.__dict__["_metadata"] = copy.deepcopy(
|
| 461 |
+
dest.__dict__["_metadata"]
|
| 462 |
+
)
|
| 463 |
+
is_optional, et = _resolve_optional(dest._metadata.element_type)
|
| 464 |
+
if is_structured_config(et):
|
| 465 |
+
prototype = DictConfig(et, ref_type=et, is_optional=is_optional)
|
| 466 |
+
for item in src._iter_ex(resolve=False):
|
| 467 |
+
if isinstance(item, DictConfig):
|
| 468 |
+
item = OmegaConf.merge(prototype, item)
|
| 469 |
+
temp_target.append(item)
|
| 470 |
+
else:
|
| 471 |
+
for item in src._iter_ex(resolve=False):
|
| 472 |
+
temp_target.append(item)
|
| 473 |
+
|
| 474 |
+
dest.__dict__["_content"] = temp_target.__dict__["_content"]
|
| 475 |
+
|
| 476 |
+
# explicit flags on the source config are replacing the flag values in the destination
|
| 477 |
+
flags = src._metadata.flags
|
| 478 |
+
assert flags is not None
|
| 479 |
+
for flag, value in flags.items():
|
| 480 |
+
if value is not None:
|
| 481 |
+
dest._set_flag(flag, value)
|
| 482 |
+
|
| 483 |
+
def merge_with(
|
| 484 |
+
self,
|
| 485 |
+
*others: Union[
|
| 486 |
+
"BaseContainer", Dict[str, Any], List[Any], Tuple[Any, ...], Any
|
| 487 |
+
],
|
| 488 |
+
) -> None:
|
| 489 |
+
try:
|
| 490 |
+
self._merge_with(*others)
|
| 491 |
+
except Exception as e:
|
| 492 |
+
self._format_and_raise(key=None, value=None, cause=e)
|
| 493 |
+
|
| 494 |
+
def _merge_with(
|
| 495 |
+
self,
|
| 496 |
+
*others: Union[
|
| 497 |
+
"BaseContainer", Dict[str, Any], List[Any], Tuple[Any, ...], Any
|
| 498 |
+
],
|
| 499 |
+
) -> None:
|
| 500 |
+
from .dictconfig import DictConfig
|
| 501 |
+
from .listconfig import ListConfig
|
| 502 |
+
|
| 503 |
+
"""merge a list of other Config objects into this one, overriding as needed"""
|
| 504 |
+
for other in others:
|
| 505 |
+
if other is None:
|
| 506 |
+
raise ValueError("Cannot merge with a None config")
|
| 507 |
+
|
| 508 |
+
my_flags = {}
|
| 509 |
+
if self._get_flag("allow_objects") is True:
|
| 510 |
+
my_flags = {"allow_objects": True}
|
| 511 |
+
other = _ensure_container(other, flags=my_flags)
|
| 512 |
+
|
| 513 |
+
if isinstance(self, DictConfig) and isinstance(other, DictConfig):
|
| 514 |
+
BaseContainer._map_merge(self, other)
|
| 515 |
+
elif isinstance(self, ListConfig) and isinstance(other, ListConfig):
|
| 516 |
+
BaseContainer._list_merge(self, other)
|
| 517 |
+
else:
|
| 518 |
+
raise TypeError("Cannot merge DictConfig with ListConfig")
|
| 519 |
+
|
| 520 |
+
# recursively correct the parent hierarchy after the merge
|
| 521 |
+
self._re_parent()
|
| 522 |
+
|
| 523 |
+
# noinspection PyProtectedMember
|
| 524 |
+
def _set_item_impl(self, key: Any, value: Any) -> None:
|
| 525 |
+
"""
|
| 526 |
+
Changes the value of the node key with the desired value. If the node key doesn't
|
| 527 |
+
exist it creates a new one.
|
| 528 |
+
"""
|
| 529 |
+
from .nodes import AnyNode, ValueNode
|
| 530 |
+
|
| 531 |
+
if isinstance(value, Node):
|
| 532 |
+
do_deepcopy = not self._get_flag("no_deepcopy_set_nodes")
|
| 533 |
+
if not do_deepcopy and isinstance(value, Box):
|
| 534 |
+
# if value is from the same config, perform a deepcopy no matter what.
|
| 535 |
+
if self._get_root() is value._get_root():
|
| 536 |
+
do_deepcopy = True
|
| 537 |
+
|
| 538 |
+
if do_deepcopy:
|
| 539 |
+
value = copy.deepcopy(value)
|
| 540 |
+
value._set_parent(None)
|
| 541 |
+
|
| 542 |
+
try:
|
| 543 |
+
old = value._key()
|
| 544 |
+
value._set_key(key)
|
| 545 |
+
self._validate_set(key, value)
|
| 546 |
+
finally:
|
| 547 |
+
value._set_key(old)
|
| 548 |
+
else:
|
| 549 |
+
self._validate_set(key, value)
|
| 550 |
+
|
| 551 |
+
if self._get_flag("readonly"):
|
| 552 |
+
raise ReadonlyConfigError("Cannot change read-only config container")
|
| 553 |
+
|
| 554 |
+
input_is_node = isinstance(value, Node)
|
| 555 |
+
target_node_ref = self._get_node(key)
|
| 556 |
+
assert target_node_ref is None or isinstance(target_node_ref, Node)
|
| 557 |
+
|
| 558 |
+
input_is_typed_vnode = isinstance(value, ValueNode) and not isinstance(
|
| 559 |
+
value, AnyNode
|
| 560 |
+
)
|
| 561 |
+
|
| 562 |
+
def get_target_type_hint(val: Any) -> Any:
|
| 563 |
+
if not is_structured_config(val):
|
| 564 |
+
type_hint = self._metadata.element_type
|
| 565 |
+
else:
|
| 566 |
+
target = self._get_node(key)
|
| 567 |
+
if target is None:
|
| 568 |
+
type_hint = self._metadata.element_type
|
| 569 |
+
else:
|
| 570 |
+
assert isinstance(target, Node)
|
| 571 |
+
type_hint = target._metadata.type_hint
|
| 572 |
+
return type_hint
|
| 573 |
+
|
| 574 |
+
target_type_hint = get_target_type_hint(value)
|
| 575 |
+
_, target_ref_type = _resolve_optional(target_type_hint)
|
| 576 |
+
|
| 577 |
+
def assign(value_key: Any, val: Node) -> None:
|
| 578 |
+
assert val._get_parent() is None
|
| 579 |
+
v = val
|
| 580 |
+
v._set_parent(self)
|
| 581 |
+
v._set_key(value_key)
|
| 582 |
+
_deep_update_type_hint(node=v, type_hint=self._metadata.element_type)
|
| 583 |
+
self.__dict__["_content"][value_key] = v
|
| 584 |
+
|
| 585 |
+
if input_is_typed_vnode and not is_union_annotation(target_ref_type):
|
| 586 |
+
assign(key, value)
|
| 587 |
+
else:
|
| 588 |
+
# input is not a ValueNode, can be primitive or box
|
| 589 |
+
|
| 590 |
+
special_value = _is_special(value)
|
| 591 |
+
# We use the `Node._set_value` method if the target node exists and:
|
| 592 |
+
# 1. the target has an explicit ref_type, or
|
| 593 |
+
# 2. the target is an AnyNode and the input is a primitive type.
|
| 594 |
+
should_set_value = target_node_ref is not None and (
|
| 595 |
+
target_node_ref._has_ref_type()
|
| 596 |
+
or (
|
| 597 |
+
isinstance(target_node_ref, AnyNode)
|
| 598 |
+
and is_primitive_type_annotation(value)
|
| 599 |
+
)
|
| 600 |
+
)
|
| 601 |
+
if should_set_value:
|
| 602 |
+
if special_value and isinstance(value, Node):
|
| 603 |
+
value = value._value()
|
| 604 |
+
self.__dict__["_content"][key]._set_value(value)
|
| 605 |
+
elif input_is_node:
|
| 606 |
+
if (
|
| 607 |
+
special_value
|
| 608 |
+
and (
|
| 609 |
+
is_container_annotation(target_ref_type)
|
| 610 |
+
or is_structured_config(target_ref_type)
|
| 611 |
+
)
|
| 612 |
+
or is_primitive_type_annotation(target_ref_type)
|
| 613 |
+
or is_union_annotation(target_ref_type)
|
| 614 |
+
):
|
| 615 |
+
value = _get_value(value)
|
| 616 |
+
self._wrap_value_and_set(key, value, target_type_hint)
|
| 617 |
+
else:
|
| 618 |
+
assign(key, value)
|
| 619 |
+
else:
|
| 620 |
+
self._wrap_value_and_set(key, value, target_type_hint)
|
| 621 |
+
|
| 622 |
+
def _wrap_value_and_set(self, key: Any, val: Any, type_hint: Any) -> None:
|
| 623 |
+
from omegaconf.omegaconf import _maybe_wrap
|
| 624 |
+
|
| 625 |
+
is_optional, ref_type = _resolve_optional(type_hint)
|
| 626 |
+
|
| 627 |
+
try:
|
| 628 |
+
wrapped = _maybe_wrap(
|
| 629 |
+
ref_type=ref_type,
|
| 630 |
+
key=key,
|
| 631 |
+
value=val,
|
| 632 |
+
is_optional=is_optional,
|
| 633 |
+
parent=self,
|
| 634 |
+
)
|
| 635 |
+
except ValidationError as e:
|
| 636 |
+
self._format_and_raise(key=key, value=val, cause=e)
|
| 637 |
+
self.__dict__["_content"][key] = wrapped
|
| 638 |
+
|
| 639 |
+
@staticmethod
|
| 640 |
+
def _item_eq(
|
| 641 |
+
c1: Container,
|
| 642 |
+
k1: Union[DictKeyType, int],
|
| 643 |
+
c2: Container,
|
| 644 |
+
k2: Union[DictKeyType, int],
|
| 645 |
+
) -> bool:
|
| 646 |
+
v1 = c1._get_child(k1)
|
| 647 |
+
v2 = c2._get_child(k2)
|
| 648 |
+
assert v1 is not None and v2 is not None
|
| 649 |
+
|
| 650 |
+
assert isinstance(v1, Node)
|
| 651 |
+
assert isinstance(v2, Node)
|
| 652 |
+
|
| 653 |
+
if v1._is_none() and v2._is_none():
|
| 654 |
+
return True
|
| 655 |
+
|
| 656 |
+
if v1._is_missing() and v2._is_missing():
|
| 657 |
+
return True
|
| 658 |
+
|
| 659 |
+
v1_inter = v1._is_interpolation()
|
| 660 |
+
v2_inter = v2._is_interpolation()
|
| 661 |
+
dv1: Optional[Node] = v1
|
| 662 |
+
dv2: Optional[Node] = v2
|
| 663 |
+
|
| 664 |
+
if v1_inter:
|
| 665 |
+
dv1 = v1._maybe_dereference_node()
|
| 666 |
+
if v2_inter:
|
| 667 |
+
dv2 = v2._maybe_dereference_node()
|
| 668 |
+
|
| 669 |
+
if v1_inter and v2_inter:
|
| 670 |
+
if dv1 is None or dv2 is None:
|
| 671 |
+
return v1 == v2
|
| 672 |
+
else:
|
| 673 |
+
# both are not none, if both are containers compare as container
|
| 674 |
+
if isinstance(dv1, Container) and isinstance(dv2, Container):
|
| 675 |
+
if dv1 != dv2:
|
| 676 |
+
return False
|
| 677 |
+
dv1 = _get_value(dv1)
|
| 678 |
+
dv2 = _get_value(dv2)
|
| 679 |
+
return dv1 == dv2
|
| 680 |
+
elif not v1_inter and not v2_inter:
|
| 681 |
+
v1 = _get_value(v1)
|
| 682 |
+
v2 = _get_value(v2)
|
| 683 |
+
ret = v1 == v2
|
| 684 |
+
assert isinstance(ret, bool)
|
| 685 |
+
return ret
|
| 686 |
+
else:
|
| 687 |
+
dv1 = _get_value(dv1)
|
| 688 |
+
dv2 = _get_value(dv2)
|
| 689 |
+
ret = dv1 == dv2
|
| 690 |
+
assert isinstance(ret, bool)
|
| 691 |
+
return ret
|
| 692 |
+
|
| 693 |
+
def _is_optional(self) -> bool:
|
| 694 |
+
return self.__dict__["_metadata"].optional is True
|
| 695 |
+
|
| 696 |
+
def _is_interpolation(self) -> bool:
|
| 697 |
+
return _is_interpolation(self.__dict__["_content"])
|
| 698 |
+
|
| 699 |
+
@abstractmethod
|
| 700 |
+
def _validate_get(self, key: Any, value: Any = None) -> None:
|
| 701 |
+
...
|
| 702 |
+
|
| 703 |
+
@abstractmethod
|
| 704 |
+
def _validate_set(self, key: Any, value: Any) -> None:
|
| 705 |
+
...
|
| 706 |
+
|
| 707 |
+
def _value(self) -> Any:
|
| 708 |
+
return self.__dict__["_content"]
|
| 709 |
+
|
| 710 |
+
def _get_full_key(self, key: Union[DictKeyType, int, slice, None]) -> str:
|
| 711 |
+
from .listconfig import ListConfig
|
| 712 |
+
from .omegaconf import _select_one
|
| 713 |
+
|
| 714 |
+
if not isinstance(key, (int, str, Enum, float, bool, slice, bytes, type(None))):
|
| 715 |
+
return ""
|
| 716 |
+
|
| 717 |
+
def _slice_to_str(x: slice) -> str:
|
| 718 |
+
if x.step is not None:
|
| 719 |
+
return f"{x.start}:{x.stop}:{x.step}"
|
| 720 |
+
else:
|
| 721 |
+
return f"{x.start}:{x.stop}"
|
| 722 |
+
|
| 723 |
+
def prepand(
|
| 724 |
+
full_key: str,
|
| 725 |
+
parent_type: Any,
|
| 726 |
+
cur_type: Any,
|
| 727 |
+
key: Optional[Union[DictKeyType, int, slice]],
|
| 728 |
+
) -> str:
|
| 729 |
+
if key is None:
|
| 730 |
+
return full_key
|
| 731 |
+
|
| 732 |
+
if isinstance(key, slice):
|
| 733 |
+
key = _slice_to_str(key)
|
| 734 |
+
elif isinstance(key, Enum):
|
| 735 |
+
key = key.name
|
| 736 |
+
else:
|
| 737 |
+
key = str(key)
|
| 738 |
+
|
| 739 |
+
assert isinstance(key, str)
|
| 740 |
+
|
| 741 |
+
if issubclass(parent_type, ListConfig):
|
| 742 |
+
if full_key != "":
|
| 743 |
+
if issubclass(cur_type, ListConfig):
|
| 744 |
+
full_key = f"[{key}]{full_key}"
|
| 745 |
+
else:
|
| 746 |
+
full_key = f"[{key}].{full_key}"
|
| 747 |
+
else:
|
| 748 |
+
full_key = f"[{key}]"
|
| 749 |
+
else:
|
| 750 |
+
if full_key == "":
|
| 751 |
+
full_key = key
|
| 752 |
+
else:
|
| 753 |
+
if issubclass(cur_type, ListConfig):
|
| 754 |
+
full_key = f"{key}{full_key}"
|
| 755 |
+
else:
|
| 756 |
+
full_key = f"{key}.{full_key}"
|
| 757 |
+
return full_key
|
| 758 |
+
|
| 759 |
+
if key is not None and key != "":
|
| 760 |
+
assert isinstance(self, Container)
|
| 761 |
+
cur, _ = _select_one(
|
| 762 |
+
c=self, key=str(key), throw_on_missing=False, throw_on_type_error=False
|
| 763 |
+
)
|
| 764 |
+
if cur is None:
|
| 765 |
+
cur = self
|
| 766 |
+
full_key = prepand("", type(cur), None, key)
|
| 767 |
+
if cur._key() is not None:
|
| 768 |
+
full_key = prepand(
|
| 769 |
+
full_key, type(cur._get_parent()), type(cur), cur._key()
|
| 770 |
+
)
|
| 771 |
+
else:
|
| 772 |
+
full_key = prepand("", type(cur._get_parent()), type(cur), cur._key())
|
| 773 |
+
else:
|
| 774 |
+
cur = self
|
| 775 |
+
if cur._key() is None:
|
| 776 |
+
return ""
|
| 777 |
+
full_key = self._key()
|
| 778 |
+
|
| 779 |
+
assert cur is not None
|
| 780 |
+
memo = {id(cur)} # remember already visited nodes so as to detect cycles
|
| 781 |
+
while cur._get_parent() is not None:
|
| 782 |
+
cur = cur._get_parent()
|
| 783 |
+
if id(cur) in memo:
|
| 784 |
+
raise ConfigCycleDetectedException(
|
| 785 |
+
f"Cycle when iterating over parents of key `{key!s}`"
|
| 786 |
+
)
|
| 787 |
+
memo.add(id(cur))
|
| 788 |
+
assert cur is not None
|
| 789 |
+
if cur._key() is not None:
|
| 790 |
+
full_key = prepand(
|
| 791 |
+
full_key, type(cur._get_parent()), type(cur), cur._key()
|
| 792 |
+
)
|
| 793 |
+
|
| 794 |
+
return full_key
|
| 795 |
+
|
| 796 |
+
|
| 797 |
+
def _create_structured_with_missing_fields(
|
| 798 |
+
ref_type: type, object_type: Optional[type] = None
|
| 799 |
+
) -> "DictConfig":
|
| 800 |
+
from . import MISSING, DictConfig
|
| 801 |
+
|
| 802 |
+
cfg_data = get_structured_config_data(ref_type)
|
| 803 |
+
for v in cfg_data.values():
|
| 804 |
+
v._set_value(MISSING)
|
| 805 |
+
|
| 806 |
+
cfg = DictConfig(cfg_data)
|
| 807 |
+
cfg._metadata.optional, cfg._metadata.ref_type = _resolve_optional(ref_type)
|
| 808 |
+
cfg._metadata.object_type = object_type
|
| 809 |
+
|
| 810 |
+
return cfg
|
| 811 |
+
|
| 812 |
+
|
| 813 |
+
def _update_types(node: Node, ref_type: Any, object_type: Optional[type]) -> None:
|
| 814 |
+
if object_type is not None and not is_primitive_dict(object_type):
|
| 815 |
+
node._metadata.object_type = object_type
|
| 816 |
+
|
| 817 |
+
if node._metadata.ref_type is Any:
|
| 818 |
+
_deep_update_type_hint(node, ref_type)
|
| 819 |
+
|
| 820 |
+
|
| 821 |
+
def _deep_update_type_hint(node: Node, type_hint: Any) -> None:
|
| 822 |
+
"""Ensure node is compatible with type_hint, mutating if necessary."""
|
| 823 |
+
from omegaconf import DictConfig, ListConfig
|
| 824 |
+
|
| 825 |
+
from ._utils import get_dict_key_value_types, get_list_element_type
|
| 826 |
+
|
| 827 |
+
if type_hint is Any:
|
| 828 |
+
return
|
| 829 |
+
|
| 830 |
+
_shallow_validate_type_hint(node, type_hint)
|
| 831 |
+
|
| 832 |
+
new_is_optional, new_ref_type = _resolve_optional(type_hint)
|
| 833 |
+
node._metadata.ref_type = new_ref_type
|
| 834 |
+
node._metadata.optional = new_is_optional
|
| 835 |
+
|
| 836 |
+
if is_list_annotation(new_ref_type) and isinstance(node, ListConfig):
|
| 837 |
+
new_element_type = get_list_element_type(new_ref_type)
|
| 838 |
+
node._metadata.element_type = new_element_type
|
| 839 |
+
if not _is_special(node):
|
| 840 |
+
for i in range(len(node)):
|
| 841 |
+
_deep_update_subnode(node, i, new_element_type)
|
| 842 |
+
|
| 843 |
+
if is_dict_annotation(new_ref_type) and isinstance(node, DictConfig):
|
| 844 |
+
new_key_type, new_element_type = get_dict_key_value_types(new_ref_type)
|
| 845 |
+
node._metadata.key_type = new_key_type
|
| 846 |
+
node._metadata.element_type = new_element_type
|
| 847 |
+
if not _is_special(node):
|
| 848 |
+
for key in node:
|
| 849 |
+
if new_key_type is not Any and not isinstance(key, new_key_type):
|
| 850 |
+
raise KeyValidationError(
|
| 851 |
+
f"Key {key!r} ({type(key).__name__}) is incompatible"
|
| 852 |
+
+ f" with key type hint '{new_key_type.__name__}'"
|
| 853 |
+
)
|
| 854 |
+
_deep_update_subnode(node, key, new_element_type)
|
| 855 |
+
|
| 856 |
+
|
| 857 |
+
def _deep_update_subnode(node: BaseContainer, key: Any, value_type_hint: Any) -> None:
|
| 858 |
+
"""Get node[key] and ensure it is compatible with value_type_hint, mutating if necessary."""
|
| 859 |
+
subnode = node._get_node(key)
|
| 860 |
+
assert isinstance(subnode, Node)
|
| 861 |
+
if _is_special(subnode):
|
| 862 |
+
# Ensure special values are wrapped in a Node subclass that
|
| 863 |
+
# is compatible with the type hint.
|
| 864 |
+
node._wrap_value_and_set(key, subnode._value(), value_type_hint)
|
| 865 |
+
subnode = node._get_node(key)
|
| 866 |
+
assert isinstance(subnode, Node)
|
| 867 |
+
_deep_update_type_hint(subnode, value_type_hint)
|
| 868 |
+
|
| 869 |
+
|
| 870 |
+
def _shallow_validate_type_hint(node: Node, type_hint: Any) -> None:
|
| 871 |
+
"""Error if node's type, content and metadata are not compatible with type_hint."""
|
| 872 |
+
from omegaconf import DictConfig, ListConfig, ValueNode
|
| 873 |
+
|
| 874 |
+
is_optional, ref_type = _resolve_optional(type_hint)
|
| 875 |
+
|
| 876 |
+
vk = get_value_kind(node)
|
| 877 |
+
|
| 878 |
+
if node._is_none():
|
| 879 |
+
if not is_optional:
|
| 880 |
+
value = _get_value(node)
|
| 881 |
+
raise ValidationError(
|
| 882 |
+
f"Value {value!r} ({type(value).__name__})"
|
| 883 |
+
+ f" is incompatible with type hint '{ref_type.__name__}'"
|
| 884 |
+
)
|
| 885 |
+
return
|
| 886 |
+
elif vk in (ValueKind.MANDATORY_MISSING, ValueKind.INTERPOLATION):
|
| 887 |
+
return
|
| 888 |
+
elif vk == ValueKind.VALUE:
|
| 889 |
+
if is_primitive_type_annotation(ref_type) and isinstance(node, ValueNode):
|
| 890 |
+
value = node._value()
|
| 891 |
+
if not isinstance(value, ref_type):
|
| 892 |
+
raise ValidationError(
|
| 893 |
+
f"Value {value!r} ({type(value).__name__})"
|
| 894 |
+
+ f" is incompatible with type hint '{ref_type.__name__}'"
|
| 895 |
+
)
|
| 896 |
+
elif is_structured_config(ref_type) and isinstance(node, DictConfig):
|
| 897 |
+
return
|
| 898 |
+
elif is_dict_annotation(ref_type) and isinstance(node, DictConfig):
|
| 899 |
+
return
|
| 900 |
+
elif is_list_annotation(ref_type) and isinstance(node, ListConfig):
|
| 901 |
+
return
|
| 902 |
+
else:
|
| 903 |
+
if isinstance(node, ValueNode):
|
| 904 |
+
value = node._value()
|
| 905 |
+
raise ValidationError(
|
| 906 |
+
f"Value {value!r} ({type(value).__name__})"
|
| 907 |
+
+ f" is incompatible with type hint '{ref_type}'"
|
| 908 |
+
)
|
| 909 |
+
else:
|
| 910 |
+
raise ValidationError(
|
| 911 |
+
f"'{type(node).__name__}' is incompatible"
|
| 912 |
+
+ f" with type hint '{ref_type}'"
|
| 913 |
+
)
|
| 914 |
+
|
| 915 |
+
else:
|
| 916 |
+
assert False
|
lib/python3.12/site-packages/omegaconf/dictconfig.py
ADDED
|
@@ -0,0 +1,776 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
from enum import Enum
|
| 3 |
+
from typing import (
|
| 4 |
+
Any,
|
| 5 |
+
Dict,
|
| 6 |
+
ItemsView,
|
| 7 |
+
Iterable,
|
| 8 |
+
Iterator,
|
| 9 |
+
KeysView,
|
| 10 |
+
List,
|
| 11 |
+
MutableMapping,
|
| 12 |
+
Optional,
|
| 13 |
+
Sequence,
|
| 14 |
+
Tuple,
|
| 15 |
+
Type,
|
| 16 |
+
Union,
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
from ._utils import (
|
| 20 |
+
_DEFAULT_MARKER_,
|
| 21 |
+
ValueKind,
|
| 22 |
+
_get_value,
|
| 23 |
+
_is_interpolation,
|
| 24 |
+
_is_missing_literal,
|
| 25 |
+
_is_missing_value,
|
| 26 |
+
_is_none,
|
| 27 |
+
_resolve_optional,
|
| 28 |
+
_valid_dict_key_annotation_type,
|
| 29 |
+
format_and_raise,
|
| 30 |
+
get_structured_config_data,
|
| 31 |
+
get_structured_config_init_field_names,
|
| 32 |
+
get_type_of,
|
| 33 |
+
get_value_kind,
|
| 34 |
+
is_container_annotation,
|
| 35 |
+
is_dict,
|
| 36 |
+
is_primitive_dict,
|
| 37 |
+
is_structured_config,
|
| 38 |
+
is_structured_config_frozen,
|
| 39 |
+
type_str,
|
| 40 |
+
)
|
| 41 |
+
from .base import Box, Container, ContainerMetadata, DictKeyType, Node
|
| 42 |
+
from .basecontainer import BaseContainer
|
| 43 |
+
from .errors import (
|
| 44 |
+
ConfigAttributeError,
|
| 45 |
+
ConfigKeyError,
|
| 46 |
+
ConfigTypeError,
|
| 47 |
+
InterpolationResolutionError,
|
| 48 |
+
KeyValidationError,
|
| 49 |
+
MissingMandatoryValue,
|
| 50 |
+
OmegaConfBaseException,
|
| 51 |
+
ReadonlyConfigError,
|
| 52 |
+
ValidationError,
|
| 53 |
+
)
|
| 54 |
+
from .nodes import EnumNode, ValueNode
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
class DictConfig(BaseContainer, MutableMapping[Any, Any]):
|
| 58 |
+
|
| 59 |
+
_metadata: ContainerMetadata
|
| 60 |
+
_content: Union[Dict[DictKeyType, Node], None, str]
|
| 61 |
+
|
| 62 |
+
def __init__(
|
| 63 |
+
self,
|
| 64 |
+
content: Union[Dict[DictKeyType, Any], "DictConfig", Any],
|
| 65 |
+
key: Any = None,
|
| 66 |
+
parent: Optional[Box] = None,
|
| 67 |
+
ref_type: Union[Any, Type[Any]] = Any,
|
| 68 |
+
key_type: Union[Any, Type[Any]] = Any,
|
| 69 |
+
element_type: Union[Any, Type[Any]] = Any,
|
| 70 |
+
is_optional: bool = True,
|
| 71 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 72 |
+
) -> None:
|
| 73 |
+
try:
|
| 74 |
+
if isinstance(content, DictConfig):
|
| 75 |
+
if flags is None:
|
| 76 |
+
flags = content._metadata.flags
|
| 77 |
+
super().__init__(
|
| 78 |
+
parent=parent,
|
| 79 |
+
metadata=ContainerMetadata(
|
| 80 |
+
key=key,
|
| 81 |
+
optional=is_optional,
|
| 82 |
+
ref_type=ref_type,
|
| 83 |
+
object_type=dict,
|
| 84 |
+
key_type=key_type,
|
| 85 |
+
element_type=element_type,
|
| 86 |
+
flags=flags,
|
| 87 |
+
),
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
if not _valid_dict_key_annotation_type(key_type):
|
| 91 |
+
raise KeyValidationError(f"Unsupported key type {key_type}")
|
| 92 |
+
|
| 93 |
+
if is_structured_config(content) or is_structured_config(ref_type):
|
| 94 |
+
self._set_value(content, flags=flags)
|
| 95 |
+
if is_structured_config_frozen(content) or is_structured_config_frozen(
|
| 96 |
+
ref_type
|
| 97 |
+
):
|
| 98 |
+
self._set_flag("readonly", True)
|
| 99 |
+
|
| 100 |
+
else:
|
| 101 |
+
if isinstance(content, DictConfig):
|
| 102 |
+
metadata = copy.deepcopy(content._metadata)
|
| 103 |
+
metadata.key = key
|
| 104 |
+
metadata.ref_type = ref_type
|
| 105 |
+
metadata.optional = is_optional
|
| 106 |
+
metadata.element_type = element_type
|
| 107 |
+
metadata.key_type = key_type
|
| 108 |
+
self.__dict__["_metadata"] = metadata
|
| 109 |
+
self._set_value(content, flags=flags)
|
| 110 |
+
except Exception as ex:
|
| 111 |
+
format_and_raise(node=None, key=key, value=None, cause=ex, msg=str(ex))
|
| 112 |
+
|
| 113 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "DictConfig":
|
| 114 |
+
res = DictConfig(None)
|
| 115 |
+
res.__dict__["_metadata"] = copy.deepcopy(self.__dict__["_metadata"], memo=memo)
|
| 116 |
+
res.__dict__["_flags_cache"] = copy.deepcopy(
|
| 117 |
+
self.__dict__["_flags_cache"], memo=memo
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
src_content = self.__dict__["_content"]
|
| 121 |
+
if isinstance(src_content, dict):
|
| 122 |
+
content_copy = {}
|
| 123 |
+
for k, v in src_content.items():
|
| 124 |
+
old_parent = v.__dict__["_parent"]
|
| 125 |
+
try:
|
| 126 |
+
v.__dict__["_parent"] = None
|
| 127 |
+
vc = copy.deepcopy(v, memo=memo)
|
| 128 |
+
vc.__dict__["_parent"] = res
|
| 129 |
+
content_copy[k] = vc
|
| 130 |
+
finally:
|
| 131 |
+
v.__dict__["_parent"] = old_parent
|
| 132 |
+
else:
|
| 133 |
+
# None and strings can be assigned as is
|
| 134 |
+
content_copy = src_content
|
| 135 |
+
|
| 136 |
+
res.__dict__["_content"] = content_copy
|
| 137 |
+
# parent is retained, but not copied
|
| 138 |
+
res.__dict__["_parent"] = self.__dict__["_parent"]
|
| 139 |
+
return res
|
| 140 |
+
|
| 141 |
+
def copy(self) -> "DictConfig":
|
| 142 |
+
return copy.copy(self)
|
| 143 |
+
|
| 144 |
+
def _is_typed(self) -> bool:
|
| 145 |
+
return self._metadata.object_type not in (Any, None) and not is_dict(
|
| 146 |
+
self._metadata.object_type
|
| 147 |
+
)
|
| 148 |
+
|
| 149 |
+
def _validate_get(self, key: Any, value: Any = None) -> None:
|
| 150 |
+
is_typed = self._is_typed()
|
| 151 |
+
|
| 152 |
+
is_struct = self._get_flag("struct") is True
|
| 153 |
+
if key not in self.__dict__["_content"]:
|
| 154 |
+
if is_typed:
|
| 155 |
+
# do not raise an exception if struct is explicitly set to False
|
| 156 |
+
if self._get_node_flag("struct") is False:
|
| 157 |
+
return
|
| 158 |
+
if is_typed or is_struct:
|
| 159 |
+
if is_typed:
|
| 160 |
+
assert self._metadata.object_type not in (dict, None)
|
| 161 |
+
msg = f"Key '{key}' not in '{self._metadata.object_type.__name__}'"
|
| 162 |
+
else:
|
| 163 |
+
msg = f"Key '{key}' is not in struct"
|
| 164 |
+
self._format_and_raise(
|
| 165 |
+
key=key, value=value, cause=ConfigAttributeError(msg)
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
def _validate_set(self, key: Any, value: Any) -> None:
|
| 169 |
+
from omegaconf import OmegaConf
|
| 170 |
+
|
| 171 |
+
vk = get_value_kind(value)
|
| 172 |
+
if vk == ValueKind.INTERPOLATION:
|
| 173 |
+
return
|
| 174 |
+
if _is_none(value):
|
| 175 |
+
self._validate_non_optional(key, value)
|
| 176 |
+
return
|
| 177 |
+
if vk == ValueKind.MANDATORY_MISSING or value is None:
|
| 178 |
+
return
|
| 179 |
+
|
| 180 |
+
target = self._get_node(key) if key is not None else self
|
| 181 |
+
|
| 182 |
+
target_has_ref_type = isinstance(
|
| 183 |
+
target, DictConfig
|
| 184 |
+
) and target._metadata.ref_type not in (Any, dict)
|
| 185 |
+
is_valid_target = target is None or not target_has_ref_type
|
| 186 |
+
|
| 187 |
+
if is_valid_target:
|
| 188 |
+
return
|
| 189 |
+
|
| 190 |
+
assert isinstance(target, Node)
|
| 191 |
+
|
| 192 |
+
target_type = target._metadata.ref_type
|
| 193 |
+
value_type = OmegaConf.get_type(value)
|
| 194 |
+
|
| 195 |
+
if is_dict(value_type) and is_dict(target_type):
|
| 196 |
+
return
|
| 197 |
+
if is_container_annotation(target_type) and not is_container_annotation(
|
| 198 |
+
value_type
|
| 199 |
+
):
|
| 200 |
+
raise ValidationError(
|
| 201 |
+
f"Cannot assign {type_str(value_type)} to {type_str(target_type)}"
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
if target_type is not None and value_type is not None:
|
| 205 |
+
origin = getattr(target_type, "__origin__", target_type)
|
| 206 |
+
if not issubclass(value_type, origin):
|
| 207 |
+
self._raise_invalid_value(value, value_type, target_type)
|
| 208 |
+
|
| 209 |
+
def _validate_merge(self, value: Any) -> None:
|
| 210 |
+
from omegaconf import OmegaConf
|
| 211 |
+
|
| 212 |
+
dest = self
|
| 213 |
+
src = value
|
| 214 |
+
|
| 215 |
+
self._validate_non_optional(None, src)
|
| 216 |
+
|
| 217 |
+
dest_obj_type = OmegaConf.get_type(dest)
|
| 218 |
+
src_obj_type = OmegaConf.get_type(src)
|
| 219 |
+
|
| 220 |
+
if dest._is_missing() and src._metadata.object_type not in (dict, None):
|
| 221 |
+
self._validate_set(key=None, value=_get_value(src))
|
| 222 |
+
|
| 223 |
+
if src._is_missing():
|
| 224 |
+
return
|
| 225 |
+
|
| 226 |
+
validation_error = (
|
| 227 |
+
dest_obj_type is not None
|
| 228 |
+
and src_obj_type is not None
|
| 229 |
+
and is_structured_config(dest_obj_type)
|
| 230 |
+
and not src._is_none()
|
| 231 |
+
and not is_dict(src_obj_type)
|
| 232 |
+
and not issubclass(src_obj_type, dest_obj_type)
|
| 233 |
+
)
|
| 234 |
+
if validation_error:
|
| 235 |
+
msg = (
|
| 236 |
+
f"Merge error: {type_str(src_obj_type)} is not a "
|
| 237 |
+
f"subclass of {type_str(dest_obj_type)}. value: {src}"
|
| 238 |
+
)
|
| 239 |
+
raise ValidationError(msg)
|
| 240 |
+
|
| 241 |
+
def _validate_non_optional(self, key: Optional[DictKeyType], value: Any) -> None:
|
| 242 |
+
if _is_none(value, resolve=True, throw_on_resolution_failure=False):
|
| 243 |
+
|
| 244 |
+
if key is not None:
|
| 245 |
+
child = self._get_node(key)
|
| 246 |
+
if child is not None:
|
| 247 |
+
assert isinstance(child, Node)
|
| 248 |
+
field_is_optional = child._is_optional()
|
| 249 |
+
else:
|
| 250 |
+
field_is_optional, _ = _resolve_optional(
|
| 251 |
+
self._metadata.element_type
|
| 252 |
+
)
|
| 253 |
+
else:
|
| 254 |
+
field_is_optional = self._is_optional()
|
| 255 |
+
|
| 256 |
+
if not field_is_optional:
|
| 257 |
+
self._format_and_raise(
|
| 258 |
+
key=key,
|
| 259 |
+
value=value,
|
| 260 |
+
cause=ValidationError("field '$FULL_KEY' is not Optional"),
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
def _raise_invalid_value(
|
| 264 |
+
self, value: Any, value_type: Any, target_type: Any
|
| 265 |
+
) -> None:
|
| 266 |
+
assert value_type is not None
|
| 267 |
+
assert target_type is not None
|
| 268 |
+
msg = (
|
| 269 |
+
f"Invalid type assigned: {type_str(value_type)} is not a "
|
| 270 |
+
f"subclass of {type_str(target_type)}. value: {value}"
|
| 271 |
+
)
|
| 272 |
+
raise ValidationError(msg)
|
| 273 |
+
|
| 274 |
+
def _validate_and_normalize_key(self, key: Any) -> DictKeyType:
|
| 275 |
+
return self._s_validate_and_normalize_key(self._metadata.key_type, key)
|
| 276 |
+
|
| 277 |
+
def _s_validate_and_normalize_key(self, key_type: Any, key: Any) -> DictKeyType:
|
| 278 |
+
if key_type is Any:
|
| 279 |
+
for t in DictKeyType.__args__: # type: ignore
|
| 280 |
+
if isinstance(key, t):
|
| 281 |
+
return key # type: ignore
|
| 282 |
+
raise KeyValidationError("Incompatible key type '$KEY_TYPE'")
|
| 283 |
+
elif key_type is bool and key in [0, 1]:
|
| 284 |
+
# Python treats True as 1 and False as 0 when used as dict keys
|
| 285 |
+
# assert hash(0) == hash(False)
|
| 286 |
+
# assert hash(1) == hash(True)
|
| 287 |
+
return bool(key)
|
| 288 |
+
elif key_type in (str, bytes, int, float, bool): # primitive type
|
| 289 |
+
if not isinstance(key, key_type):
|
| 290 |
+
raise KeyValidationError(
|
| 291 |
+
f"Key $KEY ($KEY_TYPE) is incompatible with ({key_type.__name__})"
|
| 292 |
+
)
|
| 293 |
+
|
| 294 |
+
return key # type: ignore
|
| 295 |
+
elif issubclass(key_type, Enum):
|
| 296 |
+
try:
|
| 297 |
+
return EnumNode.validate_and_convert_to_enum(key_type, key)
|
| 298 |
+
except ValidationError:
|
| 299 |
+
valid = ", ".join([x for x in key_type.__members__.keys()])
|
| 300 |
+
raise KeyValidationError(
|
| 301 |
+
f"Key '$KEY' is incompatible with the enum type '{key_type.__name__}', valid: [{valid}]"
|
| 302 |
+
)
|
| 303 |
+
else:
|
| 304 |
+
assert False, f"Unsupported key type {key_type}"
|
| 305 |
+
|
| 306 |
+
def __setitem__(self, key: DictKeyType, value: Any) -> None:
|
| 307 |
+
try:
|
| 308 |
+
self.__set_impl(key=key, value=value)
|
| 309 |
+
except AttributeError as e:
|
| 310 |
+
self._format_and_raise(
|
| 311 |
+
key=key, value=value, type_override=ConfigKeyError, cause=e
|
| 312 |
+
)
|
| 313 |
+
except Exception as e:
|
| 314 |
+
self._format_and_raise(key=key, value=value, cause=e)
|
| 315 |
+
|
| 316 |
+
def __set_impl(self, key: DictKeyType, value: Any) -> None:
|
| 317 |
+
key = self._validate_and_normalize_key(key)
|
| 318 |
+
self._set_item_impl(key, value)
|
| 319 |
+
|
| 320 |
+
# hide content while inspecting in debugger
|
| 321 |
+
def __dir__(self) -> Iterable[str]:
|
| 322 |
+
if self._is_missing() or self._is_none():
|
| 323 |
+
return []
|
| 324 |
+
return self.__dict__["_content"].keys() # type: ignore
|
| 325 |
+
|
| 326 |
+
def __setattr__(self, key: str, value: Any) -> None:
|
| 327 |
+
"""
|
| 328 |
+
Allow assigning attributes to DictConfig
|
| 329 |
+
:param key:
|
| 330 |
+
:param value:
|
| 331 |
+
:return:
|
| 332 |
+
"""
|
| 333 |
+
try:
|
| 334 |
+
self.__set_impl(key, value)
|
| 335 |
+
except Exception as e:
|
| 336 |
+
if isinstance(e, OmegaConfBaseException) and e._initialized:
|
| 337 |
+
raise e
|
| 338 |
+
self._format_and_raise(key=key, value=value, cause=e)
|
| 339 |
+
assert False
|
| 340 |
+
|
| 341 |
+
def __getattr__(self, key: str) -> Any:
|
| 342 |
+
"""
|
| 343 |
+
Allow accessing dictionary values as attributes
|
| 344 |
+
:param key:
|
| 345 |
+
:return:
|
| 346 |
+
"""
|
| 347 |
+
if key == "__name__":
|
| 348 |
+
raise AttributeError()
|
| 349 |
+
|
| 350 |
+
try:
|
| 351 |
+
return self._get_impl(
|
| 352 |
+
key=key, default_value=_DEFAULT_MARKER_, validate_key=False
|
| 353 |
+
)
|
| 354 |
+
except ConfigKeyError as e:
|
| 355 |
+
self._format_and_raise(
|
| 356 |
+
key=key, value=None, cause=e, type_override=ConfigAttributeError
|
| 357 |
+
)
|
| 358 |
+
except Exception as e:
|
| 359 |
+
self._format_and_raise(key=key, value=None, cause=e)
|
| 360 |
+
|
| 361 |
+
def __getitem__(self, key: DictKeyType) -> Any:
|
| 362 |
+
"""
|
| 363 |
+
Allow map style access
|
| 364 |
+
:param key:
|
| 365 |
+
:return:
|
| 366 |
+
"""
|
| 367 |
+
|
| 368 |
+
try:
|
| 369 |
+
return self._get_impl(key=key, default_value=_DEFAULT_MARKER_)
|
| 370 |
+
except AttributeError as e:
|
| 371 |
+
self._format_and_raise(
|
| 372 |
+
key=key, value=None, cause=e, type_override=ConfigKeyError
|
| 373 |
+
)
|
| 374 |
+
except Exception as e:
|
| 375 |
+
self._format_and_raise(key=key, value=None, cause=e)
|
| 376 |
+
|
| 377 |
+
def __delattr__(self, key: str) -> None:
|
| 378 |
+
"""
|
| 379 |
+
Allow deleting dictionary values as attributes
|
| 380 |
+
:param key:
|
| 381 |
+
:return:
|
| 382 |
+
"""
|
| 383 |
+
if self._get_flag("readonly"):
|
| 384 |
+
self._format_and_raise(
|
| 385 |
+
key=key,
|
| 386 |
+
value=None,
|
| 387 |
+
cause=ReadonlyConfigError(
|
| 388 |
+
"DictConfig in read-only mode does not support deletion"
|
| 389 |
+
),
|
| 390 |
+
)
|
| 391 |
+
try:
|
| 392 |
+
del self.__dict__["_content"][key]
|
| 393 |
+
except KeyError:
|
| 394 |
+
msg = "Attribute not found: '$KEY'"
|
| 395 |
+
self._format_and_raise(key=key, value=None, cause=ConfigAttributeError(msg))
|
| 396 |
+
|
| 397 |
+
def __delitem__(self, key: DictKeyType) -> None:
|
| 398 |
+
key = self._validate_and_normalize_key(key)
|
| 399 |
+
if self._get_flag("readonly"):
|
| 400 |
+
self._format_and_raise(
|
| 401 |
+
key=key,
|
| 402 |
+
value=None,
|
| 403 |
+
cause=ReadonlyConfigError(
|
| 404 |
+
"DictConfig in read-only mode does not support deletion"
|
| 405 |
+
),
|
| 406 |
+
)
|
| 407 |
+
if self._get_flag("struct"):
|
| 408 |
+
self._format_and_raise(
|
| 409 |
+
key=key,
|
| 410 |
+
value=None,
|
| 411 |
+
cause=ConfigTypeError(
|
| 412 |
+
"DictConfig in struct mode does not support deletion"
|
| 413 |
+
),
|
| 414 |
+
)
|
| 415 |
+
if self._is_typed() and self._get_node_flag("struct") is not False:
|
| 416 |
+
self._format_and_raise(
|
| 417 |
+
key=key,
|
| 418 |
+
value=None,
|
| 419 |
+
cause=ConfigTypeError(
|
| 420 |
+
f"{type_str(self._metadata.object_type)} (DictConfig) does not support deletion"
|
| 421 |
+
),
|
| 422 |
+
)
|
| 423 |
+
|
| 424 |
+
try:
|
| 425 |
+
del self.__dict__["_content"][key]
|
| 426 |
+
except KeyError:
|
| 427 |
+
msg = "Key not found: '$KEY'"
|
| 428 |
+
self._format_and_raise(key=key, value=None, cause=ConfigKeyError(msg))
|
| 429 |
+
|
| 430 |
+
def get(self, key: DictKeyType, default_value: Any = None) -> Any:
|
| 431 |
+
"""Return the value for `key` if `key` is in the dictionary, else
|
| 432 |
+
`default_value` (defaulting to `None`)."""
|
| 433 |
+
try:
|
| 434 |
+
return self._get_impl(key=key, default_value=default_value)
|
| 435 |
+
except KeyValidationError as e:
|
| 436 |
+
self._format_and_raise(key=key, value=None, cause=e)
|
| 437 |
+
|
| 438 |
+
def _get_impl(
|
| 439 |
+
self, key: DictKeyType, default_value: Any, validate_key: bool = True
|
| 440 |
+
) -> Any:
|
| 441 |
+
try:
|
| 442 |
+
node = self._get_child(
|
| 443 |
+
key=key, throw_on_missing_key=True, validate_key=validate_key
|
| 444 |
+
)
|
| 445 |
+
except (ConfigAttributeError, ConfigKeyError):
|
| 446 |
+
if default_value is not _DEFAULT_MARKER_:
|
| 447 |
+
return default_value
|
| 448 |
+
else:
|
| 449 |
+
raise
|
| 450 |
+
assert isinstance(node, Node)
|
| 451 |
+
return self._resolve_with_default(
|
| 452 |
+
key=key, value=node, default_value=default_value
|
| 453 |
+
)
|
| 454 |
+
|
| 455 |
+
def _get_node(
|
| 456 |
+
self,
|
| 457 |
+
key: DictKeyType,
|
| 458 |
+
validate_access: bool = True,
|
| 459 |
+
validate_key: bool = True,
|
| 460 |
+
throw_on_missing_value: bool = False,
|
| 461 |
+
throw_on_missing_key: bool = False,
|
| 462 |
+
) -> Optional[Node]:
|
| 463 |
+
try:
|
| 464 |
+
key = self._validate_and_normalize_key(key)
|
| 465 |
+
except KeyValidationError:
|
| 466 |
+
if validate_access and validate_key:
|
| 467 |
+
raise
|
| 468 |
+
else:
|
| 469 |
+
if throw_on_missing_key:
|
| 470 |
+
raise ConfigAttributeError
|
| 471 |
+
else:
|
| 472 |
+
return None
|
| 473 |
+
|
| 474 |
+
if validate_access:
|
| 475 |
+
self._validate_get(key)
|
| 476 |
+
|
| 477 |
+
value: Optional[Node] = self.__dict__["_content"].get(key)
|
| 478 |
+
if value is None:
|
| 479 |
+
if throw_on_missing_key:
|
| 480 |
+
raise ConfigKeyError(f"Missing key {key!s}")
|
| 481 |
+
elif throw_on_missing_value and value._is_missing():
|
| 482 |
+
raise MissingMandatoryValue("Missing mandatory value: $KEY")
|
| 483 |
+
return value
|
| 484 |
+
|
| 485 |
+
def pop(self, key: DictKeyType, default: Any = _DEFAULT_MARKER_) -> Any:
|
| 486 |
+
try:
|
| 487 |
+
if self._get_flag("readonly"):
|
| 488 |
+
raise ReadonlyConfigError("Cannot pop from read-only node")
|
| 489 |
+
if self._get_flag("struct"):
|
| 490 |
+
raise ConfigTypeError("DictConfig in struct mode does not support pop")
|
| 491 |
+
if self._is_typed() and self._get_node_flag("struct") is not False:
|
| 492 |
+
raise ConfigTypeError(
|
| 493 |
+
f"{type_str(self._metadata.object_type)} (DictConfig) does not support pop"
|
| 494 |
+
)
|
| 495 |
+
key = self._validate_and_normalize_key(key)
|
| 496 |
+
node = self._get_child(key=key, validate_access=False)
|
| 497 |
+
if node is not None:
|
| 498 |
+
assert isinstance(node, Node)
|
| 499 |
+
value = self._resolve_with_default(
|
| 500 |
+
key=key, value=node, default_value=default
|
| 501 |
+
)
|
| 502 |
+
|
| 503 |
+
del self[key]
|
| 504 |
+
return value
|
| 505 |
+
else:
|
| 506 |
+
if default is not _DEFAULT_MARKER_:
|
| 507 |
+
return default
|
| 508 |
+
else:
|
| 509 |
+
full = self._get_full_key(key=key)
|
| 510 |
+
if full != key:
|
| 511 |
+
raise ConfigKeyError(
|
| 512 |
+
f"Key not found: '{key!s}' (path: '{full}')"
|
| 513 |
+
)
|
| 514 |
+
else:
|
| 515 |
+
raise ConfigKeyError(f"Key not found: '{key!s}'")
|
| 516 |
+
except Exception as e:
|
| 517 |
+
self._format_and_raise(key=key, value=None, cause=e)
|
| 518 |
+
|
| 519 |
+
def keys(self) -> KeysView[DictKeyType]:
|
| 520 |
+
if self._is_missing() or self._is_interpolation() or self._is_none():
|
| 521 |
+
return {}.keys()
|
| 522 |
+
ret = self.__dict__["_content"].keys()
|
| 523 |
+
assert isinstance(ret, KeysView)
|
| 524 |
+
return ret
|
| 525 |
+
|
| 526 |
+
def __contains__(self, key: object) -> bool:
|
| 527 |
+
"""
|
| 528 |
+
A key is contained in a DictConfig if there is an associated value and
|
| 529 |
+
it is not a mandatory missing value ('???').
|
| 530 |
+
:param key:
|
| 531 |
+
:return:
|
| 532 |
+
"""
|
| 533 |
+
|
| 534 |
+
try:
|
| 535 |
+
key = self._validate_and_normalize_key(key)
|
| 536 |
+
except KeyValidationError:
|
| 537 |
+
return False
|
| 538 |
+
|
| 539 |
+
try:
|
| 540 |
+
node = self._get_child(key)
|
| 541 |
+
assert node is None or isinstance(node, Node)
|
| 542 |
+
except (KeyError, AttributeError):
|
| 543 |
+
node = None
|
| 544 |
+
|
| 545 |
+
if node is None:
|
| 546 |
+
return False
|
| 547 |
+
else:
|
| 548 |
+
try:
|
| 549 |
+
self._resolve_with_default(key=key, value=node)
|
| 550 |
+
return True
|
| 551 |
+
except InterpolationResolutionError:
|
| 552 |
+
# Interpolations that fail count as existing.
|
| 553 |
+
return True
|
| 554 |
+
except MissingMandatoryValue:
|
| 555 |
+
# Missing values count as *not* existing.
|
| 556 |
+
return False
|
| 557 |
+
|
| 558 |
+
def __iter__(self) -> Iterator[DictKeyType]:
|
| 559 |
+
return iter(self.keys())
|
| 560 |
+
|
| 561 |
+
def items(self) -> ItemsView[DictKeyType, Any]:
|
| 562 |
+
return dict(self.items_ex(resolve=True, keys=None)).items()
|
| 563 |
+
|
| 564 |
+
def setdefault(self, key: DictKeyType, default: Any = None) -> Any:
|
| 565 |
+
if key in self:
|
| 566 |
+
ret = self.__getitem__(key)
|
| 567 |
+
else:
|
| 568 |
+
ret = default
|
| 569 |
+
self.__setitem__(key, default)
|
| 570 |
+
return ret
|
| 571 |
+
|
| 572 |
+
def items_ex(
|
| 573 |
+
self, resolve: bool = True, keys: Optional[Sequence[DictKeyType]] = None
|
| 574 |
+
) -> List[Tuple[DictKeyType, Any]]:
|
| 575 |
+
items: List[Tuple[DictKeyType, Any]] = []
|
| 576 |
+
|
| 577 |
+
if self._is_none():
|
| 578 |
+
self._format_and_raise(
|
| 579 |
+
key=None,
|
| 580 |
+
value=None,
|
| 581 |
+
cause=TypeError("Cannot iterate a DictConfig object representing None"),
|
| 582 |
+
)
|
| 583 |
+
if self._is_missing():
|
| 584 |
+
raise MissingMandatoryValue("Cannot iterate a missing DictConfig")
|
| 585 |
+
|
| 586 |
+
for key in self.keys():
|
| 587 |
+
if resolve:
|
| 588 |
+
value = self[key]
|
| 589 |
+
else:
|
| 590 |
+
value = self.__dict__["_content"][key]
|
| 591 |
+
if isinstance(value, ValueNode):
|
| 592 |
+
value = value._value()
|
| 593 |
+
if keys is None or key in keys:
|
| 594 |
+
items.append((key, value))
|
| 595 |
+
|
| 596 |
+
return items
|
| 597 |
+
|
| 598 |
+
def __eq__(self, other: Any) -> bool:
|
| 599 |
+
if other is None:
|
| 600 |
+
return self.__dict__["_content"] is None
|
| 601 |
+
if is_primitive_dict(other) or is_structured_config(other):
|
| 602 |
+
other = DictConfig(other, flags={"allow_objects": True})
|
| 603 |
+
return DictConfig._dict_conf_eq(self, other)
|
| 604 |
+
if isinstance(other, DictConfig):
|
| 605 |
+
return DictConfig._dict_conf_eq(self, other)
|
| 606 |
+
if self._is_missing():
|
| 607 |
+
return _is_missing_literal(other)
|
| 608 |
+
return NotImplemented
|
| 609 |
+
|
| 610 |
+
def __ne__(self, other: Any) -> bool:
|
| 611 |
+
x = self.__eq__(other)
|
| 612 |
+
if x is not NotImplemented:
|
| 613 |
+
return not x
|
| 614 |
+
return NotImplemented
|
| 615 |
+
|
| 616 |
+
def __hash__(self) -> int:
|
| 617 |
+
return hash(str(self))
|
| 618 |
+
|
| 619 |
+
def _promote(self, type_or_prototype: Optional[Type[Any]]) -> None:
|
| 620 |
+
"""
|
| 621 |
+
Retypes a node.
|
| 622 |
+
This should only be used in rare circumstances, where you want to dynamically change
|
| 623 |
+
the runtime structured-type of a DictConfig.
|
| 624 |
+
It will change the type and add the additional fields based on the input class or object
|
| 625 |
+
"""
|
| 626 |
+
if type_or_prototype is None:
|
| 627 |
+
return
|
| 628 |
+
if not is_structured_config(type_or_prototype):
|
| 629 |
+
raise ValueError(f"Expected structured config class: {type_or_prototype}")
|
| 630 |
+
|
| 631 |
+
from omegaconf import OmegaConf
|
| 632 |
+
|
| 633 |
+
proto: DictConfig = OmegaConf.structured(type_or_prototype)
|
| 634 |
+
object_type = proto._metadata.object_type
|
| 635 |
+
# remove the type to prevent assignment validation from rejecting the promotion.
|
| 636 |
+
proto._metadata.object_type = None
|
| 637 |
+
self.merge_with(proto)
|
| 638 |
+
# restore the type.
|
| 639 |
+
self._metadata.object_type = object_type
|
| 640 |
+
|
| 641 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 642 |
+
try:
|
| 643 |
+
previous_content = self.__dict__["_content"]
|
| 644 |
+
self._set_value_impl(value, flags)
|
| 645 |
+
except Exception as e:
|
| 646 |
+
self.__dict__["_content"] = previous_content
|
| 647 |
+
raise e
|
| 648 |
+
|
| 649 |
+
def _set_value_impl(
|
| 650 |
+
self, value: Any, flags: Optional[Dict[str, bool]] = None
|
| 651 |
+
) -> None:
|
| 652 |
+
from omegaconf import MISSING, flag_override
|
| 653 |
+
|
| 654 |
+
if flags is None:
|
| 655 |
+
flags = {}
|
| 656 |
+
|
| 657 |
+
assert not isinstance(value, ValueNode)
|
| 658 |
+
self._validate_set(key=None, value=value)
|
| 659 |
+
|
| 660 |
+
if _is_none(value, resolve=True):
|
| 661 |
+
self.__dict__["_content"] = None
|
| 662 |
+
self._metadata.object_type = None
|
| 663 |
+
elif _is_interpolation(value, strict_interpolation_validation=True):
|
| 664 |
+
self.__dict__["_content"] = value
|
| 665 |
+
self._metadata.object_type = None
|
| 666 |
+
elif _is_missing_value(value):
|
| 667 |
+
self.__dict__["_content"] = MISSING
|
| 668 |
+
self._metadata.object_type = None
|
| 669 |
+
else:
|
| 670 |
+
self.__dict__["_content"] = {}
|
| 671 |
+
if is_structured_config(value):
|
| 672 |
+
self._metadata.object_type = None
|
| 673 |
+
ao = self._get_flag("allow_objects")
|
| 674 |
+
data = get_structured_config_data(value, allow_objects=ao)
|
| 675 |
+
with flag_override(self, ["struct", "readonly"], False):
|
| 676 |
+
for k, v in data.items():
|
| 677 |
+
self.__setitem__(k, v)
|
| 678 |
+
self._metadata.object_type = get_type_of(value)
|
| 679 |
+
|
| 680 |
+
elif isinstance(value, DictConfig):
|
| 681 |
+
self._metadata.flags = copy.deepcopy(flags)
|
| 682 |
+
with flag_override(self, ["struct", "readonly"], False):
|
| 683 |
+
for k, v in value.__dict__["_content"].items():
|
| 684 |
+
self.__setitem__(k, v)
|
| 685 |
+
self._metadata.object_type = value._metadata.object_type
|
| 686 |
+
|
| 687 |
+
elif isinstance(value, dict):
|
| 688 |
+
with flag_override(self, ["struct", "readonly"], False):
|
| 689 |
+
for k, v in value.items():
|
| 690 |
+
self.__setitem__(k, v)
|
| 691 |
+
self._metadata.object_type = dict
|
| 692 |
+
|
| 693 |
+
else: # pragma: no cover
|
| 694 |
+
msg = f"Unsupported value type: {value}"
|
| 695 |
+
raise ValidationError(msg)
|
| 696 |
+
|
| 697 |
+
@staticmethod
|
| 698 |
+
def _dict_conf_eq(d1: "DictConfig", d2: "DictConfig") -> bool:
|
| 699 |
+
|
| 700 |
+
d1_none = d1.__dict__["_content"] is None
|
| 701 |
+
d2_none = d2.__dict__["_content"] is None
|
| 702 |
+
if d1_none and d2_none:
|
| 703 |
+
return True
|
| 704 |
+
if d1_none != d2_none:
|
| 705 |
+
return False
|
| 706 |
+
|
| 707 |
+
assert isinstance(d1, DictConfig)
|
| 708 |
+
assert isinstance(d2, DictConfig)
|
| 709 |
+
if len(d1) != len(d2):
|
| 710 |
+
return False
|
| 711 |
+
if d1._is_missing() or d2._is_missing():
|
| 712 |
+
return d1._is_missing() is d2._is_missing()
|
| 713 |
+
|
| 714 |
+
for k, v in d1.items_ex(resolve=False):
|
| 715 |
+
if k not in d2.__dict__["_content"]:
|
| 716 |
+
return False
|
| 717 |
+
if not BaseContainer._item_eq(d1, k, d2, k):
|
| 718 |
+
return False
|
| 719 |
+
|
| 720 |
+
return True
|
| 721 |
+
|
| 722 |
+
def _to_object(self) -> Any:
|
| 723 |
+
"""
|
| 724 |
+
Instantiate an instance of `self._metadata.object_type`.
|
| 725 |
+
This requires `self` to be a structured config.
|
| 726 |
+
Nested subconfigs are converted by calling `OmegaConf.to_object`.
|
| 727 |
+
"""
|
| 728 |
+
from omegaconf import OmegaConf
|
| 729 |
+
|
| 730 |
+
object_type = self._metadata.object_type
|
| 731 |
+
assert is_structured_config(object_type)
|
| 732 |
+
init_field_names = set(get_structured_config_init_field_names(object_type))
|
| 733 |
+
|
| 734 |
+
init_field_items: Dict[str, Any] = {}
|
| 735 |
+
non_init_field_items: Dict[str, Any] = {}
|
| 736 |
+
for k in self.keys():
|
| 737 |
+
assert isinstance(k, str)
|
| 738 |
+
node = self._get_child(k)
|
| 739 |
+
assert isinstance(node, Node)
|
| 740 |
+
try:
|
| 741 |
+
node = node._dereference_node()
|
| 742 |
+
except InterpolationResolutionError as e:
|
| 743 |
+
self._format_and_raise(key=k, value=None, cause=e)
|
| 744 |
+
if node._is_missing():
|
| 745 |
+
if k not in init_field_names:
|
| 746 |
+
continue # MISSING is ignored for init=False fields
|
| 747 |
+
self._format_and_raise(
|
| 748 |
+
key=k,
|
| 749 |
+
value=None,
|
| 750 |
+
cause=MissingMandatoryValue(
|
| 751 |
+
"Structured config of type `$OBJECT_TYPE` has missing mandatory value: $KEY"
|
| 752 |
+
),
|
| 753 |
+
)
|
| 754 |
+
if isinstance(node, Container):
|
| 755 |
+
v = OmegaConf.to_object(node)
|
| 756 |
+
else:
|
| 757 |
+
v = node._value()
|
| 758 |
+
|
| 759 |
+
if k in init_field_names:
|
| 760 |
+
init_field_items[k] = v
|
| 761 |
+
else:
|
| 762 |
+
non_init_field_items[k] = v
|
| 763 |
+
|
| 764 |
+
try:
|
| 765 |
+
result = object_type(**init_field_items)
|
| 766 |
+
except TypeError as exc:
|
| 767 |
+
self._format_and_raise(
|
| 768 |
+
key=None,
|
| 769 |
+
value=None,
|
| 770 |
+
cause=exc,
|
| 771 |
+
msg="Could not create instance of `$OBJECT_TYPE`: " + str(exc),
|
| 772 |
+
)
|
| 773 |
+
|
| 774 |
+
for k, v in non_init_field_items.items():
|
| 775 |
+
setattr(result, k, v)
|
| 776 |
+
return result
|
lib/python3.12/site-packages/omegaconf/errors.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, Optional, Type
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
class OmegaConfBaseException(Exception):
|
| 5 |
+
# would ideally be typed Optional[Node]
|
| 6 |
+
parent_node: Any
|
| 7 |
+
child_node: Any
|
| 8 |
+
key: Any
|
| 9 |
+
full_key: Optional[str]
|
| 10 |
+
value: Any
|
| 11 |
+
msg: Optional[str]
|
| 12 |
+
cause: Optional[Exception]
|
| 13 |
+
object_type: Optional[Type[Any]]
|
| 14 |
+
object_type_str: Optional[str]
|
| 15 |
+
ref_type: Optional[Type[Any]]
|
| 16 |
+
ref_type_str: Optional[str]
|
| 17 |
+
|
| 18 |
+
_initialized: bool = False
|
| 19 |
+
|
| 20 |
+
def __init__(self, *_args: Any, **_kwargs: Any) -> None:
|
| 21 |
+
self.parent_node = None
|
| 22 |
+
self.child_node = None
|
| 23 |
+
self.key = None
|
| 24 |
+
self.full_key = None
|
| 25 |
+
self.value = None
|
| 26 |
+
self.msg = None
|
| 27 |
+
self.object_type = None
|
| 28 |
+
self.ref_type = None
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class MissingMandatoryValue(OmegaConfBaseException):
|
| 32 |
+
"""Thrown when a variable flagged with '???' value is accessed to
|
| 33 |
+
indicate that the value was not set"""
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class KeyValidationError(OmegaConfBaseException, ValueError):
|
| 37 |
+
"""
|
| 38 |
+
Thrown when an a key of invalid type is used
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
class ValidationError(OmegaConfBaseException, ValueError):
|
| 43 |
+
"""
|
| 44 |
+
Thrown when a value fails validation
|
| 45 |
+
"""
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
class UnsupportedValueType(ValidationError, ValueError):
|
| 49 |
+
"""
|
| 50 |
+
Thrown when an input value is not of supported type
|
| 51 |
+
"""
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
class ReadonlyConfigError(OmegaConfBaseException):
|
| 55 |
+
"""
|
| 56 |
+
Thrown when someone tries to modify a frozen config
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class InterpolationResolutionError(OmegaConfBaseException, ValueError):
|
| 61 |
+
"""
|
| 62 |
+
Base class for exceptions raised when resolving an interpolation.
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
class UnsupportedInterpolationType(InterpolationResolutionError):
|
| 67 |
+
"""
|
| 68 |
+
Thrown when an attempt to use an unregistered interpolation is made
|
| 69 |
+
"""
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
class InterpolationKeyError(InterpolationResolutionError):
|
| 73 |
+
"""
|
| 74 |
+
Thrown when a node does not exist when resolving an interpolation.
|
| 75 |
+
"""
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
class InterpolationToMissingValueError(InterpolationResolutionError):
|
| 79 |
+
"""
|
| 80 |
+
Thrown when a node interpolation points to a node that is set to ???.
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class InterpolationValidationError(InterpolationResolutionError, ValidationError):
|
| 85 |
+
"""
|
| 86 |
+
Thrown when the result of an interpolation fails the validation step.
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
class ConfigKeyError(OmegaConfBaseException, KeyError):
|
| 91 |
+
"""
|
| 92 |
+
Thrown from DictConfig when a regular dict access would have caused a KeyError.
|
| 93 |
+
"""
|
| 94 |
+
|
| 95 |
+
msg: str
|
| 96 |
+
|
| 97 |
+
def __init__(self, msg: str) -> None:
|
| 98 |
+
super().__init__(msg)
|
| 99 |
+
self.msg = msg
|
| 100 |
+
|
| 101 |
+
def __str__(self) -> str:
|
| 102 |
+
"""
|
| 103 |
+
Workaround to nasty KeyError quirk: https://bugs.python.org/issue2651
|
| 104 |
+
"""
|
| 105 |
+
return self.msg
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
class ConfigAttributeError(OmegaConfBaseException, AttributeError):
|
| 109 |
+
"""
|
| 110 |
+
Thrown from a config object when a regular access would have caused an AttributeError.
|
| 111 |
+
"""
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
class ConfigTypeError(OmegaConfBaseException, TypeError):
|
| 115 |
+
"""
|
| 116 |
+
Thrown from a config object when a regular access would have caused a TypeError.
|
| 117 |
+
"""
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
class ConfigIndexError(OmegaConfBaseException, IndexError):
|
| 121 |
+
"""
|
| 122 |
+
Thrown from a config object when a regular access would have caused an IndexError.
|
| 123 |
+
"""
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
class ConfigValueError(OmegaConfBaseException, ValueError):
|
| 127 |
+
"""
|
| 128 |
+
Thrown from a config object when a regular access would have caused a ValueError.
|
| 129 |
+
"""
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
class ConfigCycleDetectedException(OmegaConfBaseException):
|
| 133 |
+
"""
|
| 134 |
+
Thrown when a cycle is detected in the graph made by config nodes.
|
| 135 |
+
"""
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
class GrammarParseError(OmegaConfBaseException):
|
| 139 |
+
"""
|
| 140 |
+
Thrown when failing to parse an expression according to the ANTLR grammar.
|
| 141 |
+
"""
|
lib/python3.12/site-packages/omegaconf/grammar/__init__.py
ADDED
|
File without changes
|
lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarLexer.py
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated from /tmp/build-via-sdist-fm63w174/omegaconf-2.3.0/omegaconf/grammar/OmegaConfGrammarLexer.g4 by ANTLR 4.9.3
|
| 2 |
+
from antlr4 import *
|
| 3 |
+
from io import StringIO
|
| 4 |
+
import sys
|
| 5 |
+
if sys.version_info[1] > 5:
|
| 6 |
+
from typing import TextIO
|
| 7 |
+
else:
|
| 8 |
+
from typing.io import TextIO
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def serializedATN():
|
| 13 |
+
with StringIO() as buf:
|
| 14 |
+
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\36")
|
| 15 |
+
buf.write("\u01e7\b\1\b\1\b\1\b\1\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5")
|
| 16 |
+
buf.write("\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13")
|
| 17 |
+
buf.write("\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t")
|
| 18 |
+
buf.write("\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26")
|
| 19 |
+
buf.write("\4\27\t\27\4\30\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34")
|
| 20 |
+
buf.write("\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!\t!\4\"\t")
|
| 21 |
+
buf.write("\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4")
|
| 22 |
+
buf.write("+\t+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62")
|
| 23 |
+
buf.write("\t\62\4\63\t\63\4\64\t\64\4\65\t\65\4\66\t\66\3\2\3\2")
|
| 24 |
+
buf.write("\3\3\3\3\3\4\3\4\3\4\5\4y\n\4\3\4\7\4|\n\4\f\4\16\4\177")
|
| 25 |
+
buf.write("\13\4\5\4\u0081\n\4\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3")
|
| 26 |
+
buf.write("\7\7\7\u008c\n\7\f\7\16\7\u008f\13\7\3\7\3\7\3\b\7\b\u0094")
|
| 27 |
+
buf.write("\n\b\f\b\16\b\u0097\13\b\3\b\3\b\3\b\3\b\3\t\6\t\u009e")
|
| 28 |
+
buf.write("\n\t\r\t\16\t\u009f\3\n\6\n\u00a3\n\n\r\n\16\n\u00a4\3")
|
| 29 |
+
buf.write("\n\3\n\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\5\f\u00b1\n")
|
| 30 |
+
buf.write("\f\3\f\3\f\3\r\3\r\5\r\u00b7\n\r\3\r\3\r\3\16\5\16\u00bc")
|
| 31 |
+
buf.write("\n\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\20\3\20")
|
| 32 |
+
buf.write("\3\20\3\20\3\21\5\21\u00cb\n\21\3\21\3\21\5\21\u00cf\n")
|
| 33 |
+
buf.write("\21\3\22\3\22\5\22\u00d3\n\22\3\23\5\23\u00d6\n\23\3\23")
|
| 34 |
+
buf.write("\3\23\3\24\5\24\u00db\n\24\3\24\3\24\5\24\u00df\n\24\3")
|
| 35 |
+
buf.write("\25\3\25\3\25\3\25\5\25\u00e5\n\25\3\25\3\25\3\25\5\25")
|
| 36 |
+
buf.write("\u00ea\n\25\3\25\7\25\u00ed\n\25\f\25\16\25\u00f0\13\25")
|
| 37 |
+
buf.write("\5\25\u00f2\n\25\3\26\3\26\5\26\u00f6\n\26\3\26\3\26\5")
|
| 38 |
+
buf.write("\26\u00fa\n\26\3\26\3\26\5\26\u00fe\n\26\3\26\7\26\u0101")
|
| 39 |
+
buf.write("\n\26\f\26\16\26\u0104\13\26\3\27\5\27\u0107\n\27\3\27")
|
| 40 |
+
buf.write("\3\27\3\27\3\27\3\27\3\27\3\27\3\27\5\27\u0111\n\27\3")
|
| 41 |
+
buf.write("\30\5\30\u0114\n\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31")
|
| 42 |
+
buf.write("\3\31\3\31\3\31\3\31\5\31\u0121\n\31\3\32\3\32\3\32\3")
|
| 43 |
+
buf.write("\32\3\32\3\33\3\33\3\34\3\34\5\34\u012c\n\34\3\34\3\34")
|
| 44 |
+
buf.write("\3\34\7\34\u0131\n\34\f\34\16\34\u0134\13\34\3\35\3\35")
|
| 45 |
+
buf.write("\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35")
|
| 46 |
+
buf.write("\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\6\35")
|
| 47 |
+
buf.write("\u014d\n\35\r\35\16\35\u014e\3\36\6\36\u0152\n\36\r\36")
|
| 48 |
+
buf.write("\16\36\u0153\3\37\3\37\5\37\u0158\n\37\3\37\3\37\3\37")
|
| 49 |
+
buf.write("\3 \5 \u015e\n \3 \3 \5 \u0162\n \3 \3 \3 \3!\5!\u0168")
|
| 50 |
+
buf.write("\n!\3!\3!\3!\3!\3\"\3\"\3#\3#\3#\3#\3$\3$\3$\3$\3%\3%")
|
| 51 |
+
buf.write("\3%\3%\3&\6&\u017d\n&\r&\16&\u017e\3\'\3\'\3\'\3\'\3\'")
|
| 52 |
+
buf.write("\3(\3(\3(\3(\3)\7)\u018b\n)\f)\16)\u018e\13)\3)\3)\3)")
|
| 53 |
+
buf.write("\3)\3*\3*\3*\3*\3+\7+\u0199\n+\f+\16+\u019c\13+\3+\3+")
|
| 54 |
+
buf.write("\3+\3+\3+\3,\6,\u01a4\n,\r,\16,\u01a5\3-\6-\u01a9\n-\r")
|
| 55 |
+
buf.write("-\16-\u01aa\3-\3-\3.\3.\3.\3.\3/\3/\3/\3/\3/\3\60\3\60")
|
| 56 |
+
buf.write("\3\60\3\60\3\60\3\61\7\61\u01be\n\61\f\61\16\61\u01c1")
|
| 57 |
+
buf.write("\13\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\63\7")
|
| 58 |
+
buf.write("\63\u01cc\n\63\f\63\16\63\u01cf\13\63\3\63\3\63\3\63\3")
|
| 59 |
+
buf.write("\63\3\63\3\64\6\64\u01d7\n\64\r\64\16\64\u01d8\3\64\3")
|
| 60 |
+
buf.write("\64\3\65\6\65\u01de\n\65\r\65\16\65\u01df\3\65\3\65\3")
|
| 61 |
+
buf.write("\66\3\66\3\66\3\66\2\2\67\7\2\t\2\13\2\r\2\17\2\21\3\23")
|
| 62 |
+
buf.write("\4\25\5\27\2\31\34\33\6\35\7\37\b!\t#\n%\13\'\f)\r+\16")
|
| 63 |
+
buf.write("-\2/\2\61\17\63\20\65\21\67\229\23;\24=\25?\26A\2C\2E")
|
| 64 |
+
buf.write("\27G\30I\35K\36M\2O\31Q\2S\32U\2W\2Y\2[\33]\2_\2a\2c\2")
|
| 65 |
+
buf.write("e\2g\2i\2k\2m\2o\2\7\2\3\4\5\6\32\4\2C\\c|\3\2\62;\3\2")
|
| 66 |
+
buf.write("\63;\3\2&&\4\2&&^^\4\2GGgg\4\2--//\4\2KKkk\4\2PPpp\4\2")
|
| 67 |
+
buf.write("HHhh\4\2CCcc\4\2VVvv\4\2TTtt\4\2WWww\4\2NNnn\4\2UUuu\b")
|
| 68 |
+
buf.write("\2&\',-/\61AB^^~~\4\2//aa\4\2\13\13\"\"\13\2\13\13\"\"")
|
| 69 |
+
buf.write("$$)+\60\60<<]_}}\177\177\4\2&&))\5\2&&))^^\4\2$$&&\5\2")
|
| 70 |
+
buf.write("$$&&^^\2\u0218\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2")
|
| 71 |
+
buf.write("\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\3\33\3\2\2\2\3")
|
| 72 |
+
buf.write("\35\3\2\2\2\3\37\3\2\2\2\3!\3\2\2\2\3#\3\2\2\2\3%\3\2")
|
| 73 |
+
buf.write("\2\2\3\'\3\2\2\2\3)\3\2\2\2\3+\3\2\2\2\3\61\3\2\2\2\3")
|
| 74 |
+
buf.write("\63\3\2\2\2\3\65\3\2\2\2\3\67\3\2\2\2\39\3\2\2\2\3;\3")
|
| 75 |
+
buf.write("\2\2\2\3=\3\2\2\2\3?\3\2\2\2\4A\3\2\2\2\4C\3\2\2\2\4E")
|
| 76 |
+
buf.write("\3\2\2\2\4G\3\2\2\2\4I\3\2\2\2\4K\3\2\2\2\4M\3\2\2\2\4")
|
| 77 |
+
buf.write("O\3\2\2\2\5Q\3\2\2\2\5S\3\2\2\2\5U\3\2\2\2\5W\3\2\2\2")
|
| 78 |
+
buf.write("\5Y\3\2\2\2\5[\3\2\2\2\5]\3\2\2\2\5_\3\2\2\2\6a\3\2\2")
|
| 79 |
+
buf.write("\2\6c\3\2\2\2\6e\3\2\2\2\6g\3\2\2\2\6i\3\2\2\2\6k\3\2")
|
| 80 |
+
buf.write("\2\2\6m\3\2\2\2\6o\3\2\2\2\7q\3\2\2\2\ts\3\2\2\2\13\u0080")
|
| 81 |
+
buf.write("\3\2\2\2\r\u0082\3\2\2\2\17\u0085\3\2\2\2\21\u008d\3\2")
|
| 82 |
+
buf.write("\2\2\23\u0095\3\2\2\2\25\u009d\3\2\2\2\27\u00a2\3\2\2")
|
| 83 |
+
buf.write("\2\31\u00a8\3\2\2\2\33\u00ac\3\2\2\2\35\u00b4\3\2\2\2")
|
| 84 |
+
buf.write("\37\u00bb\3\2\2\2!\u00c1\3\2\2\2#\u00c5\3\2\2\2%\u00ca")
|
| 85 |
+
buf.write("\3\2\2\2\'\u00d0\3\2\2\2)\u00d5\3\2\2\2+\u00da\3\2\2\2")
|
| 86 |
+
buf.write("-\u00f1\3\2\2\2/\u00f5\3\2\2\2\61\u0106\3\2\2\2\63\u0113")
|
| 87 |
+
buf.write("\3\2\2\2\65\u0120\3\2\2\2\67\u0122\3\2\2\29\u0127\3\2")
|
| 88 |
+
buf.write("\2\2;\u012b\3\2\2\2=\u014c\3\2\2\2?\u0151\3\2\2\2A\u0155")
|
| 89 |
+
buf.write("\3\2\2\2C\u015d\3\2\2\2E\u0167\3\2\2\2G\u016d\3\2\2\2")
|
| 90 |
+
buf.write("I\u016f\3\2\2\2K\u0173\3\2\2\2M\u0177\3\2\2\2O\u017c\3")
|
| 91 |
+
buf.write("\2\2\2Q\u0180\3\2\2\2S\u0185\3\2\2\2U\u018c\3\2\2\2W\u0193")
|
| 92 |
+
buf.write("\3\2\2\2Y\u019a\3\2\2\2[\u01a3\3\2\2\2]\u01a8\3\2\2\2")
|
| 93 |
+
buf.write("_\u01ae\3\2\2\2a\u01b2\3\2\2\2c\u01b7\3\2\2\2e\u01bf\3")
|
| 94 |
+
buf.write("\2\2\2g\u01c6\3\2\2\2i\u01cd\3\2\2\2k\u01d6\3\2\2\2m\u01dd")
|
| 95 |
+
buf.write("\3\2\2\2o\u01e3\3\2\2\2qr\t\2\2\2r\b\3\2\2\2st\t\3\2\2")
|
| 96 |
+
buf.write("t\n\3\2\2\2u\u0081\7\62\2\2v}\t\4\2\2wy\7a\2\2xw\3\2\2")
|
| 97 |
+
buf.write("\2xy\3\2\2\2yz\3\2\2\2z|\5\t\3\2{x\3\2\2\2|\177\3\2\2")
|
| 98 |
+
buf.write("\2}{\3\2\2\2}~\3\2\2\2~\u0081\3\2\2\2\177}\3\2\2\2\u0080")
|
| 99 |
+
buf.write("u\3\2\2\2\u0080v\3\2\2\2\u0081\f\3\2\2\2\u0082\u0083\7")
|
| 100 |
+
buf.write("^\2\2\u0083\u0084\7^\2\2\u0084\16\3\2\2\2\u0085\u0086")
|
| 101 |
+
buf.write("\5\33\f\2\u0086\u0087\3\2\2\2\u0087\u0088\b\6\2\2\u0088")
|
| 102 |
+
buf.write("\u0089\b\6\3\2\u0089\20\3\2\2\2\u008a\u008c\n\5\2\2\u008b")
|
| 103 |
+
buf.write("\u008a\3\2\2\2\u008c\u008f\3\2\2\2\u008d\u008b\3\2\2\2")
|
| 104 |
+
buf.write("\u008d\u008e\3\2\2\2\u008e\u0090\3\2\2\2\u008f\u008d\3")
|
| 105 |
+
buf.write("\2\2\2\u0090\u0091\n\6\2\2\u0091\22\3\2\2\2\u0092\u0094")
|
| 106 |
+
buf.write("\5\r\5\2\u0093\u0092\3\2\2\2\u0094\u0097\3\2\2\2\u0095")
|
| 107 |
+
buf.write("\u0093\3\2\2\2\u0095\u0096\3\2\2\2\u0096\u0098\3\2\2\2")
|
| 108 |
+
buf.write("\u0097\u0095\3\2\2\2\u0098\u0099\7^\2\2\u0099\u009a\7")
|
| 109 |
+
buf.write("&\2\2\u009a\u009b\7}\2\2\u009b\24\3\2\2\2\u009c\u009e")
|
| 110 |
+
buf.write("\5\r\5\2\u009d\u009c\3\2\2\2\u009e\u009f\3\2\2\2\u009f")
|
| 111 |
+
buf.write("\u009d\3\2\2\2\u009f\u00a0\3\2\2\2\u00a0\26\3\2\2\2\u00a1")
|
| 112 |
+
buf.write("\u00a3\7^\2\2\u00a2\u00a1\3\2\2\2\u00a3\u00a4\3\2\2\2")
|
| 113 |
+
buf.write("\u00a4\u00a2\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5\u00a6\3")
|
| 114 |
+
buf.write("\2\2\2\u00a6\u00a7\b\n\4\2\u00a7\30\3\2\2\2\u00a8\u00a9")
|
| 115 |
+
buf.write("\7&\2\2\u00a9\u00aa\3\2\2\2\u00aa\u00ab\b\13\4\2\u00ab")
|
| 116 |
+
buf.write("\32\3\2\2\2\u00ac\u00ad\7&\2\2\u00ad\u00ae\7}\2\2\u00ae")
|
| 117 |
+
buf.write("\u00b0\3\2\2\2\u00af\u00b1\5?\36\2\u00b0\u00af\3\2\2\2")
|
| 118 |
+
buf.write("\u00b0\u00b1\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b3\b")
|
| 119 |
+
buf.write("\f\3\2\u00b3\34\3\2\2\2\u00b4\u00b6\7}\2\2\u00b5\u00b7")
|
| 120 |
+
buf.write("\5?\36\2\u00b6\u00b5\3\2\2\2\u00b6\u00b7\3\2\2\2\u00b7")
|
| 121 |
+
buf.write("\u00b8\3\2\2\2\u00b8\u00b9\b\r\5\2\u00b9\36\3\2\2\2\u00ba")
|
| 122 |
+
buf.write("\u00bc\5?\36\2\u00bb\u00ba\3\2\2\2\u00bb\u00bc\3\2\2\2")
|
| 123 |
+
buf.write("\u00bc\u00bd\3\2\2\2\u00bd\u00be\7\177\2\2\u00be\u00bf")
|
| 124 |
+
buf.write("\3\2\2\2\u00bf\u00c0\b\16\6\2\u00c0 \3\2\2\2\u00c1\u00c2")
|
| 125 |
+
buf.write("\7)\2\2\u00c2\u00c3\3\2\2\2\u00c3\u00c4\b\17\7\2\u00c4")
|
| 126 |
+
buf.write("\"\3\2\2\2\u00c5\u00c6\7$\2\2\u00c6\u00c7\3\2\2\2\u00c7")
|
| 127 |
+
buf.write("\u00c8\b\20\b\2\u00c8$\3\2\2\2\u00c9\u00cb\5?\36\2\u00ca")
|
| 128 |
+
buf.write("\u00c9\3\2\2\2\u00ca\u00cb\3\2\2\2\u00cb\u00cc\3\2\2\2")
|
| 129 |
+
buf.write("\u00cc\u00ce\7.\2\2\u00cd\u00cf\5?\36\2\u00ce\u00cd\3")
|
| 130 |
+
buf.write("\2\2\2\u00ce\u00cf\3\2\2\2\u00cf&\3\2\2\2\u00d0\u00d2")
|
| 131 |
+
buf.write("\7]\2\2\u00d1\u00d3\5?\36\2\u00d2\u00d1\3\2\2\2\u00d2")
|
| 132 |
+
buf.write("\u00d3\3\2\2\2\u00d3(\3\2\2\2\u00d4\u00d6\5?\36\2\u00d5")
|
| 133 |
+
buf.write("\u00d4\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6\u00d7\3\2\2\2")
|
| 134 |
+
buf.write("\u00d7\u00d8\7_\2\2\u00d8*\3\2\2\2\u00d9\u00db\5?\36\2")
|
| 135 |
+
buf.write("\u00da\u00d9\3\2\2\2\u00da\u00db\3\2\2\2\u00db\u00dc\3")
|
| 136 |
+
buf.write("\2\2\2\u00dc\u00de\7<\2\2\u00dd\u00df\5?\36\2\u00de\u00dd")
|
| 137 |
+
buf.write("\3\2\2\2\u00de\u00df\3\2\2\2\u00df,\3\2\2\2\u00e0\u00e1")
|
| 138 |
+
buf.write("\5\13\4\2\u00e1\u00e2\7\60\2\2\u00e2\u00f2\3\2\2\2\u00e3")
|
| 139 |
+
buf.write("\u00e5\5\13\4\2\u00e4\u00e3\3\2\2\2\u00e4\u00e5\3\2\2")
|
| 140 |
+
buf.write("\2\u00e5\u00e6\3\2\2\2\u00e6\u00e7\7\60\2\2\u00e7\u00ee")
|
| 141 |
+
buf.write("\5\t\3\2\u00e8\u00ea\7a\2\2\u00e9\u00e8\3\2\2\2\u00e9")
|
| 142 |
+
buf.write("\u00ea\3\2\2\2\u00ea\u00eb\3\2\2\2\u00eb\u00ed\5\t\3\2")
|
| 143 |
+
buf.write("\u00ec\u00e9\3\2\2\2\u00ed\u00f0\3\2\2\2\u00ee\u00ec\3")
|
| 144 |
+
buf.write("\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f2\3\2\2\2\u00f0\u00ee")
|
| 145 |
+
buf.write("\3\2\2\2\u00f1\u00e0\3\2\2\2\u00f1\u00e4\3\2\2\2\u00f2")
|
| 146 |
+
buf.write(".\3\2\2\2\u00f3\u00f6\5\13\4\2\u00f4\u00f6\5-\25\2\u00f5")
|
| 147 |
+
buf.write("\u00f3\3\2\2\2\u00f5\u00f4\3\2\2\2\u00f6\u00f7\3\2\2\2")
|
| 148 |
+
buf.write("\u00f7\u00f9\t\7\2\2\u00f8\u00fa\t\b\2\2\u00f9\u00f8\3")
|
| 149 |
+
buf.write("\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fb\3\2\2\2\u00fb\u0102")
|
| 150 |
+
buf.write("\5\t\3\2\u00fc\u00fe\7a\2\2\u00fd\u00fc\3\2\2\2\u00fd")
|
| 151 |
+
buf.write("\u00fe\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff\u0101\5\t\3\2")
|
| 152 |
+
buf.write("\u0100\u00fd\3\2\2\2\u0101\u0104\3\2\2\2\u0102\u0100\3")
|
| 153 |
+
buf.write("\2\2\2\u0102\u0103\3\2\2\2\u0103\60\3\2\2\2\u0104\u0102")
|
| 154 |
+
buf.write("\3\2\2\2\u0105\u0107\t\b\2\2\u0106\u0105\3\2\2\2\u0106")
|
| 155 |
+
buf.write("\u0107\3\2\2\2\u0107\u0110\3\2\2\2\u0108\u0111\5-\25\2")
|
| 156 |
+
buf.write("\u0109\u0111\5/\26\2\u010a\u010b\t\t\2\2\u010b\u010c\t")
|
| 157 |
+
buf.write("\n\2\2\u010c\u0111\t\13\2\2\u010d\u010e\t\n\2\2\u010e")
|
| 158 |
+
buf.write("\u010f\t\f\2\2\u010f\u0111\t\n\2\2\u0110\u0108\3\2\2\2")
|
| 159 |
+
buf.write("\u0110\u0109\3\2\2\2\u0110\u010a\3\2\2\2\u0110\u010d\3")
|
| 160 |
+
buf.write("\2\2\2\u0111\62\3\2\2\2\u0112\u0114\t\b\2\2\u0113\u0112")
|
| 161 |
+
buf.write("\3\2\2\2\u0113\u0114\3\2\2\2\u0114\u0115\3\2\2\2\u0115")
|
| 162 |
+
buf.write("\u0116\5\13\4\2\u0116\64\3\2\2\2\u0117\u0118\t\r\2\2\u0118")
|
| 163 |
+
buf.write("\u0119\t\16\2\2\u0119\u011a\t\17\2\2\u011a\u0121\t\7\2")
|
| 164 |
+
buf.write("\2\u011b\u011c\t\13\2\2\u011c\u011d\t\f\2\2\u011d\u011e")
|
| 165 |
+
buf.write("\t\20\2\2\u011e\u011f\t\21\2\2\u011f\u0121\t\7\2\2\u0120")
|
| 166 |
+
buf.write("\u0117\3\2\2\2\u0120\u011b\3\2\2\2\u0121\66\3\2\2\2\u0122")
|
| 167 |
+
buf.write("\u0123\t\n\2\2\u0123\u0124\t\17\2\2\u0124\u0125\t\20\2")
|
| 168 |
+
buf.write("\2\u0125\u0126\t\20\2\2\u01268\3\2\2\2\u0127\u0128\t\22")
|
| 169 |
+
buf.write("\2\2\u0128:\3\2\2\2\u0129\u012c\5\7\2\2\u012a\u012c\7")
|
| 170 |
+
buf.write("a\2\2\u012b\u0129\3\2\2\2\u012b\u012a\3\2\2\2\u012c\u0132")
|
| 171 |
+
buf.write("\3\2\2\2\u012d\u0131\5\7\2\2\u012e\u0131\5\t\3\2\u012f")
|
| 172 |
+
buf.write("\u0131\t\23\2\2\u0130\u012d\3\2\2\2\u0130\u012e\3\2\2")
|
| 173 |
+
buf.write("\2\u0130\u012f\3\2\2\2\u0131\u0134\3\2\2\2\u0132\u0130")
|
| 174 |
+
buf.write("\3\2\2\2\u0132\u0133\3\2\2\2\u0133<\3\2\2\2\u0134\u0132")
|
| 175 |
+
buf.write("\3\2\2\2\u0135\u014d\5\r\5\2\u0136\u0137\7^\2\2\u0137")
|
| 176 |
+
buf.write("\u014d\7*\2\2\u0138\u0139\7^\2\2\u0139\u014d\7+\2\2\u013a")
|
| 177 |
+
buf.write("\u013b\7^\2\2\u013b\u014d\7]\2\2\u013c\u013d\7^\2\2\u013d")
|
| 178 |
+
buf.write("\u014d\7_\2\2\u013e\u013f\7^\2\2\u013f\u014d\7}\2\2\u0140")
|
| 179 |
+
buf.write("\u0141\7^\2\2\u0141\u014d\7\177\2\2\u0142\u0143\7^\2\2")
|
| 180 |
+
buf.write("\u0143\u014d\7<\2\2\u0144\u0145\7^\2\2\u0145\u014d\7?")
|
| 181 |
+
buf.write("\2\2\u0146\u0147\7^\2\2\u0147\u014d\7.\2\2\u0148\u0149")
|
| 182 |
+
buf.write("\7^\2\2\u0149\u014d\7\"\2\2\u014a\u014b\7^\2\2\u014b\u014d")
|
| 183 |
+
buf.write("\7\13\2\2\u014c\u0135\3\2\2\2\u014c\u0136\3\2\2\2\u014c")
|
| 184 |
+
buf.write("\u0138\3\2\2\2\u014c\u013a\3\2\2\2\u014c\u013c\3\2\2\2")
|
| 185 |
+
buf.write("\u014c\u013e\3\2\2\2\u014c\u0140\3\2\2\2\u014c\u0142\3")
|
| 186 |
+
buf.write("\2\2\2\u014c\u0144\3\2\2\2\u014c\u0146\3\2\2\2\u014c\u0148")
|
| 187 |
+
buf.write("\3\2\2\2\u014c\u014a\3\2\2\2\u014d\u014e\3\2\2\2\u014e")
|
| 188 |
+
buf.write("\u014c\3\2\2\2\u014e\u014f\3\2\2\2\u014f>\3\2\2\2\u0150")
|
| 189 |
+
buf.write("\u0152\t\24\2\2\u0151\u0150\3\2\2\2\u0152\u0153\3\2\2")
|
| 190 |
+
buf.write("\2\u0153\u0151\3\2\2\2\u0153\u0154\3\2\2\2\u0154@\3\2")
|
| 191 |
+
buf.write("\2\2\u0155\u0157\5\33\f\2\u0156\u0158\5?\36\2\u0157\u0156")
|
| 192 |
+
buf.write("\3\2\2\2\u0157\u0158\3\2\2\2\u0158\u0159\3\2\2\2\u0159")
|
| 193 |
+
buf.write("\u015a\b\37\2\2\u015a\u015b\b\37\3\2\u015bB\3\2\2\2\u015c")
|
| 194 |
+
buf.write("\u015e\5?\36\2\u015d\u015c\3\2\2\2\u015d\u015e\3\2\2\2")
|
| 195 |
+
buf.write("\u015e\u015f\3\2\2\2\u015f\u0161\7<\2\2\u0160\u0162\5")
|
| 196 |
+
buf.write("?\36\2\u0161\u0160\3\2\2\2\u0161\u0162\3\2\2\2\u0162\u0163")
|
| 197 |
+
buf.write("\3\2\2\2\u0163\u0164\b \t\2\u0164\u0165\b \n\2\u0165D")
|
| 198 |
+
buf.write("\3\2\2\2\u0166\u0168\5?\36\2\u0167\u0166\3\2\2\2\u0167")
|
| 199 |
+
buf.write("\u0168\3\2\2\2\u0168\u0169\3\2\2\2\u0169\u016a\7\177\2")
|
| 200 |
+
buf.write("\2\u016a\u016b\3\2\2\2\u016b\u016c\b!\6\2\u016cF\3\2\2")
|
| 201 |
+
buf.write("\2\u016d\u016e\7\60\2\2\u016eH\3\2\2\2\u016f\u0170\7]")
|
| 202 |
+
buf.write("\2\2\u0170\u0171\3\2\2\2\u0171\u0172\b#\13\2\u0172J\3")
|
| 203 |
+
buf.write("\2\2\2\u0173\u0174\7_\2\2\u0174\u0175\3\2\2\2\u0175\u0176")
|
| 204 |
+
buf.write("\b$\f\2\u0176L\3\2\2\2\u0177\u0178\5;\34\2\u0178\u0179")
|
| 205 |
+
buf.write("\3\2\2\2\u0179\u017a\b%\r\2\u017aN\3\2\2\2\u017b\u017d")
|
| 206 |
+
buf.write("\n\25\2\2\u017c\u017b\3\2\2\2\u017d\u017e\3\2\2\2\u017e")
|
| 207 |
+
buf.write("\u017c\3\2\2\2\u017e\u017f\3\2\2\2\u017fP\3\2\2\2\u0180")
|
| 208 |
+
buf.write("\u0181\5\33\f\2\u0181\u0182\3\2\2\2\u0182\u0183\b\'\2")
|
| 209 |
+
buf.write("\2\u0183\u0184\b\'\3\2\u0184R\3\2\2\2\u0185\u0186\7)\2")
|
| 210 |
+
buf.write("\2\u0186\u0187\3\2\2\2\u0187\u0188\b(\6\2\u0188T\3\2\2")
|
| 211 |
+
buf.write("\2\u0189\u018b\n\26\2\2\u018a\u0189\3\2\2\2\u018b\u018e")
|
| 212 |
+
buf.write("\3\2\2\2\u018c\u018a\3\2\2\2\u018c\u018d\3\2\2\2\u018d")
|
| 213 |
+
buf.write("\u018f\3\2\2\2\u018e\u018c\3\2\2\2\u018f\u0190\n\27\2")
|
| 214 |
+
buf.write("\2\u0190\u0191\3\2\2\2\u0191\u0192\b)\4\2\u0192V\3\2\2")
|
| 215 |
+
buf.write("\2\u0193\u0194\5\23\b\2\u0194\u0195\3\2\2\2\u0195\u0196")
|
| 216 |
+
buf.write("\b*\16\2\u0196X\3\2\2\2\u0197\u0199\5\r\5\2\u0198\u0197")
|
| 217 |
+
buf.write("\3\2\2\2\u0199\u019c\3\2\2\2\u019a\u0198\3\2\2\2\u019a")
|
| 218 |
+
buf.write("\u019b\3\2\2\2\u019b\u019d\3\2\2\2\u019c\u019a\3\2\2\2")
|
| 219 |
+
buf.write("\u019d\u019e\7^\2\2\u019e\u019f\7)\2\2\u019f\u01a0\3\2")
|
| 220 |
+
buf.write("\2\2\u01a0\u01a1\b+\17\2\u01a1Z\3\2\2\2\u01a2\u01a4\5")
|
| 221 |
+
buf.write("\r\5\2\u01a3\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5\u01a3")
|
| 222 |
+
buf.write("\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\\\3\2\2\2\u01a7\u01a9")
|
| 223 |
+
buf.write("\7^\2\2\u01a8\u01a7\3\2\2\2\u01a9\u01aa\3\2\2\2\u01aa")
|
| 224 |
+
buf.write("\u01a8\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab\u01ac\3\2\2\2")
|
| 225 |
+
buf.write("\u01ac\u01ad\b-\4\2\u01ad^\3\2\2\2\u01ae\u01af\7&\2\2")
|
| 226 |
+
buf.write("\u01af\u01b0\3\2\2\2\u01b0\u01b1\b.\4\2\u01b1`\3\2\2\2")
|
| 227 |
+
buf.write("\u01b2\u01b3\5\33\f\2\u01b3\u01b4\3\2\2\2\u01b4\u01b5")
|
| 228 |
+
buf.write("\b/\2\2\u01b5\u01b6\b/\3\2\u01b6b\3\2\2\2\u01b7\u01b8")
|
| 229 |
+
buf.write("\7$\2\2\u01b8\u01b9\3\2\2\2\u01b9\u01ba\b\60\20\2\u01ba")
|
| 230 |
+
buf.write("\u01bb\b\60\6\2\u01bbd\3\2\2\2\u01bc\u01be\n\30\2\2\u01bd")
|
| 231 |
+
buf.write("\u01bc\3\2\2\2\u01be\u01c1\3\2\2\2\u01bf\u01bd\3\2\2\2")
|
| 232 |
+
buf.write("\u01bf\u01c0\3\2\2\2\u01c0\u01c2\3\2\2\2\u01c1\u01bf\3")
|
| 233 |
+
buf.write("\2\2\2\u01c2\u01c3\n\31\2\2\u01c3\u01c4\3\2\2\2\u01c4")
|
| 234 |
+
buf.write("\u01c5\b\61\4\2\u01c5f\3\2\2\2\u01c6\u01c7\5\23\b\2\u01c7")
|
| 235 |
+
buf.write("\u01c8\3\2\2\2\u01c8\u01c9\b\62\16\2\u01c9h\3\2\2\2\u01ca")
|
| 236 |
+
buf.write("\u01cc\5\r\5\2\u01cb\u01ca\3\2\2\2\u01cc\u01cf\3\2\2\2")
|
| 237 |
+
buf.write("\u01cd\u01cb\3\2\2\2\u01cd\u01ce\3\2\2\2\u01ce\u01d0\3")
|
| 238 |
+
buf.write("\2\2\2\u01cf\u01cd\3\2\2\2\u01d0\u01d1\7^\2\2\u01d1\u01d2")
|
| 239 |
+
buf.write("\7$\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d4\b\63\17\2\u01d4")
|
| 240 |
+
buf.write("j\3\2\2\2\u01d5\u01d7\5\r\5\2\u01d6\u01d5\3\2\2\2\u01d7")
|
| 241 |
+
buf.write("\u01d8\3\2\2\2\u01d8\u01d6\3\2\2\2\u01d8\u01d9\3\2\2\2")
|
| 242 |
+
buf.write("\u01d9\u01da\3\2\2\2\u01da\u01db\b\64\21\2\u01dbl\3\2")
|
| 243 |
+
buf.write("\2\2\u01dc\u01de\7^\2\2\u01dd\u01dc\3\2\2\2\u01de\u01df")
|
| 244 |
+
buf.write("\3\2\2\2\u01df\u01dd\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0")
|
| 245 |
+
buf.write("\u01e1\3\2\2\2\u01e1\u01e2\b\65\4\2\u01e2n\3\2\2\2\u01e3")
|
| 246 |
+
buf.write("\u01e4\7&\2\2\u01e4\u01e5\3\2\2\2\u01e5\u01e6\b\66\4\2")
|
| 247 |
+
buf.write("\u01e6p\3\2\2\2\66\2\3\4\5\6x}\u0080\u008d\u0095\u009f")
|
| 248 |
+
buf.write("\u00a4\u00b0\u00b6\u00bb\u00ca\u00ce\u00d2\u00d5\u00da")
|
| 249 |
+
buf.write("\u00de\u00e4\u00e9\u00ee\u00f1\u00f5\u00f9\u00fd\u0102")
|
| 250 |
+
buf.write("\u0106\u0110\u0113\u0120\u012b\u0130\u0132\u014c\u014e")
|
| 251 |
+
buf.write("\u0153\u0157\u015d\u0161\u0167\u017e\u018c\u019a\u01a5")
|
| 252 |
+
buf.write("\u01aa\u01bf\u01cd\u01d8\u01df\22\t\6\2\7\4\2\t\3\2\7")
|
| 253 |
+
buf.write("\3\2\6\2\2\7\5\2\7\6\2\t\16\2\4\3\2\t\f\2\t\r\2\t\24\2")
|
| 254 |
+
buf.write("\t\4\2\t\25\2\t\32\2\t\33\2")
|
| 255 |
+
return buf.getvalue()
|
| 256 |
+
|
| 257 |
+
|
| 258 |
+
class OmegaConfGrammarLexer(Lexer):
|
| 259 |
+
|
| 260 |
+
atn = ATNDeserializer().deserialize(serializedATN())
|
| 261 |
+
|
| 262 |
+
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
| 263 |
+
|
| 264 |
+
VALUE_MODE = 1
|
| 265 |
+
INTERPOLATION_MODE = 2
|
| 266 |
+
QUOTED_SINGLE_MODE = 3
|
| 267 |
+
QUOTED_DOUBLE_MODE = 4
|
| 268 |
+
|
| 269 |
+
ANY_STR = 1
|
| 270 |
+
ESC_INTER = 2
|
| 271 |
+
TOP_ESC = 3
|
| 272 |
+
INTER_OPEN = 4
|
| 273 |
+
BRACE_OPEN = 5
|
| 274 |
+
BRACE_CLOSE = 6
|
| 275 |
+
QUOTE_OPEN_SINGLE = 7
|
| 276 |
+
QUOTE_OPEN_DOUBLE = 8
|
| 277 |
+
COMMA = 9
|
| 278 |
+
BRACKET_OPEN = 10
|
| 279 |
+
BRACKET_CLOSE = 11
|
| 280 |
+
COLON = 12
|
| 281 |
+
FLOAT = 13
|
| 282 |
+
INT = 14
|
| 283 |
+
BOOL = 15
|
| 284 |
+
NULL = 16
|
| 285 |
+
UNQUOTED_CHAR = 17
|
| 286 |
+
ID = 18
|
| 287 |
+
ESC = 19
|
| 288 |
+
WS = 20
|
| 289 |
+
INTER_CLOSE = 21
|
| 290 |
+
DOT = 22
|
| 291 |
+
INTER_KEY = 23
|
| 292 |
+
MATCHING_QUOTE_CLOSE = 24
|
| 293 |
+
QUOTED_ESC = 25
|
| 294 |
+
DOLLAR = 26
|
| 295 |
+
INTER_BRACKET_OPEN = 27
|
| 296 |
+
INTER_BRACKET_CLOSE = 28
|
| 297 |
+
|
| 298 |
+
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
|
| 299 |
+
|
| 300 |
+
modeNames = [ "DEFAULT_MODE", "VALUE_MODE", "INTERPOLATION_MODE", "QUOTED_SINGLE_MODE",
|
| 301 |
+
"QUOTED_DOUBLE_MODE" ]
|
| 302 |
+
|
| 303 |
+
literalNames = [ "<INVALID>",
|
| 304 |
+
"'.'", "'['", "']'" ]
|
| 305 |
+
|
| 306 |
+
symbolicNames = [ "<INVALID>",
|
| 307 |
+
"ANY_STR", "ESC_INTER", "TOP_ESC", "INTER_OPEN", "BRACE_OPEN",
|
| 308 |
+
"BRACE_CLOSE", "QUOTE_OPEN_SINGLE", "QUOTE_OPEN_DOUBLE", "COMMA",
|
| 309 |
+
"BRACKET_OPEN", "BRACKET_CLOSE", "COLON", "FLOAT", "INT", "BOOL",
|
| 310 |
+
"NULL", "UNQUOTED_CHAR", "ID", "ESC", "WS", "INTER_CLOSE", "DOT",
|
| 311 |
+
"INTER_KEY", "MATCHING_QUOTE_CLOSE", "QUOTED_ESC", "DOLLAR",
|
| 312 |
+
"INTER_BRACKET_OPEN", "INTER_BRACKET_CLOSE" ]
|
| 313 |
+
|
| 314 |
+
ruleNames = [ "CHAR", "DIGIT", "INT_UNSIGNED", "ESC_BACKSLASH", "TOP_INTER_OPEN",
|
| 315 |
+
"ANY_STR", "ESC_INTER", "TOP_ESC", "BACKSLASHES", "DOLLAR",
|
| 316 |
+
"INTER_OPEN", "BRACE_OPEN", "BRACE_CLOSE", "QUOTE_OPEN_SINGLE",
|
| 317 |
+
"QUOTE_OPEN_DOUBLE", "COMMA", "BRACKET_OPEN", "BRACKET_CLOSE",
|
| 318 |
+
"COLON", "POINT_FLOAT", "EXPONENT_FLOAT", "FLOAT", "INT",
|
| 319 |
+
"BOOL", "NULL", "UNQUOTED_CHAR", "ID", "ESC", "WS", "NESTED_INTER_OPEN",
|
| 320 |
+
"INTER_COLON", "INTER_CLOSE", "DOT", "INTER_BRACKET_OPEN",
|
| 321 |
+
"INTER_BRACKET_CLOSE", "INTER_ID", "INTER_KEY", "QSINGLE_INTER_OPEN",
|
| 322 |
+
"MATCHING_QUOTE_CLOSE", "QSINGLE_STR", "QSINGLE_ESC_INTER",
|
| 323 |
+
"QSINGLE_ESC_QUOTE", "QUOTED_ESC", "QSINGLE_BACKSLASHES",
|
| 324 |
+
"QSINGLE_DOLLAR", "QDOUBLE_INTER_OPEN", "QDOUBLE_CLOSE",
|
| 325 |
+
"QDOUBLE_STR", "QDOUBLE_ESC_INTER", "QDOUBLE_ESC_QUOTE",
|
| 326 |
+
"QDOUBLE_ESC", "QDOUBLE_BACKSLASHES", "QDOUBLE_DOLLAR" ]
|
| 327 |
+
|
| 328 |
+
grammarFileName = "OmegaConfGrammarLexer.g4"
|
| 329 |
+
|
| 330 |
+
def __init__(self, input=None, output:TextIO = sys.stdout):
|
| 331 |
+
super().__init__(input, output)
|
| 332 |
+
self.checkVersion("4.9.3")
|
| 333 |
+
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
|
| 334 |
+
self._actions = None
|
| 335 |
+
self._predicates = None
|
| 336 |
+
|
| 337 |
+
|
lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParser.py
ADDED
|
@@ -0,0 +1,1595 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated from /tmp/build-via-sdist-fm63w174/omegaconf-2.3.0/omegaconf/grammar/OmegaConfGrammarParser.g4 by ANTLR 4.9.3
|
| 2 |
+
# encoding: utf-8
|
| 3 |
+
from antlr4 import *
|
| 4 |
+
from io import StringIO
|
| 5 |
+
import sys
|
| 6 |
+
if sys.version_info[1] > 5:
|
| 7 |
+
from typing import TextIO
|
| 8 |
+
else:
|
| 9 |
+
from typing.io import TextIO
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def serializedATN():
|
| 13 |
+
with StringIO() as buf:
|
| 14 |
+
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\36")
|
| 15 |
+
buf.write("\u00b7\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
|
| 16 |
+
buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
|
| 17 |
+
buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\3\2\3\2\3\2\3\3\3")
|
| 18 |
+
buf.write("\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\6\4/\n\4\r\4\16\4\60\3")
|
| 19 |
+
buf.write("\5\3\5\3\5\3\5\5\5\67\n\5\3\6\3\6\5\6;\n\6\3\6\3\6\3\7")
|
| 20 |
+
buf.write("\3\7\3\7\3\7\7\7C\n\7\f\7\16\7F\13\7\5\7H\n\7\3\7\3\7")
|
| 21 |
+
buf.write("\3\b\3\b\3\b\3\b\3\t\3\t\3\t\5\tS\n\t\7\tU\n\t\f\t\16")
|
| 22 |
+
buf.write("\tX\13\t\3\t\3\t\5\t\\\n\t\6\t^\n\t\r\t\16\t_\5\tb\n\t")
|
| 23 |
+
buf.write("\3\n\3\n\5\nf\n\n\3\13\3\13\7\13j\n\13\f\13\16\13m\13")
|
| 24 |
+
buf.write("\13\3\13\3\13\3\13\3\13\3\13\5\13t\n\13\3\13\3\13\3\13")
|
| 25 |
+
buf.write("\3\13\3\13\3\13\7\13|\n\13\f\13\16\13\177\13\13\3\13\3")
|
| 26 |
+
buf.write("\13\3\f\3\f\3\f\3\f\5\f\u0087\n\f\3\f\3\f\3\r\3\r\3\r")
|
| 27 |
+
buf.write("\5\r\u008e\n\r\3\16\3\16\5\16\u0092\n\16\3\16\3\16\3\16")
|
| 28 |
+
buf.write("\5\16\u0097\n\16\7\16\u0099\n\16\f\16\16\16\u009c\13\16")
|
| 29 |
+
buf.write("\3\17\3\17\5\17\u00a0\n\17\3\17\3\17\3\20\3\20\3\20\3")
|
| 30 |
+
buf.write("\20\3\20\3\20\3\20\3\20\3\20\3\20\6\20\u00ae\n\20\r\20")
|
| 31 |
+
buf.write("\16\20\u00af\3\21\6\21\u00b3\n\21\r\21\16\21\u00b4\3\21")
|
| 32 |
+
buf.write("\2\2\22\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \2\4\3")
|
| 33 |
+
buf.write("\2\t\n\3\2\17\26\2\u00ce\2\"\3\2\2\2\4%\3\2\2\2\6.\3\2")
|
| 34 |
+
buf.write("\2\2\b\66\3\2\2\2\n8\3\2\2\2\f>\3\2\2\2\16K\3\2\2\2\20")
|
| 35 |
+
buf.write("a\3\2\2\2\22e\3\2\2\2\24g\3\2\2\2\26\u0082\3\2\2\2\30")
|
| 36 |
+
buf.write("\u008d\3\2\2\2\32\u0091\3\2\2\2\34\u009d\3\2\2\2\36\u00ad")
|
| 37 |
+
buf.write("\3\2\2\2 \u00b2\3\2\2\2\"#\5\6\4\2#$\7\2\2\3$\3\3\2\2")
|
| 38 |
+
buf.write("\2%&\5\b\5\2&\'\7\2\2\3\'\5\3\2\2\2(/\5\22\n\2)/\7\3\2")
|
| 39 |
+
buf.write("\2*/\7\25\2\2+/\7\4\2\2,/\7\5\2\2-/\7\33\2\2.(\3\2\2\2")
|
| 40 |
+
buf.write(".)\3\2\2\2.*\3\2\2\2.+\3\2\2\2.,\3\2\2\2.-\3\2\2\2/\60")
|
| 41 |
+
buf.write("\3\2\2\2\60.\3\2\2\2\60\61\3\2\2\2\61\7\3\2\2\2\62\67")
|
| 42 |
+
buf.write("\5\36\20\2\63\67\5\34\17\2\64\67\5\n\6\2\65\67\5\f\7\2")
|
| 43 |
+
buf.write("\66\62\3\2\2\2\66\63\3\2\2\2\66\64\3\2\2\2\66\65\3\2\2")
|
| 44 |
+
buf.write("\2\67\t\3\2\2\28:\7\f\2\29;\5\20\t\2:9\3\2\2\2:;\3\2\2")
|
| 45 |
+
buf.write("\2;<\3\2\2\2<=\7\r\2\2=\13\3\2\2\2>G\7\7\2\2?D\5\16\b")
|
| 46 |
+
buf.write("\2@A\7\13\2\2AC\5\16\b\2B@\3\2\2\2CF\3\2\2\2DB\3\2\2\2")
|
| 47 |
+
buf.write("DE\3\2\2\2EH\3\2\2\2FD\3\2\2\2G?\3\2\2\2GH\3\2\2\2HI\3")
|
| 48 |
+
buf.write("\2\2\2IJ\7\b\2\2J\r\3\2\2\2KL\5 \21\2LM\7\16\2\2MN\5\b")
|
| 49 |
+
buf.write("\5\2N\17\3\2\2\2OV\5\b\5\2PR\7\13\2\2QS\5\b\5\2RQ\3\2")
|
| 50 |
+
buf.write("\2\2RS\3\2\2\2SU\3\2\2\2TP\3\2\2\2UX\3\2\2\2VT\3\2\2\2")
|
| 51 |
+
buf.write("VW\3\2\2\2Wb\3\2\2\2XV\3\2\2\2Y[\7\13\2\2Z\\\5\b\5\2[")
|
| 52 |
+
buf.write("Z\3\2\2\2[\\\3\2\2\2\\^\3\2\2\2]Y\3\2\2\2^_\3\2\2\2_]")
|
| 53 |
+
buf.write("\3\2\2\2_`\3\2\2\2`b\3\2\2\2aO\3\2\2\2a]\3\2\2\2b\21\3")
|
| 54 |
+
buf.write("\2\2\2cf\5\24\13\2df\5\26\f\2ec\3\2\2\2ed\3\2\2\2f\23")
|
| 55 |
+
buf.write("\3\2\2\2gk\7\6\2\2hj\7\30\2\2ih\3\2\2\2jm\3\2\2\2ki\3")
|
| 56 |
+
buf.write("\2\2\2kl\3\2\2\2ls\3\2\2\2mk\3\2\2\2nt\5\30\r\2op\7\f")
|
| 57 |
+
buf.write("\2\2pq\5\30\r\2qr\7\r\2\2rt\3\2\2\2sn\3\2\2\2so\3\2\2")
|
| 58 |
+
buf.write("\2t}\3\2\2\2uv\7\30\2\2v|\5\30\r\2wx\7\f\2\2xy\5\30\r")
|
| 59 |
+
buf.write("\2yz\7\r\2\2z|\3\2\2\2{u\3\2\2\2{w\3\2\2\2|\177\3\2\2")
|
| 60 |
+
buf.write("\2}{\3\2\2\2}~\3\2\2\2~\u0080\3\2\2\2\177}\3\2\2\2\u0080")
|
| 61 |
+
buf.write("\u0081\7\27\2\2\u0081\25\3\2\2\2\u0082\u0083\7\6\2\2\u0083")
|
| 62 |
+
buf.write("\u0084\5\32\16\2\u0084\u0086\7\16\2\2\u0085\u0087\5\20")
|
| 63 |
+
buf.write("\t\2\u0086\u0085\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u0088")
|
| 64 |
+
buf.write("\3\2\2\2\u0088\u0089\7\b\2\2\u0089\27\3\2\2\2\u008a\u008e")
|
| 65 |
+
buf.write("\5\22\n\2\u008b\u008e\7\24\2\2\u008c\u008e\7\31\2\2\u008d")
|
| 66 |
+
buf.write("\u008a\3\2\2\2\u008d\u008b\3\2\2\2\u008d\u008c\3\2\2\2")
|
| 67 |
+
buf.write("\u008e\31\3\2\2\2\u008f\u0092\5\22\n\2\u0090\u0092\7\24")
|
| 68 |
+
buf.write("\2\2\u0091\u008f\3\2\2\2\u0091\u0090\3\2\2\2\u0092\u009a")
|
| 69 |
+
buf.write("\3\2\2\2\u0093\u0096\7\30\2\2\u0094\u0097\5\22\n\2\u0095")
|
| 70 |
+
buf.write("\u0097\7\24\2\2\u0096\u0094\3\2\2\2\u0096\u0095\3\2\2")
|
| 71 |
+
buf.write("\2\u0097\u0099\3\2\2\2\u0098\u0093\3\2\2\2\u0099\u009c")
|
| 72 |
+
buf.write("\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b\3\2\2\2\u009b")
|
| 73 |
+
buf.write("\33\3\2\2\2\u009c\u009a\3\2\2\2\u009d\u009f\t\2\2\2\u009e")
|
| 74 |
+
buf.write("\u00a0\5\6\4\2\u009f\u009e\3\2\2\2\u009f\u00a0\3\2\2\2")
|
| 75 |
+
buf.write("\u00a0\u00a1\3\2\2\2\u00a1\u00a2\7\32\2\2\u00a2\35\3\2")
|
| 76 |
+
buf.write("\2\2\u00a3\u00ae\7\24\2\2\u00a4\u00ae\7\22\2\2\u00a5\u00ae")
|
| 77 |
+
buf.write("\7\20\2\2\u00a6\u00ae\7\17\2\2\u00a7\u00ae\7\21\2\2\u00a8")
|
| 78 |
+
buf.write("\u00ae\7\23\2\2\u00a9\u00ae\7\16\2\2\u00aa\u00ae\7\25")
|
| 79 |
+
buf.write("\2\2\u00ab\u00ae\7\26\2\2\u00ac\u00ae\5\22\n\2\u00ad\u00a3")
|
| 80 |
+
buf.write("\3\2\2\2\u00ad\u00a4\3\2\2\2\u00ad\u00a5\3\2\2\2\u00ad")
|
| 81 |
+
buf.write("\u00a6\3\2\2\2\u00ad\u00a7\3\2\2\2\u00ad\u00a8\3\2\2\2")
|
| 82 |
+
buf.write("\u00ad\u00a9\3\2\2\2\u00ad\u00aa\3\2\2\2\u00ad\u00ab\3")
|
| 83 |
+
buf.write("\2\2\2\u00ad\u00ac\3\2\2\2\u00ae\u00af\3\2\2\2\u00af\u00ad")
|
| 84 |
+
buf.write("\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\37\3\2\2\2\u00b1\u00b3")
|
| 85 |
+
buf.write("\t\3\2\2\u00b2\u00b1\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4")
|
| 86 |
+
buf.write("\u00b2\3\2\2\2\u00b4\u00b5\3\2\2\2\u00b5!\3\2\2\2\33.")
|
| 87 |
+
buf.write("\60\66:DGRV[_aeks{}\u0086\u008d\u0091\u0096\u009a\u009f")
|
| 88 |
+
buf.write("\u00ad\u00af\u00b4")
|
| 89 |
+
return buf.getvalue()
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
class OmegaConfGrammarParser ( Parser ):
|
| 93 |
+
|
| 94 |
+
grammarFileName = "OmegaConfGrammarParser.g4"
|
| 95 |
+
|
| 96 |
+
atn = ATNDeserializer().deserialize(serializedATN())
|
| 97 |
+
|
| 98 |
+
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
|
| 99 |
+
|
| 100 |
+
sharedContextCache = PredictionContextCache()
|
| 101 |
+
|
| 102 |
+
literalNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
|
| 103 |
+
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
|
| 104 |
+
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
|
| 105 |
+
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
|
| 106 |
+
"<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>",
|
| 107 |
+
"<INVALID>", "<INVALID>", "'.'", "<INVALID>", "<INVALID>",
|
| 108 |
+
"<INVALID>", "<INVALID>", "'['", "']'" ]
|
| 109 |
+
|
| 110 |
+
symbolicNames = [ "<INVALID>", "ANY_STR", "ESC_INTER", "TOP_ESC", "INTER_OPEN",
|
| 111 |
+
"BRACE_OPEN", "BRACE_CLOSE", "QUOTE_OPEN_SINGLE",
|
| 112 |
+
"QUOTE_OPEN_DOUBLE", "COMMA", "BRACKET_OPEN", "BRACKET_CLOSE",
|
| 113 |
+
"COLON", "FLOAT", "INT", "BOOL", "NULL", "UNQUOTED_CHAR",
|
| 114 |
+
"ID", "ESC", "WS", "INTER_CLOSE", "DOT", "INTER_KEY",
|
| 115 |
+
"MATCHING_QUOTE_CLOSE", "QUOTED_ESC", "DOLLAR", "INTER_BRACKET_OPEN",
|
| 116 |
+
"INTER_BRACKET_CLOSE" ]
|
| 117 |
+
|
| 118 |
+
RULE_configValue = 0
|
| 119 |
+
RULE_singleElement = 1
|
| 120 |
+
RULE_text = 2
|
| 121 |
+
RULE_element = 3
|
| 122 |
+
RULE_listContainer = 4
|
| 123 |
+
RULE_dictContainer = 5
|
| 124 |
+
RULE_dictKeyValuePair = 6
|
| 125 |
+
RULE_sequence = 7
|
| 126 |
+
RULE_interpolation = 8
|
| 127 |
+
RULE_interpolationNode = 9
|
| 128 |
+
RULE_interpolationResolver = 10
|
| 129 |
+
RULE_configKey = 11
|
| 130 |
+
RULE_resolverName = 12
|
| 131 |
+
RULE_quotedValue = 13
|
| 132 |
+
RULE_primitive = 14
|
| 133 |
+
RULE_dictKey = 15
|
| 134 |
+
|
| 135 |
+
ruleNames = [ "configValue", "singleElement", "text", "element", "listContainer",
|
| 136 |
+
"dictContainer", "dictKeyValuePair", "sequence", "interpolation",
|
| 137 |
+
"interpolationNode", "interpolationResolver", "configKey",
|
| 138 |
+
"resolverName", "quotedValue", "primitive", "dictKey" ]
|
| 139 |
+
|
| 140 |
+
EOF = Token.EOF
|
| 141 |
+
ANY_STR=1
|
| 142 |
+
ESC_INTER=2
|
| 143 |
+
TOP_ESC=3
|
| 144 |
+
INTER_OPEN=4
|
| 145 |
+
BRACE_OPEN=5
|
| 146 |
+
BRACE_CLOSE=6
|
| 147 |
+
QUOTE_OPEN_SINGLE=7
|
| 148 |
+
QUOTE_OPEN_DOUBLE=8
|
| 149 |
+
COMMA=9
|
| 150 |
+
BRACKET_OPEN=10
|
| 151 |
+
BRACKET_CLOSE=11
|
| 152 |
+
COLON=12
|
| 153 |
+
FLOAT=13
|
| 154 |
+
INT=14
|
| 155 |
+
BOOL=15
|
| 156 |
+
NULL=16
|
| 157 |
+
UNQUOTED_CHAR=17
|
| 158 |
+
ID=18
|
| 159 |
+
ESC=19
|
| 160 |
+
WS=20
|
| 161 |
+
INTER_CLOSE=21
|
| 162 |
+
DOT=22
|
| 163 |
+
INTER_KEY=23
|
| 164 |
+
MATCHING_QUOTE_CLOSE=24
|
| 165 |
+
QUOTED_ESC=25
|
| 166 |
+
DOLLAR=26
|
| 167 |
+
INTER_BRACKET_OPEN=27
|
| 168 |
+
INTER_BRACKET_CLOSE=28
|
| 169 |
+
|
| 170 |
+
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
|
| 171 |
+
super().__init__(input, output)
|
| 172 |
+
self.checkVersion("4.9.3")
|
| 173 |
+
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
|
| 174 |
+
self._predicates = None
|
| 175 |
+
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
class ConfigValueContext(ParserRuleContext):
|
| 180 |
+
__slots__ = 'parser'
|
| 181 |
+
|
| 182 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 183 |
+
super().__init__(parent, invokingState)
|
| 184 |
+
self.parser = parser
|
| 185 |
+
|
| 186 |
+
def text(self):
|
| 187 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.TextContext,0)
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
def EOF(self):
|
| 191 |
+
return self.getToken(OmegaConfGrammarParser.EOF, 0)
|
| 192 |
+
|
| 193 |
+
def getRuleIndex(self):
|
| 194 |
+
return OmegaConfGrammarParser.RULE_configValue
|
| 195 |
+
|
| 196 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 197 |
+
if hasattr( listener, "enterConfigValue" ):
|
| 198 |
+
listener.enterConfigValue(self)
|
| 199 |
+
|
| 200 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 201 |
+
if hasattr( listener, "exitConfigValue" ):
|
| 202 |
+
listener.exitConfigValue(self)
|
| 203 |
+
|
| 204 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 205 |
+
if hasattr( visitor, "visitConfigValue" ):
|
| 206 |
+
return visitor.visitConfigValue(self)
|
| 207 |
+
else:
|
| 208 |
+
return visitor.visitChildren(self)
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
|
| 213 |
+
def configValue(self):
|
| 214 |
+
|
| 215 |
+
localctx = OmegaConfGrammarParser.ConfigValueContext(self, self._ctx, self.state)
|
| 216 |
+
self.enterRule(localctx, 0, self.RULE_configValue)
|
| 217 |
+
try:
|
| 218 |
+
self.enterOuterAlt(localctx, 1)
|
| 219 |
+
self.state = 32
|
| 220 |
+
self.text()
|
| 221 |
+
self.state = 33
|
| 222 |
+
self.match(OmegaConfGrammarParser.EOF)
|
| 223 |
+
except RecognitionException as re:
|
| 224 |
+
localctx.exception = re
|
| 225 |
+
self._errHandler.reportError(self, re)
|
| 226 |
+
self._errHandler.recover(self, re)
|
| 227 |
+
finally:
|
| 228 |
+
self.exitRule()
|
| 229 |
+
return localctx
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
class SingleElementContext(ParserRuleContext):
|
| 233 |
+
__slots__ = 'parser'
|
| 234 |
+
|
| 235 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 236 |
+
super().__init__(parent, invokingState)
|
| 237 |
+
self.parser = parser
|
| 238 |
+
|
| 239 |
+
def element(self):
|
| 240 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ElementContext,0)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
def EOF(self):
|
| 244 |
+
return self.getToken(OmegaConfGrammarParser.EOF, 0)
|
| 245 |
+
|
| 246 |
+
def getRuleIndex(self):
|
| 247 |
+
return OmegaConfGrammarParser.RULE_singleElement
|
| 248 |
+
|
| 249 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 250 |
+
if hasattr( listener, "enterSingleElement" ):
|
| 251 |
+
listener.enterSingleElement(self)
|
| 252 |
+
|
| 253 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 254 |
+
if hasattr( listener, "exitSingleElement" ):
|
| 255 |
+
listener.exitSingleElement(self)
|
| 256 |
+
|
| 257 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 258 |
+
if hasattr( visitor, "visitSingleElement" ):
|
| 259 |
+
return visitor.visitSingleElement(self)
|
| 260 |
+
else:
|
| 261 |
+
return visitor.visitChildren(self)
|
| 262 |
+
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
def singleElement(self):
|
| 267 |
+
|
| 268 |
+
localctx = OmegaConfGrammarParser.SingleElementContext(self, self._ctx, self.state)
|
| 269 |
+
self.enterRule(localctx, 2, self.RULE_singleElement)
|
| 270 |
+
try:
|
| 271 |
+
self.enterOuterAlt(localctx, 1)
|
| 272 |
+
self.state = 35
|
| 273 |
+
self.element()
|
| 274 |
+
self.state = 36
|
| 275 |
+
self.match(OmegaConfGrammarParser.EOF)
|
| 276 |
+
except RecognitionException as re:
|
| 277 |
+
localctx.exception = re
|
| 278 |
+
self._errHandler.reportError(self, re)
|
| 279 |
+
self._errHandler.recover(self, re)
|
| 280 |
+
finally:
|
| 281 |
+
self.exitRule()
|
| 282 |
+
return localctx
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
class TextContext(ParserRuleContext):
|
| 286 |
+
__slots__ = 'parser'
|
| 287 |
+
|
| 288 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 289 |
+
super().__init__(parent, invokingState)
|
| 290 |
+
self.parser = parser
|
| 291 |
+
|
| 292 |
+
def interpolation(self, i:int=None):
|
| 293 |
+
if i is None:
|
| 294 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.InterpolationContext)
|
| 295 |
+
else:
|
| 296 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationContext,i)
|
| 297 |
+
|
| 298 |
+
|
| 299 |
+
def ANY_STR(self, i:int=None):
|
| 300 |
+
if i is None:
|
| 301 |
+
return self.getTokens(OmegaConfGrammarParser.ANY_STR)
|
| 302 |
+
else:
|
| 303 |
+
return self.getToken(OmegaConfGrammarParser.ANY_STR, i)
|
| 304 |
+
|
| 305 |
+
def ESC(self, i:int=None):
|
| 306 |
+
if i is None:
|
| 307 |
+
return self.getTokens(OmegaConfGrammarParser.ESC)
|
| 308 |
+
else:
|
| 309 |
+
return self.getToken(OmegaConfGrammarParser.ESC, i)
|
| 310 |
+
|
| 311 |
+
def ESC_INTER(self, i:int=None):
|
| 312 |
+
if i is None:
|
| 313 |
+
return self.getTokens(OmegaConfGrammarParser.ESC_INTER)
|
| 314 |
+
else:
|
| 315 |
+
return self.getToken(OmegaConfGrammarParser.ESC_INTER, i)
|
| 316 |
+
|
| 317 |
+
def TOP_ESC(self, i:int=None):
|
| 318 |
+
if i is None:
|
| 319 |
+
return self.getTokens(OmegaConfGrammarParser.TOP_ESC)
|
| 320 |
+
else:
|
| 321 |
+
return self.getToken(OmegaConfGrammarParser.TOP_ESC, i)
|
| 322 |
+
|
| 323 |
+
def QUOTED_ESC(self, i:int=None):
|
| 324 |
+
if i is None:
|
| 325 |
+
return self.getTokens(OmegaConfGrammarParser.QUOTED_ESC)
|
| 326 |
+
else:
|
| 327 |
+
return self.getToken(OmegaConfGrammarParser.QUOTED_ESC, i)
|
| 328 |
+
|
| 329 |
+
def getRuleIndex(self):
|
| 330 |
+
return OmegaConfGrammarParser.RULE_text
|
| 331 |
+
|
| 332 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 333 |
+
if hasattr( listener, "enterText" ):
|
| 334 |
+
listener.enterText(self)
|
| 335 |
+
|
| 336 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 337 |
+
if hasattr( listener, "exitText" ):
|
| 338 |
+
listener.exitText(self)
|
| 339 |
+
|
| 340 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 341 |
+
if hasattr( visitor, "visitText" ):
|
| 342 |
+
return visitor.visitText(self)
|
| 343 |
+
else:
|
| 344 |
+
return visitor.visitChildren(self)
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
def text(self):
|
| 350 |
+
|
| 351 |
+
localctx = OmegaConfGrammarParser.TextContext(self, self._ctx, self.state)
|
| 352 |
+
self.enterRule(localctx, 4, self.RULE_text)
|
| 353 |
+
self._la = 0 # Token type
|
| 354 |
+
try:
|
| 355 |
+
self.enterOuterAlt(localctx, 1)
|
| 356 |
+
self.state = 44
|
| 357 |
+
self._errHandler.sync(self)
|
| 358 |
+
_la = self._input.LA(1)
|
| 359 |
+
while True:
|
| 360 |
+
self.state = 44
|
| 361 |
+
self._errHandler.sync(self)
|
| 362 |
+
token = self._input.LA(1)
|
| 363 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN]:
|
| 364 |
+
self.state = 38
|
| 365 |
+
self.interpolation()
|
| 366 |
+
pass
|
| 367 |
+
elif token in [OmegaConfGrammarParser.ANY_STR]:
|
| 368 |
+
self.state = 39
|
| 369 |
+
self.match(OmegaConfGrammarParser.ANY_STR)
|
| 370 |
+
pass
|
| 371 |
+
elif token in [OmegaConfGrammarParser.ESC]:
|
| 372 |
+
self.state = 40
|
| 373 |
+
self.match(OmegaConfGrammarParser.ESC)
|
| 374 |
+
pass
|
| 375 |
+
elif token in [OmegaConfGrammarParser.ESC_INTER]:
|
| 376 |
+
self.state = 41
|
| 377 |
+
self.match(OmegaConfGrammarParser.ESC_INTER)
|
| 378 |
+
pass
|
| 379 |
+
elif token in [OmegaConfGrammarParser.TOP_ESC]:
|
| 380 |
+
self.state = 42
|
| 381 |
+
self.match(OmegaConfGrammarParser.TOP_ESC)
|
| 382 |
+
pass
|
| 383 |
+
elif token in [OmegaConfGrammarParser.QUOTED_ESC]:
|
| 384 |
+
self.state = 43
|
| 385 |
+
self.match(OmegaConfGrammarParser.QUOTED_ESC)
|
| 386 |
+
pass
|
| 387 |
+
else:
|
| 388 |
+
raise NoViableAltException(self)
|
| 389 |
+
|
| 390 |
+
self.state = 46
|
| 391 |
+
self._errHandler.sync(self)
|
| 392 |
+
_la = self._input.LA(1)
|
| 393 |
+
if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.ANY_STR) | (1 << OmegaConfGrammarParser.ESC_INTER) | (1 << OmegaConfGrammarParser.TOP_ESC) | (1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.QUOTED_ESC))) != 0)):
|
| 394 |
+
break
|
| 395 |
+
|
| 396 |
+
except RecognitionException as re:
|
| 397 |
+
localctx.exception = re
|
| 398 |
+
self._errHandler.reportError(self, re)
|
| 399 |
+
self._errHandler.recover(self, re)
|
| 400 |
+
finally:
|
| 401 |
+
self.exitRule()
|
| 402 |
+
return localctx
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
class ElementContext(ParserRuleContext):
|
| 406 |
+
__slots__ = 'parser'
|
| 407 |
+
|
| 408 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 409 |
+
super().__init__(parent, invokingState)
|
| 410 |
+
self.parser = parser
|
| 411 |
+
|
| 412 |
+
def primitive(self):
|
| 413 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.PrimitiveContext,0)
|
| 414 |
+
|
| 415 |
+
|
| 416 |
+
def quotedValue(self):
|
| 417 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.QuotedValueContext,0)
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
def listContainer(self):
|
| 421 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ListContainerContext,0)
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
def dictContainer(self):
|
| 425 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.DictContainerContext,0)
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
def getRuleIndex(self):
|
| 429 |
+
return OmegaConfGrammarParser.RULE_element
|
| 430 |
+
|
| 431 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 432 |
+
if hasattr( listener, "enterElement" ):
|
| 433 |
+
listener.enterElement(self)
|
| 434 |
+
|
| 435 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 436 |
+
if hasattr( listener, "exitElement" ):
|
| 437 |
+
listener.exitElement(self)
|
| 438 |
+
|
| 439 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 440 |
+
if hasattr( visitor, "visitElement" ):
|
| 441 |
+
return visitor.visitElement(self)
|
| 442 |
+
else:
|
| 443 |
+
return visitor.visitChildren(self)
|
| 444 |
+
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
def element(self):
|
| 449 |
+
|
| 450 |
+
localctx = OmegaConfGrammarParser.ElementContext(self, self._ctx, self.state)
|
| 451 |
+
self.enterRule(localctx, 6, self.RULE_element)
|
| 452 |
+
try:
|
| 453 |
+
self.state = 52
|
| 454 |
+
self._errHandler.sync(self)
|
| 455 |
+
token = self._input.LA(1)
|
| 456 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN, OmegaConfGrammarParser.COLON, OmegaConfGrammarParser.FLOAT, OmegaConfGrammarParser.INT, OmegaConfGrammarParser.BOOL, OmegaConfGrammarParser.NULL, OmegaConfGrammarParser.UNQUOTED_CHAR, OmegaConfGrammarParser.ID, OmegaConfGrammarParser.ESC, OmegaConfGrammarParser.WS]:
|
| 457 |
+
self.enterOuterAlt(localctx, 1)
|
| 458 |
+
self.state = 48
|
| 459 |
+
self.primitive()
|
| 460 |
+
pass
|
| 461 |
+
elif token in [OmegaConfGrammarParser.QUOTE_OPEN_SINGLE, OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE]:
|
| 462 |
+
self.enterOuterAlt(localctx, 2)
|
| 463 |
+
self.state = 49
|
| 464 |
+
self.quotedValue()
|
| 465 |
+
pass
|
| 466 |
+
elif token in [OmegaConfGrammarParser.BRACKET_OPEN]:
|
| 467 |
+
self.enterOuterAlt(localctx, 3)
|
| 468 |
+
self.state = 50
|
| 469 |
+
self.listContainer()
|
| 470 |
+
pass
|
| 471 |
+
elif token in [OmegaConfGrammarParser.BRACE_OPEN]:
|
| 472 |
+
self.enterOuterAlt(localctx, 4)
|
| 473 |
+
self.state = 51
|
| 474 |
+
self.dictContainer()
|
| 475 |
+
pass
|
| 476 |
+
else:
|
| 477 |
+
raise NoViableAltException(self)
|
| 478 |
+
|
| 479 |
+
except RecognitionException as re:
|
| 480 |
+
localctx.exception = re
|
| 481 |
+
self._errHandler.reportError(self, re)
|
| 482 |
+
self._errHandler.recover(self, re)
|
| 483 |
+
finally:
|
| 484 |
+
self.exitRule()
|
| 485 |
+
return localctx
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
class ListContainerContext(ParserRuleContext):
|
| 489 |
+
__slots__ = 'parser'
|
| 490 |
+
|
| 491 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 492 |
+
super().__init__(parent, invokingState)
|
| 493 |
+
self.parser = parser
|
| 494 |
+
|
| 495 |
+
def BRACKET_OPEN(self):
|
| 496 |
+
return self.getToken(OmegaConfGrammarParser.BRACKET_OPEN, 0)
|
| 497 |
+
|
| 498 |
+
def BRACKET_CLOSE(self):
|
| 499 |
+
return self.getToken(OmegaConfGrammarParser.BRACKET_CLOSE, 0)
|
| 500 |
+
|
| 501 |
+
def sequence(self):
|
| 502 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.SequenceContext,0)
|
| 503 |
+
|
| 504 |
+
|
| 505 |
+
def getRuleIndex(self):
|
| 506 |
+
return OmegaConfGrammarParser.RULE_listContainer
|
| 507 |
+
|
| 508 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 509 |
+
if hasattr( listener, "enterListContainer" ):
|
| 510 |
+
listener.enterListContainer(self)
|
| 511 |
+
|
| 512 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 513 |
+
if hasattr( listener, "exitListContainer" ):
|
| 514 |
+
listener.exitListContainer(self)
|
| 515 |
+
|
| 516 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 517 |
+
if hasattr( visitor, "visitListContainer" ):
|
| 518 |
+
return visitor.visitListContainer(self)
|
| 519 |
+
else:
|
| 520 |
+
return visitor.visitChildren(self)
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
def listContainer(self):
|
| 526 |
+
|
| 527 |
+
localctx = OmegaConfGrammarParser.ListContainerContext(self, self._ctx, self.state)
|
| 528 |
+
self.enterRule(localctx, 8, self.RULE_listContainer)
|
| 529 |
+
self._la = 0 # Token type
|
| 530 |
+
try:
|
| 531 |
+
self.enterOuterAlt(localctx, 1)
|
| 532 |
+
self.state = 54
|
| 533 |
+
self.match(OmegaConfGrammarParser.BRACKET_OPEN)
|
| 534 |
+
self.state = 56
|
| 535 |
+
self._errHandler.sync(self)
|
| 536 |
+
_la = self._input.LA(1)
|
| 537 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.BRACE_OPEN) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_SINGLE) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE) | (1 << OmegaConfGrammarParser.COMMA) | (1 << OmegaConfGrammarParser.BRACKET_OPEN) | (1 << OmegaConfGrammarParser.COLON) | (1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0):
|
| 538 |
+
self.state = 55
|
| 539 |
+
self.sequence()
|
| 540 |
+
|
| 541 |
+
|
| 542 |
+
self.state = 58
|
| 543 |
+
self.match(OmegaConfGrammarParser.BRACKET_CLOSE)
|
| 544 |
+
except RecognitionException as re:
|
| 545 |
+
localctx.exception = re
|
| 546 |
+
self._errHandler.reportError(self, re)
|
| 547 |
+
self._errHandler.recover(self, re)
|
| 548 |
+
finally:
|
| 549 |
+
self.exitRule()
|
| 550 |
+
return localctx
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
class DictContainerContext(ParserRuleContext):
|
| 554 |
+
__slots__ = 'parser'
|
| 555 |
+
|
| 556 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 557 |
+
super().__init__(parent, invokingState)
|
| 558 |
+
self.parser = parser
|
| 559 |
+
|
| 560 |
+
def BRACE_OPEN(self):
|
| 561 |
+
return self.getToken(OmegaConfGrammarParser.BRACE_OPEN, 0)
|
| 562 |
+
|
| 563 |
+
def BRACE_CLOSE(self):
|
| 564 |
+
return self.getToken(OmegaConfGrammarParser.BRACE_CLOSE, 0)
|
| 565 |
+
|
| 566 |
+
def dictKeyValuePair(self, i:int=None):
|
| 567 |
+
if i is None:
|
| 568 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.DictKeyValuePairContext)
|
| 569 |
+
else:
|
| 570 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.DictKeyValuePairContext,i)
|
| 571 |
+
|
| 572 |
+
|
| 573 |
+
def COMMA(self, i:int=None):
|
| 574 |
+
if i is None:
|
| 575 |
+
return self.getTokens(OmegaConfGrammarParser.COMMA)
|
| 576 |
+
else:
|
| 577 |
+
return self.getToken(OmegaConfGrammarParser.COMMA, i)
|
| 578 |
+
|
| 579 |
+
def getRuleIndex(self):
|
| 580 |
+
return OmegaConfGrammarParser.RULE_dictContainer
|
| 581 |
+
|
| 582 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 583 |
+
if hasattr( listener, "enterDictContainer" ):
|
| 584 |
+
listener.enterDictContainer(self)
|
| 585 |
+
|
| 586 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 587 |
+
if hasattr( listener, "exitDictContainer" ):
|
| 588 |
+
listener.exitDictContainer(self)
|
| 589 |
+
|
| 590 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 591 |
+
if hasattr( visitor, "visitDictContainer" ):
|
| 592 |
+
return visitor.visitDictContainer(self)
|
| 593 |
+
else:
|
| 594 |
+
return visitor.visitChildren(self)
|
| 595 |
+
|
| 596 |
+
|
| 597 |
+
|
| 598 |
+
|
| 599 |
+
def dictContainer(self):
|
| 600 |
+
|
| 601 |
+
localctx = OmegaConfGrammarParser.DictContainerContext(self, self._ctx, self.state)
|
| 602 |
+
self.enterRule(localctx, 10, self.RULE_dictContainer)
|
| 603 |
+
self._la = 0 # Token type
|
| 604 |
+
try:
|
| 605 |
+
self.enterOuterAlt(localctx, 1)
|
| 606 |
+
self.state = 60
|
| 607 |
+
self.match(OmegaConfGrammarParser.BRACE_OPEN)
|
| 608 |
+
self.state = 69
|
| 609 |
+
self._errHandler.sync(self)
|
| 610 |
+
_la = self._input.LA(1)
|
| 611 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0):
|
| 612 |
+
self.state = 61
|
| 613 |
+
self.dictKeyValuePair()
|
| 614 |
+
self.state = 66
|
| 615 |
+
self._errHandler.sync(self)
|
| 616 |
+
_la = self._input.LA(1)
|
| 617 |
+
while _la==OmegaConfGrammarParser.COMMA:
|
| 618 |
+
self.state = 62
|
| 619 |
+
self.match(OmegaConfGrammarParser.COMMA)
|
| 620 |
+
self.state = 63
|
| 621 |
+
self.dictKeyValuePair()
|
| 622 |
+
self.state = 68
|
| 623 |
+
self._errHandler.sync(self)
|
| 624 |
+
_la = self._input.LA(1)
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
|
| 628 |
+
self.state = 71
|
| 629 |
+
self.match(OmegaConfGrammarParser.BRACE_CLOSE)
|
| 630 |
+
except RecognitionException as re:
|
| 631 |
+
localctx.exception = re
|
| 632 |
+
self._errHandler.reportError(self, re)
|
| 633 |
+
self._errHandler.recover(self, re)
|
| 634 |
+
finally:
|
| 635 |
+
self.exitRule()
|
| 636 |
+
return localctx
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
class DictKeyValuePairContext(ParserRuleContext):
|
| 640 |
+
__slots__ = 'parser'
|
| 641 |
+
|
| 642 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 643 |
+
super().__init__(parent, invokingState)
|
| 644 |
+
self.parser = parser
|
| 645 |
+
|
| 646 |
+
def dictKey(self):
|
| 647 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.DictKeyContext,0)
|
| 648 |
+
|
| 649 |
+
|
| 650 |
+
def COLON(self):
|
| 651 |
+
return self.getToken(OmegaConfGrammarParser.COLON, 0)
|
| 652 |
+
|
| 653 |
+
def element(self):
|
| 654 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ElementContext,0)
|
| 655 |
+
|
| 656 |
+
|
| 657 |
+
def getRuleIndex(self):
|
| 658 |
+
return OmegaConfGrammarParser.RULE_dictKeyValuePair
|
| 659 |
+
|
| 660 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 661 |
+
if hasattr( listener, "enterDictKeyValuePair" ):
|
| 662 |
+
listener.enterDictKeyValuePair(self)
|
| 663 |
+
|
| 664 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 665 |
+
if hasattr( listener, "exitDictKeyValuePair" ):
|
| 666 |
+
listener.exitDictKeyValuePair(self)
|
| 667 |
+
|
| 668 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 669 |
+
if hasattr( visitor, "visitDictKeyValuePair" ):
|
| 670 |
+
return visitor.visitDictKeyValuePair(self)
|
| 671 |
+
else:
|
| 672 |
+
return visitor.visitChildren(self)
|
| 673 |
+
|
| 674 |
+
|
| 675 |
+
|
| 676 |
+
|
| 677 |
+
def dictKeyValuePair(self):
|
| 678 |
+
|
| 679 |
+
localctx = OmegaConfGrammarParser.DictKeyValuePairContext(self, self._ctx, self.state)
|
| 680 |
+
self.enterRule(localctx, 12, self.RULE_dictKeyValuePair)
|
| 681 |
+
try:
|
| 682 |
+
self.enterOuterAlt(localctx, 1)
|
| 683 |
+
self.state = 73
|
| 684 |
+
self.dictKey()
|
| 685 |
+
self.state = 74
|
| 686 |
+
self.match(OmegaConfGrammarParser.COLON)
|
| 687 |
+
self.state = 75
|
| 688 |
+
self.element()
|
| 689 |
+
except RecognitionException as re:
|
| 690 |
+
localctx.exception = re
|
| 691 |
+
self._errHandler.reportError(self, re)
|
| 692 |
+
self._errHandler.recover(self, re)
|
| 693 |
+
finally:
|
| 694 |
+
self.exitRule()
|
| 695 |
+
return localctx
|
| 696 |
+
|
| 697 |
+
|
| 698 |
+
class SequenceContext(ParserRuleContext):
|
| 699 |
+
__slots__ = 'parser'
|
| 700 |
+
|
| 701 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 702 |
+
super().__init__(parent, invokingState)
|
| 703 |
+
self.parser = parser
|
| 704 |
+
|
| 705 |
+
def element(self, i:int=None):
|
| 706 |
+
if i is None:
|
| 707 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.ElementContext)
|
| 708 |
+
else:
|
| 709 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ElementContext,i)
|
| 710 |
+
|
| 711 |
+
|
| 712 |
+
def COMMA(self, i:int=None):
|
| 713 |
+
if i is None:
|
| 714 |
+
return self.getTokens(OmegaConfGrammarParser.COMMA)
|
| 715 |
+
else:
|
| 716 |
+
return self.getToken(OmegaConfGrammarParser.COMMA, i)
|
| 717 |
+
|
| 718 |
+
def getRuleIndex(self):
|
| 719 |
+
return OmegaConfGrammarParser.RULE_sequence
|
| 720 |
+
|
| 721 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 722 |
+
if hasattr( listener, "enterSequence" ):
|
| 723 |
+
listener.enterSequence(self)
|
| 724 |
+
|
| 725 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 726 |
+
if hasattr( listener, "exitSequence" ):
|
| 727 |
+
listener.exitSequence(self)
|
| 728 |
+
|
| 729 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 730 |
+
if hasattr( visitor, "visitSequence" ):
|
| 731 |
+
return visitor.visitSequence(self)
|
| 732 |
+
else:
|
| 733 |
+
return visitor.visitChildren(self)
|
| 734 |
+
|
| 735 |
+
|
| 736 |
+
|
| 737 |
+
|
| 738 |
+
def sequence(self):
|
| 739 |
+
|
| 740 |
+
localctx = OmegaConfGrammarParser.SequenceContext(self, self._ctx, self.state)
|
| 741 |
+
self.enterRule(localctx, 14, self.RULE_sequence)
|
| 742 |
+
self._la = 0 # Token type
|
| 743 |
+
try:
|
| 744 |
+
self.state = 95
|
| 745 |
+
self._errHandler.sync(self)
|
| 746 |
+
token = self._input.LA(1)
|
| 747 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN, OmegaConfGrammarParser.BRACE_OPEN, OmegaConfGrammarParser.QUOTE_OPEN_SINGLE, OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE, OmegaConfGrammarParser.BRACKET_OPEN, OmegaConfGrammarParser.COLON, OmegaConfGrammarParser.FLOAT, OmegaConfGrammarParser.INT, OmegaConfGrammarParser.BOOL, OmegaConfGrammarParser.NULL, OmegaConfGrammarParser.UNQUOTED_CHAR, OmegaConfGrammarParser.ID, OmegaConfGrammarParser.ESC, OmegaConfGrammarParser.WS]:
|
| 748 |
+
self.enterOuterAlt(localctx, 1)
|
| 749 |
+
self.state = 77
|
| 750 |
+
self.element()
|
| 751 |
+
self.state = 84
|
| 752 |
+
self._errHandler.sync(self)
|
| 753 |
+
_la = self._input.LA(1)
|
| 754 |
+
while _la==OmegaConfGrammarParser.COMMA:
|
| 755 |
+
self.state = 78
|
| 756 |
+
self.match(OmegaConfGrammarParser.COMMA)
|
| 757 |
+
self.state = 80
|
| 758 |
+
self._errHandler.sync(self)
|
| 759 |
+
_la = self._input.LA(1)
|
| 760 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.BRACE_OPEN) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_SINGLE) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE) | (1 << OmegaConfGrammarParser.BRACKET_OPEN) | (1 << OmegaConfGrammarParser.COLON) | (1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0):
|
| 761 |
+
self.state = 79
|
| 762 |
+
self.element()
|
| 763 |
+
|
| 764 |
+
|
| 765 |
+
self.state = 86
|
| 766 |
+
self._errHandler.sync(self)
|
| 767 |
+
_la = self._input.LA(1)
|
| 768 |
+
|
| 769 |
+
pass
|
| 770 |
+
elif token in [OmegaConfGrammarParser.COMMA]:
|
| 771 |
+
self.enterOuterAlt(localctx, 2)
|
| 772 |
+
self.state = 91
|
| 773 |
+
self._errHandler.sync(self)
|
| 774 |
+
_la = self._input.LA(1)
|
| 775 |
+
while True:
|
| 776 |
+
self.state = 87
|
| 777 |
+
self.match(OmegaConfGrammarParser.COMMA)
|
| 778 |
+
self.state = 89
|
| 779 |
+
self._errHandler.sync(self)
|
| 780 |
+
_la = self._input.LA(1)
|
| 781 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.BRACE_OPEN) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_SINGLE) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE) | (1 << OmegaConfGrammarParser.BRACKET_OPEN) | (1 << OmegaConfGrammarParser.COLON) | (1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0):
|
| 782 |
+
self.state = 88
|
| 783 |
+
self.element()
|
| 784 |
+
|
| 785 |
+
|
| 786 |
+
self.state = 93
|
| 787 |
+
self._errHandler.sync(self)
|
| 788 |
+
_la = self._input.LA(1)
|
| 789 |
+
if not (_la==OmegaConfGrammarParser.COMMA):
|
| 790 |
+
break
|
| 791 |
+
|
| 792 |
+
pass
|
| 793 |
+
else:
|
| 794 |
+
raise NoViableAltException(self)
|
| 795 |
+
|
| 796 |
+
except RecognitionException as re:
|
| 797 |
+
localctx.exception = re
|
| 798 |
+
self._errHandler.reportError(self, re)
|
| 799 |
+
self._errHandler.recover(self, re)
|
| 800 |
+
finally:
|
| 801 |
+
self.exitRule()
|
| 802 |
+
return localctx
|
| 803 |
+
|
| 804 |
+
|
| 805 |
+
class InterpolationContext(ParserRuleContext):
|
| 806 |
+
__slots__ = 'parser'
|
| 807 |
+
|
| 808 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 809 |
+
super().__init__(parent, invokingState)
|
| 810 |
+
self.parser = parser
|
| 811 |
+
|
| 812 |
+
def interpolationNode(self):
|
| 813 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationNodeContext,0)
|
| 814 |
+
|
| 815 |
+
|
| 816 |
+
def interpolationResolver(self):
|
| 817 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationResolverContext,0)
|
| 818 |
+
|
| 819 |
+
|
| 820 |
+
def getRuleIndex(self):
|
| 821 |
+
return OmegaConfGrammarParser.RULE_interpolation
|
| 822 |
+
|
| 823 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 824 |
+
if hasattr( listener, "enterInterpolation" ):
|
| 825 |
+
listener.enterInterpolation(self)
|
| 826 |
+
|
| 827 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 828 |
+
if hasattr( listener, "exitInterpolation" ):
|
| 829 |
+
listener.exitInterpolation(self)
|
| 830 |
+
|
| 831 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 832 |
+
if hasattr( visitor, "visitInterpolation" ):
|
| 833 |
+
return visitor.visitInterpolation(self)
|
| 834 |
+
else:
|
| 835 |
+
return visitor.visitChildren(self)
|
| 836 |
+
|
| 837 |
+
|
| 838 |
+
|
| 839 |
+
|
| 840 |
+
def interpolation(self):
|
| 841 |
+
|
| 842 |
+
localctx = OmegaConfGrammarParser.InterpolationContext(self, self._ctx, self.state)
|
| 843 |
+
self.enterRule(localctx, 16, self.RULE_interpolation)
|
| 844 |
+
try:
|
| 845 |
+
self.state = 99
|
| 846 |
+
self._errHandler.sync(self)
|
| 847 |
+
la_ = self._interp.adaptivePredict(self._input,11,self._ctx)
|
| 848 |
+
if la_ == 1:
|
| 849 |
+
self.enterOuterAlt(localctx, 1)
|
| 850 |
+
self.state = 97
|
| 851 |
+
self.interpolationNode()
|
| 852 |
+
pass
|
| 853 |
+
|
| 854 |
+
elif la_ == 2:
|
| 855 |
+
self.enterOuterAlt(localctx, 2)
|
| 856 |
+
self.state = 98
|
| 857 |
+
self.interpolationResolver()
|
| 858 |
+
pass
|
| 859 |
+
|
| 860 |
+
|
| 861 |
+
except RecognitionException as re:
|
| 862 |
+
localctx.exception = re
|
| 863 |
+
self._errHandler.reportError(self, re)
|
| 864 |
+
self._errHandler.recover(self, re)
|
| 865 |
+
finally:
|
| 866 |
+
self.exitRule()
|
| 867 |
+
return localctx
|
| 868 |
+
|
| 869 |
+
|
| 870 |
+
class InterpolationNodeContext(ParserRuleContext):
|
| 871 |
+
__slots__ = 'parser'
|
| 872 |
+
|
| 873 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 874 |
+
super().__init__(parent, invokingState)
|
| 875 |
+
self.parser = parser
|
| 876 |
+
|
| 877 |
+
def INTER_OPEN(self):
|
| 878 |
+
return self.getToken(OmegaConfGrammarParser.INTER_OPEN, 0)
|
| 879 |
+
|
| 880 |
+
def INTER_CLOSE(self):
|
| 881 |
+
return self.getToken(OmegaConfGrammarParser.INTER_CLOSE, 0)
|
| 882 |
+
|
| 883 |
+
def configKey(self, i:int=None):
|
| 884 |
+
if i is None:
|
| 885 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.ConfigKeyContext)
|
| 886 |
+
else:
|
| 887 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ConfigKeyContext,i)
|
| 888 |
+
|
| 889 |
+
|
| 890 |
+
def BRACKET_OPEN(self, i:int=None):
|
| 891 |
+
if i is None:
|
| 892 |
+
return self.getTokens(OmegaConfGrammarParser.BRACKET_OPEN)
|
| 893 |
+
else:
|
| 894 |
+
return self.getToken(OmegaConfGrammarParser.BRACKET_OPEN, i)
|
| 895 |
+
|
| 896 |
+
def BRACKET_CLOSE(self, i:int=None):
|
| 897 |
+
if i is None:
|
| 898 |
+
return self.getTokens(OmegaConfGrammarParser.BRACKET_CLOSE)
|
| 899 |
+
else:
|
| 900 |
+
return self.getToken(OmegaConfGrammarParser.BRACKET_CLOSE, i)
|
| 901 |
+
|
| 902 |
+
def DOT(self, i:int=None):
|
| 903 |
+
if i is None:
|
| 904 |
+
return self.getTokens(OmegaConfGrammarParser.DOT)
|
| 905 |
+
else:
|
| 906 |
+
return self.getToken(OmegaConfGrammarParser.DOT, i)
|
| 907 |
+
|
| 908 |
+
def getRuleIndex(self):
|
| 909 |
+
return OmegaConfGrammarParser.RULE_interpolationNode
|
| 910 |
+
|
| 911 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 912 |
+
if hasattr( listener, "enterInterpolationNode" ):
|
| 913 |
+
listener.enterInterpolationNode(self)
|
| 914 |
+
|
| 915 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 916 |
+
if hasattr( listener, "exitInterpolationNode" ):
|
| 917 |
+
listener.exitInterpolationNode(self)
|
| 918 |
+
|
| 919 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 920 |
+
if hasattr( visitor, "visitInterpolationNode" ):
|
| 921 |
+
return visitor.visitInterpolationNode(self)
|
| 922 |
+
else:
|
| 923 |
+
return visitor.visitChildren(self)
|
| 924 |
+
|
| 925 |
+
|
| 926 |
+
|
| 927 |
+
|
| 928 |
+
def interpolationNode(self):
|
| 929 |
+
|
| 930 |
+
localctx = OmegaConfGrammarParser.InterpolationNodeContext(self, self._ctx, self.state)
|
| 931 |
+
self.enterRule(localctx, 18, self.RULE_interpolationNode)
|
| 932 |
+
self._la = 0 # Token type
|
| 933 |
+
try:
|
| 934 |
+
self.enterOuterAlt(localctx, 1)
|
| 935 |
+
self.state = 101
|
| 936 |
+
self.match(OmegaConfGrammarParser.INTER_OPEN)
|
| 937 |
+
self.state = 105
|
| 938 |
+
self._errHandler.sync(self)
|
| 939 |
+
_la = self._input.LA(1)
|
| 940 |
+
while _la==OmegaConfGrammarParser.DOT:
|
| 941 |
+
self.state = 102
|
| 942 |
+
self.match(OmegaConfGrammarParser.DOT)
|
| 943 |
+
self.state = 107
|
| 944 |
+
self._errHandler.sync(self)
|
| 945 |
+
_la = self._input.LA(1)
|
| 946 |
+
|
| 947 |
+
self.state = 113
|
| 948 |
+
self._errHandler.sync(self)
|
| 949 |
+
token = self._input.LA(1)
|
| 950 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN, OmegaConfGrammarParser.ID, OmegaConfGrammarParser.INTER_KEY]:
|
| 951 |
+
self.state = 108
|
| 952 |
+
self.configKey()
|
| 953 |
+
pass
|
| 954 |
+
elif token in [OmegaConfGrammarParser.BRACKET_OPEN]:
|
| 955 |
+
self.state = 109
|
| 956 |
+
self.match(OmegaConfGrammarParser.BRACKET_OPEN)
|
| 957 |
+
self.state = 110
|
| 958 |
+
self.configKey()
|
| 959 |
+
self.state = 111
|
| 960 |
+
self.match(OmegaConfGrammarParser.BRACKET_CLOSE)
|
| 961 |
+
pass
|
| 962 |
+
else:
|
| 963 |
+
raise NoViableAltException(self)
|
| 964 |
+
|
| 965 |
+
self.state = 123
|
| 966 |
+
self._errHandler.sync(self)
|
| 967 |
+
_la = self._input.LA(1)
|
| 968 |
+
while _la==OmegaConfGrammarParser.BRACKET_OPEN or _la==OmegaConfGrammarParser.DOT:
|
| 969 |
+
self.state = 121
|
| 970 |
+
self._errHandler.sync(self)
|
| 971 |
+
token = self._input.LA(1)
|
| 972 |
+
if token in [OmegaConfGrammarParser.DOT]:
|
| 973 |
+
self.state = 115
|
| 974 |
+
self.match(OmegaConfGrammarParser.DOT)
|
| 975 |
+
self.state = 116
|
| 976 |
+
self.configKey()
|
| 977 |
+
pass
|
| 978 |
+
elif token in [OmegaConfGrammarParser.BRACKET_OPEN]:
|
| 979 |
+
self.state = 117
|
| 980 |
+
self.match(OmegaConfGrammarParser.BRACKET_OPEN)
|
| 981 |
+
self.state = 118
|
| 982 |
+
self.configKey()
|
| 983 |
+
self.state = 119
|
| 984 |
+
self.match(OmegaConfGrammarParser.BRACKET_CLOSE)
|
| 985 |
+
pass
|
| 986 |
+
else:
|
| 987 |
+
raise NoViableAltException(self)
|
| 988 |
+
|
| 989 |
+
self.state = 125
|
| 990 |
+
self._errHandler.sync(self)
|
| 991 |
+
_la = self._input.LA(1)
|
| 992 |
+
|
| 993 |
+
self.state = 126
|
| 994 |
+
self.match(OmegaConfGrammarParser.INTER_CLOSE)
|
| 995 |
+
except RecognitionException as re:
|
| 996 |
+
localctx.exception = re
|
| 997 |
+
self._errHandler.reportError(self, re)
|
| 998 |
+
self._errHandler.recover(self, re)
|
| 999 |
+
finally:
|
| 1000 |
+
self.exitRule()
|
| 1001 |
+
return localctx
|
| 1002 |
+
|
| 1003 |
+
|
| 1004 |
+
class InterpolationResolverContext(ParserRuleContext):
|
| 1005 |
+
__slots__ = 'parser'
|
| 1006 |
+
|
| 1007 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1008 |
+
super().__init__(parent, invokingState)
|
| 1009 |
+
self.parser = parser
|
| 1010 |
+
|
| 1011 |
+
def INTER_OPEN(self):
|
| 1012 |
+
return self.getToken(OmegaConfGrammarParser.INTER_OPEN, 0)
|
| 1013 |
+
|
| 1014 |
+
def resolverName(self):
|
| 1015 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.ResolverNameContext,0)
|
| 1016 |
+
|
| 1017 |
+
|
| 1018 |
+
def COLON(self):
|
| 1019 |
+
return self.getToken(OmegaConfGrammarParser.COLON, 0)
|
| 1020 |
+
|
| 1021 |
+
def BRACE_CLOSE(self):
|
| 1022 |
+
return self.getToken(OmegaConfGrammarParser.BRACE_CLOSE, 0)
|
| 1023 |
+
|
| 1024 |
+
def sequence(self):
|
| 1025 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.SequenceContext,0)
|
| 1026 |
+
|
| 1027 |
+
|
| 1028 |
+
def getRuleIndex(self):
|
| 1029 |
+
return OmegaConfGrammarParser.RULE_interpolationResolver
|
| 1030 |
+
|
| 1031 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1032 |
+
if hasattr( listener, "enterInterpolationResolver" ):
|
| 1033 |
+
listener.enterInterpolationResolver(self)
|
| 1034 |
+
|
| 1035 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1036 |
+
if hasattr( listener, "exitInterpolationResolver" ):
|
| 1037 |
+
listener.exitInterpolationResolver(self)
|
| 1038 |
+
|
| 1039 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1040 |
+
if hasattr( visitor, "visitInterpolationResolver" ):
|
| 1041 |
+
return visitor.visitInterpolationResolver(self)
|
| 1042 |
+
else:
|
| 1043 |
+
return visitor.visitChildren(self)
|
| 1044 |
+
|
| 1045 |
+
|
| 1046 |
+
|
| 1047 |
+
|
| 1048 |
+
def interpolationResolver(self):
|
| 1049 |
+
|
| 1050 |
+
localctx = OmegaConfGrammarParser.InterpolationResolverContext(self, self._ctx, self.state)
|
| 1051 |
+
self.enterRule(localctx, 20, self.RULE_interpolationResolver)
|
| 1052 |
+
self._la = 0 # Token type
|
| 1053 |
+
try:
|
| 1054 |
+
self.enterOuterAlt(localctx, 1)
|
| 1055 |
+
self.state = 128
|
| 1056 |
+
self.match(OmegaConfGrammarParser.INTER_OPEN)
|
| 1057 |
+
self.state = 129
|
| 1058 |
+
self.resolverName()
|
| 1059 |
+
self.state = 130
|
| 1060 |
+
self.match(OmegaConfGrammarParser.COLON)
|
| 1061 |
+
self.state = 132
|
| 1062 |
+
self._errHandler.sync(self)
|
| 1063 |
+
_la = self._input.LA(1)
|
| 1064 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.BRACE_OPEN) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_SINGLE) | (1 << OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE) | (1 << OmegaConfGrammarParser.COMMA) | (1 << OmegaConfGrammarParser.BRACKET_OPEN) | (1 << OmegaConfGrammarParser.COLON) | (1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0):
|
| 1065 |
+
self.state = 131
|
| 1066 |
+
self.sequence()
|
| 1067 |
+
|
| 1068 |
+
|
| 1069 |
+
self.state = 134
|
| 1070 |
+
self.match(OmegaConfGrammarParser.BRACE_CLOSE)
|
| 1071 |
+
except RecognitionException as re:
|
| 1072 |
+
localctx.exception = re
|
| 1073 |
+
self._errHandler.reportError(self, re)
|
| 1074 |
+
self._errHandler.recover(self, re)
|
| 1075 |
+
finally:
|
| 1076 |
+
self.exitRule()
|
| 1077 |
+
return localctx
|
| 1078 |
+
|
| 1079 |
+
|
| 1080 |
+
class ConfigKeyContext(ParserRuleContext):
|
| 1081 |
+
__slots__ = 'parser'
|
| 1082 |
+
|
| 1083 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1084 |
+
super().__init__(parent, invokingState)
|
| 1085 |
+
self.parser = parser
|
| 1086 |
+
|
| 1087 |
+
def interpolation(self):
|
| 1088 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationContext,0)
|
| 1089 |
+
|
| 1090 |
+
|
| 1091 |
+
def ID(self):
|
| 1092 |
+
return self.getToken(OmegaConfGrammarParser.ID, 0)
|
| 1093 |
+
|
| 1094 |
+
def INTER_KEY(self):
|
| 1095 |
+
return self.getToken(OmegaConfGrammarParser.INTER_KEY, 0)
|
| 1096 |
+
|
| 1097 |
+
def getRuleIndex(self):
|
| 1098 |
+
return OmegaConfGrammarParser.RULE_configKey
|
| 1099 |
+
|
| 1100 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1101 |
+
if hasattr( listener, "enterConfigKey" ):
|
| 1102 |
+
listener.enterConfigKey(self)
|
| 1103 |
+
|
| 1104 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1105 |
+
if hasattr( listener, "exitConfigKey" ):
|
| 1106 |
+
listener.exitConfigKey(self)
|
| 1107 |
+
|
| 1108 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1109 |
+
if hasattr( visitor, "visitConfigKey" ):
|
| 1110 |
+
return visitor.visitConfigKey(self)
|
| 1111 |
+
else:
|
| 1112 |
+
return visitor.visitChildren(self)
|
| 1113 |
+
|
| 1114 |
+
|
| 1115 |
+
|
| 1116 |
+
|
| 1117 |
+
def configKey(self):
|
| 1118 |
+
|
| 1119 |
+
localctx = OmegaConfGrammarParser.ConfigKeyContext(self, self._ctx, self.state)
|
| 1120 |
+
self.enterRule(localctx, 22, self.RULE_configKey)
|
| 1121 |
+
try:
|
| 1122 |
+
self.state = 139
|
| 1123 |
+
self._errHandler.sync(self)
|
| 1124 |
+
token = self._input.LA(1)
|
| 1125 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN]:
|
| 1126 |
+
self.enterOuterAlt(localctx, 1)
|
| 1127 |
+
self.state = 136
|
| 1128 |
+
self.interpolation()
|
| 1129 |
+
pass
|
| 1130 |
+
elif token in [OmegaConfGrammarParser.ID]:
|
| 1131 |
+
self.enterOuterAlt(localctx, 2)
|
| 1132 |
+
self.state = 137
|
| 1133 |
+
self.match(OmegaConfGrammarParser.ID)
|
| 1134 |
+
pass
|
| 1135 |
+
elif token in [OmegaConfGrammarParser.INTER_KEY]:
|
| 1136 |
+
self.enterOuterAlt(localctx, 3)
|
| 1137 |
+
self.state = 138
|
| 1138 |
+
self.match(OmegaConfGrammarParser.INTER_KEY)
|
| 1139 |
+
pass
|
| 1140 |
+
else:
|
| 1141 |
+
raise NoViableAltException(self)
|
| 1142 |
+
|
| 1143 |
+
except RecognitionException as re:
|
| 1144 |
+
localctx.exception = re
|
| 1145 |
+
self._errHandler.reportError(self, re)
|
| 1146 |
+
self._errHandler.recover(self, re)
|
| 1147 |
+
finally:
|
| 1148 |
+
self.exitRule()
|
| 1149 |
+
return localctx
|
| 1150 |
+
|
| 1151 |
+
|
| 1152 |
+
class ResolverNameContext(ParserRuleContext):
|
| 1153 |
+
__slots__ = 'parser'
|
| 1154 |
+
|
| 1155 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1156 |
+
super().__init__(parent, invokingState)
|
| 1157 |
+
self.parser = parser
|
| 1158 |
+
|
| 1159 |
+
def interpolation(self, i:int=None):
|
| 1160 |
+
if i is None:
|
| 1161 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.InterpolationContext)
|
| 1162 |
+
else:
|
| 1163 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationContext,i)
|
| 1164 |
+
|
| 1165 |
+
|
| 1166 |
+
def ID(self, i:int=None):
|
| 1167 |
+
if i is None:
|
| 1168 |
+
return self.getTokens(OmegaConfGrammarParser.ID)
|
| 1169 |
+
else:
|
| 1170 |
+
return self.getToken(OmegaConfGrammarParser.ID, i)
|
| 1171 |
+
|
| 1172 |
+
def DOT(self, i:int=None):
|
| 1173 |
+
if i is None:
|
| 1174 |
+
return self.getTokens(OmegaConfGrammarParser.DOT)
|
| 1175 |
+
else:
|
| 1176 |
+
return self.getToken(OmegaConfGrammarParser.DOT, i)
|
| 1177 |
+
|
| 1178 |
+
def getRuleIndex(self):
|
| 1179 |
+
return OmegaConfGrammarParser.RULE_resolverName
|
| 1180 |
+
|
| 1181 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1182 |
+
if hasattr( listener, "enterResolverName" ):
|
| 1183 |
+
listener.enterResolverName(self)
|
| 1184 |
+
|
| 1185 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1186 |
+
if hasattr( listener, "exitResolverName" ):
|
| 1187 |
+
listener.exitResolverName(self)
|
| 1188 |
+
|
| 1189 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1190 |
+
if hasattr( visitor, "visitResolverName" ):
|
| 1191 |
+
return visitor.visitResolverName(self)
|
| 1192 |
+
else:
|
| 1193 |
+
return visitor.visitChildren(self)
|
| 1194 |
+
|
| 1195 |
+
|
| 1196 |
+
|
| 1197 |
+
|
| 1198 |
+
def resolverName(self):
|
| 1199 |
+
|
| 1200 |
+
localctx = OmegaConfGrammarParser.ResolverNameContext(self, self._ctx, self.state)
|
| 1201 |
+
self.enterRule(localctx, 24, self.RULE_resolverName)
|
| 1202 |
+
self._la = 0 # Token type
|
| 1203 |
+
try:
|
| 1204 |
+
self.enterOuterAlt(localctx, 1)
|
| 1205 |
+
self.state = 143
|
| 1206 |
+
self._errHandler.sync(self)
|
| 1207 |
+
token = self._input.LA(1)
|
| 1208 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN]:
|
| 1209 |
+
self.state = 141
|
| 1210 |
+
self.interpolation()
|
| 1211 |
+
pass
|
| 1212 |
+
elif token in [OmegaConfGrammarParser.ID]:
|
| 1213 |
+
self.state = 142
|
| 1214 |
+
self.match(OmegaConfGrammarParser.ID)
|
| 1215 |
+
pass
|
| 1216 |
+
else:
|
| 1217 |
+
raise NoViableAltException(self)
|
| 1218 |
+
|
| 1219 |
+
self.state = 152
|
| 1220 |
+
self._errHandler.sync(self)
|
| 1221 |
+
_la = self._input.LA(1)
|
| 1222 |
+
while _la==OmegaConfGrammarParser.DOT:
|
| 1223 |
+
self.state = 145
|
| 1224 |
+
self.match(OmegaConfGrammarParser.DOT)
|
| 1225 |
+
self.state = 148
|
| 1226 |
+
self._errHandler.sync(self)
|
| 1227 |
+
token = self._input.LA(1)
|
| 1228 |
+
if token in [OmegaConfGrammarParser.INTER_OPEN]:
|
| 1229 |
+
self.state = 146
|
| 1230 |
+
self.interpolation()
|
| 1231 |
+
pass
|
| 1232 |
+
elif token in [OmegaConfGrammarParser.ID]:
|
| 1233 |
+
self.state = 147
|
| 1234 |
+
self.match(OmegaConfGrammarParser.ID)
|
| 1235 |
+
pass
|
| 1236 |
+
else:
|
| 1237 |
+
raise NoViableAltException(self)
|
| 1238 |
+
|
| 1239 |
+
self.state = 154
|
| 1240 |
+
self._errHandler.sync(self)
|
| 1241 |
+
_la = self._input.LA(1)
|
| 1242 |
+
|
| 1243 |
+
except RecognitionException as re:
|
| 1244 |
+
localctx.exception = re
|
| 1245 |
+
self._errHandler.reportError(self, re)
|
| 1246 |
+
self._errHandler.recover(self, re)
|
| 1247 |
+
finally:
|
| 1248 |
+
self.exitRule()
|
| 1249 |
+
return localctx
|
| 1250 |
+
|
| 1251 |
+
|
| 1252 |
+
class QuotedValueContext(ParserRuleContext):
|
| 1253 |
+
__slots__ = 'parser'
|
| 1254 |
+
|
| 1255 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1256 |
+
super().__init__(parent, invokingState)
|
| 1257 |
+
self.parser = parser
|
| 1258 |
+
|
| 1259 |
+
def MATCHING_QUOTE_CLOSE(self):
|
| 1260 |
+
return self.getToken(OmegaConfGrammarParser.MATCHING_QUOTE_CLOSE, 0)
|
| 1261 |
+
|
| 1262 |
+
def QUOTE_OPEN_SINGLE(self):
|
| 1263 |
+
return self.getToken(OmegaConfGrammarParser.QUOTE_OPEN_SINGLE, 0)
|
| 1264 |
+
|
| 1265 |
+
def QUOTE_OPEN_DOUBLE(self):
|
| 1266 |
+
return self.getToken(OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE, 0)
|
| 1267 |
+
|
| 1268 |
+
def text(self):
|
| 1269 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.TextContext,0)
|
| 1270 |
+
|
| 1271 |
+
|
| 1272 |
+
def getRuleIndex(self):
|
| 1273 |
+
return OmegaConfGrammarParser.RULE_quotedValue
|
| 1274 |
+
|
| 1275 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1276 |
+
if hasattr( listener, "enterQuotedValue" ):
|
| 1277 |
+
listener.enterQuotedValue(self)
|
| 1278 |
+
|
| 1279 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1280 |
+
if hasattr( listener, "exitQuotedValue" ):
|
| 1281 |
+
listener.exitQuotedValue(self)
|
| 1282 |
+
|
| 1283 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1284 |
+
if hasattr( visitor, "visitQuotedValue" ):
|
| 1285 |
+
return visitor.visitQuotedValue(self)
|
| 1286 |
+
else:
|
| 1287 |
+
return visitor.visitChildren(self)
|
| 1288 |
+
|
| 1289 |
+
|
| 1290 |
+
|
| 1291 |
+
|
| 1292 |
+
def quotedValue(self):
|
| 1293 |
+
|
| 1294 |
+
localctx = OmegaConfGrammarParser.QuotedValueContext(self, self._ctx, self.state)
|
| 1295 |
+
self.enterRule(localctx, 26, self.RULE_quotedValue)
|
| 1296 |
+
self._la = 0 # Token type
|
| 1297 |
+
try:
|
| 1298 |
+
self.enterOuterAlt(localctx, 1)
|
| 1299 |
+
self.state = 155
|
| 1300 |
+
_la = self._input.LA(1)
|
| 1301 |
+
if not(_la==OmegaConfGrammarParser.QUOTE_OPEN_SINGLE or _la==OmegaConfGrammarParser.QUOTE_OPEN_DOUBLE):
|
| 1302 |
+
self._errHandler.recoverInline(self)
|
| 1303 |
+
else:
|
| 1304 |
+
self._errHandler.reportMatch(self)
|
| 1305 |
+
self.consume()
|
| 1306 |
+
self.state = 157
|
| 1307 |
+
self._errHandler.sync(self)
|
| 1308 |
+
_la = self._input.LA(1)
|
| 1309 |
+
if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.ANY_STR) | (1 << OmegaConfGrammarParser.ESC_INTER) | (1 << OmegaConfGrammarParser.TOP_ESC) | (1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.QUOTED_ESC))) != 0):
|
| 1310 |
+
self.state = 156
|
| 1311 |
+
self.text()
|
| 1312 |
+
|
| 1313 |
+
|
| 1314 |
+
self.state = 159
|
| 1315 |
+
self.match(OmegaConfGrammarParser.MATCHING_QUOTE_CLOSE)
|
| 1316 |
+
except RecognitionException as re:
|
| 1317 |
+
localctx.exception = re
|
| 1318 |
+
self._errHandler.reportError(self, re)
|
| 1319 |
+
self._errHandler.recover(self, re)
|
| 1320 |
+
finally:
|
| 1321 |
+
self.exitRule()
|
| 1322 |
+
return localctx
|
| 1323 |
+
|
| 1324 |
+
|
| 1325 |
+
class PrimitiveContext(ParserRuleContext):
|
| 1326 |
+
__slots__ = 'parser'
|
| 1327 |
+
|
| 1328 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1329 |
+
super().__init__(parent, invokingState)
|
| 1330 |
+
self.parser = parser
|
| 1331 |
+
|
| 1332 |
+
def ID(self, i:int=None):
|
| 1333 |
+
if i is None:
|
| 1334 |
+
return self.getTokens(OmegaConfGrammarParser.ID)
|
| 1335 |
+
else:
|
| 1336 |
+
return self.getToken(OmegaConfGrammarParser.ID, i)
|
| 1337 |
+
|
| 1338 |
+
def NULL(self, i:int=None):
|
| 1339 |
+
if i is None:
|
| 1340 |
+
return self.getTokens(OmegaConfGrammarParser.NULL)
|
| 1341 |
+
else:
|
| 1342 |
+
return self.getToken(OmegaConfGrammarParser.NULL, i)
|
| 1343 |
+
|
| 1344 |
+
def INT(self, i:int=None):
|
| 1345 |
+
if i is None:
|
| 1346 |
+
return self.getTokens(OmegaConfGrammarParser.INT)
|
| 1347 |
+
else:
|
| 1348 |
+
return self.getToken(OmegaConfGrammarParser.INT, i)
|
| 1349 |
+
|
| 1350 |
+
def FLOAT(self, i:int=None):
|
| 1351 |
+
if i is None:
|
| 1352 |
+
return self.getTokens(OmegaConfGrammarParser.FLOAT)
|
| 1353 |
+
else:
|
| 1354 |
+
return self.getToken(OmegaConfGrammarParser.FLOAT, i)
|
| 1355 |
+
|
| 1356 |
+
def BOOL(self, i:int=None):
|
| 1357 |
+
if i is None:
|
| 1358 |
+
return self.getTokens(OmegaConfGrammarParser.BOOL)
|
| 1359 |
+
else:
|
| 1360 |
+
return self.getToken(OmegaConfGrammarParser.BOOL, i)
|
| 1361 |
+
|
| 1362 |
+
def UNQUOTED_CHAR(self, i:int=None):
|
| 1363 |
+
if i is None:
|
| 1364 |
+
return self.getTokens(OmegaConfGrammarParser.UNQUOTED_CHAR)
|
| 1365 |
+
else:
|
| 1366 |
+
return self.getToken(OmegaConfGrammarParser.UNQUOTED_CHAR, i)
|
| 1367 |
+
|
| 1368 |
+
def COLON(self, i:int=None):
|
| 1369 |
+
if i is None:
|
| 1370 |
+
return self.getTokens(OmegaConfGrammarParser.COLON)
|
| 1371 |
+
else:
|
| 1372 |
+
return self.getToken(OmegaConfGrammarParser.COLON, i)
|
| 1373 |
+
|
| 1374 |
+
def ESC(self, i:int=None):
|
| 1375 |
+
if i is None:
|
| 1376 |
+
return self.getTokens(OmegaConfGrammarParser.ESC)
|
| 1377 |
+
else:
|
| 1378 |
+
return self.getToken(OmegaConfGrammarParser.ESC, i)
|
| 1379 |
+
|
| 1380 |
+
def WS(self, i:int=None):
|
| 1381 |
+
if i is None:
|
| 1382 |
+
return self.getTokens(OmegaConfGrammarParser.WS)
|
| 1383 |
+
else:
|
| 1384 |
+
return self.getToken(OmegaConfGrammarParser.WS, i)
|
| 1385 |
+
|
| 1386 |
+
def interpolation(self, i:int=None):
|
| 1387 |
+
if i is None:
|
| 1388 |
+
return self.getTypedRuleContexts(OmegaConfGrammarParser.InterpolationContext)
|
| 1389 |
+
else:
|
| 1390 |
+
return self.getTypedRuleContext(OmegaConfGrammarParser.InterpolationContext,i)
|
| 1391 |
+
|
| 1392 |
+
|
| 1393 |
+
def getRuleIndex(self):
|
| 1394 |
+
return OmegaConfGrammarParser.RULE_primitive
|
| 1395 |
+
|
| 1396 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1397 |
+
if hasattr( listener, "enterPrimitive" ):
|
| 1398 |
+
listener.enterPrimitive(self)
|
| 1399 |
+
|
| 1400 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1401 |
+
if hasattr( listener, "exitPrimitive" ):
|
| 1402 |
+
listener.exitPrimitive(self)
|
| 1403 |
+
|
| 1404 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1405 |
+
if hasattr( visitor, "visitPrimitive" ):
|
| 1406 |
+
return visitor.visitPrimitive(self)
|
| 1407 |
+
else:
|
| 1408 |
+
return visitor.visitChildren(self)
|
| 1409 |
+
|
| 1410 |
+
|
| 1411 |
+
|
| 1412 |
+
|
| 1413 |
+
def primitive(self):
|
| 1414 |
+
|
| 1415 |
+
localctx = OmegaConfGrammarParser.PrimitiveContext(self, self._ctx, self.state)
|
| 1416 |
+
self.enterRule(localctx, 28, self.RULE_primitive)
|
| 1417 |
+
self._la = 0 # Token type
|
| 1418 |
+
try:
|
| 1419 |
+
self.enterOuterAlt(localctx, 1)
|
| 1420 |
+
self.state = 171
|
| 1421 |
+
self._errHandler.sync(self)
|
| 1422 |
+
_la = self._input.LA(1)
|
| 1423 |
+
while True:
|
| 1424 |
+
self.state = 171
|
| 1425 |
+
self._errHandler.sync(self)
|
| 1426 |
+
token = self._input.LA(1)
|
| 1427 |
+
if token in [OmegaConfGrammarParser.ID]:
|
| 1428 |
+
self.state = 161
|
| 1429 |
+
self.match(OmegaConfGrammarParser.ID)
|
| 1430 |
+
pass
|
| 1431 |
+
elif token in [OmegaConfGrammarParser.NULL]:
|
| 1432 |
+
self.state = 162
|
| 1433 |
+
self.match(OmegaConfGrammarParser.NULL)
|
| 1434 |
+
pass
|
| 1435 |
+
elif token in [OmegaConfGrammarParser.INT]:
|
| 1436 |
+
self.state = 163
|
| 1437 |
+
self.match(OmegaConfGrammarParser.INT)
|
| 1438 |
+
pass
|
| 1439 |
+
elif token in [OmegaConfGrammarParser.FLOAT]:
|
| 1440 |
+
self.state = 164
|
| 1441 |
+
self.match(OmegaConfGrammarParser.FLOAT)
|
| 1442 |
+
pass
|
| 1443 |
+
elif token in [OmegaConfGrammarParser.BOOL]:
|
| 1444 |
+
self.state = 165
|
| 1445 |
+
self.match(OmegaConfGrammarParser.BOOL)
|
| 1446 |
+
pass
|
| 1447 |
+
elif token in [OmegaConfGrammarParser.UNQUOTED_CHAR]:
|
| 1448 |
+
self.state = 166
|
| 1449 |
+
self.match(OmegaConfGrammarParser.UNQUOTED_CHAR)
|
| 1450 |
+
pass
|
| 1451 |
+
elif token in [OmegaConfGrammarParser.COLON]:
|
| 1452 |
+
self.state = 167
|
| 1453 |
+
self.match(OmegaConfGrammarParser.COLON)
|
| 1454 |
+
pass
|
| 1455 |
+
elif token in [OmegaConfGrammarParser.ESC]:
|
| 1456 |
+
self.state = 168
|
| 1457 |
+
self.match(OmegaConfGrammarParser.ESC)
|
| 1458 |
+
pass
|
| 1459 |
+
elif token in [OmegaConfGrammarParser.WS]:
|
| 1460 |
+
self.state = 169
|
| 1461 |
+
self.match(OmegaConfGrammarParser.WS)
|
| 1462 |
+
pass
|
| 1463 |
+
elif token in [OmegaConfGrammarParser.INTER_OPEN]:
|
| 1464 |
+
self.state = 170
|
| 1465 |
+
self.interpolation()
|
| 1466 |
+
pass
|
| 1467 |
+
else:
|
| 1468 |
+
raise NoViableAltException(self)
|
| 1469 |
+
|
| 1470 |
+
self.state = 173
|
| 1471 |
+
self._errHandler.sync(self)
|
| 1472 |
+
_la = self._input.LA(1)
|
| 1473 |
+
if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.INTER_OPEN) | (1 << OmegaConfGrammarParser.COLON) | (1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0)):
|
| 1474 |
+
break
|
| 1475 |
+
|
| 1476 |
+
except RecognitionException as re:
|
| 1477 |
+
localctx.exception = re
|
| 1478 |
+
self._errHandler.reportError(self, re)
|
| 1479 |
+
self._errHandler.recover(self, re)
|
| 1480 |
+
finally:
|
| 1481 |
+
self.exitRule()
|
| 1482 |
+
return localctx
|
| 1483 |
+
|
| 1484 |
+
|
| 1485 |
+
class DictKeyContext(ParserRuleContext):
|
| 1486 |
+
__slots__ = 'parser'
|
| 1487 |
+
|
| 1488 |
+
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
|
| 1489 |
+
super().__init__(parent, invokingState)
|
| 1490 |
+
self.parser = parser
|
| 1491 |
+
|
| 1492 |
+
def ID(self, i:int=None):
|
| 1493 |
+
if i is None:
|
| 1494 |
+
return self.getTokens(OmegaConfGrammarParser.ID)
|
| 1495 |
+
else:
|
| 1496 |
+
return self.getToken(OmegaConfGrammarParser.ID, i)
|
| 1497 |
+
|
| 1498 |
+
def NULL(self, i:int=None):
|
| 1499 |
+
if i is None:
|
| 1500 |
+
return self.getTokens(OmegaConfGrammarParser.NULL)
|
| 1501 |
+
else:
|
| 1502 |
+
return self.getToken(OmegaConfGrammarParser.NULL, i)
|
| 1503 |
+
|
| 1504 |
+
def INT(self, i:int=None):
|
| 1505 |
+
if i is None:
|
| 1506 |
+
return self.getTokens(OmegaConfGrammarParser.INT)
|
| 1507 |
+
else:
|
| 1508 |
+
return self.getToken(OmegaConfGrammarParser.INT, i)
|
| 1509 |
+
|
| 1510 |
+
def FLOAT(self, i:int=None):
|
| 1511 |
+
if i is None:
|
| 1512 |
+
return self.getTokens(OmegaConfGrammarParser.FLOAT)
|
| 1513 |
+
else:
|
| 1514 |
+
return self.getToken(OmegaConfGrammarParser.FLOAT, i)
|
| 1515 |
+
|
| 1516 |
+
def BOOL(self, i:int=None):
|
| 1517 |
+
if i is None:
|
| 1518 |
+
return self.getTokens(OmegaConfGrammarParser.BOOL)
|
| 1519 |
+
else:
|
| 1520 |
+
return self.getToken(OmegaConfGrammarParser.BOOL, i)
|
| 1521 |
+
|
| 1522 |
+
def UNQUOTED_CHAR(self, i:int=None):
|
| 1523 |
+
if i is None:
|
| 1524 |
+
return self.getTokens(OmegaConfGrammarParser.UNQUOTED_CHAR)
|
| 1525 |
+
else:
|
| 1526 |
+
return self.getToken(OmegaConfGrammarParser.UNQUOTED_CHAR, i)
|
| 1527 |
+
|
| 1528 |
+
def ESC(self, i:int=None):
|
| 1529 |
+
if i is None:
|
| 1530 |
+
return self.getTokens(OmegaConfGrammarParser.ESC)
|
| 1531 |
+
else:
|
| 1532 |
+
return self.getToken(OmegaConfGrammarParser.ESC, i)
|
| 1533 |
+
|
| 1534 |
+
def WS(self, i:int=None):
|
| 1535 |
+
if i is None:
|
| 1536 |
+
return self.getTokens(OmegaConfGrammarParser.WS)
|
| 1537 |
+
else:
|
| 1538 |
+
return self.getToken(OmegaConfGrammarParser.WS, i)
|
| 1539 |
+
|
| 1540 |
+
def getRuleIndex(self):
|
| 1541 |
+
return OmegaConfGrammarParser.RULE_dictKey
|
| 1542 |
+
|
| 1543 |
+
def enterRule(self, listener:ParseTreeListener):
|
| 1544 |
+
if hasattr( listener, "enterDictKey" ):
|
| 1545 |
+
listener.enterDictKey(self)
|
| 1546 |
+
|
| 1547 |
+
def exitRule(self, listener:ParseTreeListener):
|
| 1548 |
+
if hasattr( listener, "exitDictKey" ):
|
| 1549 |
+
listener.exitDictKey(self)
|
| 1550 |
+
|
| 1551 |
+
def accept(self, visitor:ParseTreeVisitor):
|
| 1552 |
+
if hasattr( visitor, "visitDictKey" ):
|
| 1553 |
+
return visitor.visitDictKey(self)
|
| 1554 |
+
else:
|
| 1555 |
+
return visitor.visitChildren(self)
|
| 1556 |
+
|
| 1557 |
+
|
| 1558 |
+
|
| 1559 |
+
|
| 1560 |
+
def dictKey(self):
|
| 1561 |
+
|
| 1562 |
+
localctx = OmegaConfGrammarParser.DictKeyContext(self, self._ctx, self.state)
|
| 1563 |
+
self.enterRule(localctx, 30, self.RULE_dictKey)
|
| 1564 |
+
self._la = 0 # Token type
|
| 1565 |
+
try:
|
| 1566 |
+
self.enterOuterAlt(localctx, 1)
|
| 1567 |
+
self.state = 176
|
| 1568 |
+
self._errHandler.sync(self)
|
| 1569 |
+
_la = self._input.LA(1)
|
| 1570 |
+
while True:
|
| 1571 |
+
self.state = 175
|
| 1572 |
+
_la = self._input.LA(1)
|
| 1573 |
+
if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0)):
|
| 1574 |
+
self._errHandler.recoverInline(self)
|
| 1575 |
+
else:
|
| 1576 |
+
self._errHandler.reportMatch(self)
|
| 1577 |
+
self.consume()
|
| 1578 |
+
self.state = 178
|
| 1579 |
+
self._errHandler.sync(self)
|
| 1580 |
+
_la = self._input.LA(1)
|
| 1581 |
+
if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << OmegaConfGrammarParser.FLOAT) | (1 << OmegaConfGrammarParser.INT) | (1 << OmegaConfGrammarParser.BOOL) | (1 << OmegaConfGrammarParser.NULL) | (1 << OmegaConfGrammarParser.UNQUOTED_CHAR) | (1 << OmegaConfGrammarParser.ID) | (1 << OmegaConfGrammarParser.ESC) | (1 << OmegaConfGrammarParser.WS))) != 0)):
|
| 1582 |
+
break
|
| 1583 |
+
|
| 1584 |
+
except RecognitionException as re:
|
| 1585 |
+
localctx.exception = re
|
| 1586 |
+
self._errHandler.reportError(self, re)
|
| 1587 |
+
self._errHandler.recover(self, re)
|
| 1588 |
+
finally:
|
| 1589 |
+
self.exitRule()
|
| 1590 |
+
return localctx
|
| 1591 |
+
|
| 1592 |
+
|
| 1593 |
+
|
| 1594 |
+
|
| 1595 |
+
|
lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParserListener.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated from /tmp/build-via-sdist-fm63w174/omegaconf-2.3.0/omegaconf/grammar/OmegaConfGrammarParser.g4 by ANTLR 4.9.3
|
| 2 |
+
from antlr4 import *
|
| 3 |
+
if __name__ is not None and "." in __name__:
|
| 4 |
+
from .OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 5 |
+
else:
|
| 6 |
+
from OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 7 |
+
|
| 8 |
+
# This class defines a complete listener for a parse tree produced by OmegaConfGrammarParser.
|
| 9 |
+
class OmegaConfGrammarParserListener(ParseTreeListener):
|
| 10 |
+
|
| 11 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#configValue.
|
| 12 |
+
def enterConfigValue(self, ctx:OmegaConfGrammarParser.ConfigValueContext):
|
| 13 |
+
pass
|
| 14 |
+
|
| 15 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#configValue.
|
| 16 |
+
def exitConfigValue(self, ctx:OmegaConfGrammarParser.ConfigValueContext):
|
| 17 |
+
pass
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#singleElement.
|
| 21 |
+
def enterSingleElement(self, ctx:OmegaConfGrammarParser.SingleElementContext):
|
| 22 |
+
pass
|
| 23 |
+
|
| 24 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#singleElement.
|
| 25 |
+
def exitSingleElement(self, ctx:OmegaConfGrammarParser.SingleElementContext):
|
| 26 |
+
pass
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#text.
|
| 30 |
+
def enterText(self, ctx:OmegaConfGrammarParser.TextContext):
|
| 31 |
+
pass
|
| 32 |
+
|
| 33 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#text.
|
| 34 |
+
def exitText(self, ctx:OmegaConfGrammarParser.TextContext):
|
| 35 |
+
pass
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#element.
|
| 39 |
+
def enterElement(self, ctx:OmegaConfGrammarParser.ElementContext):
|
| 40 |
+
pass
|
| 41 |
+
|
| 42 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#element.
|
| 43 |
+
def exitElement(self, ctx:OmegaConfGrammarParser.ElementContext):
|
| 44 |
+
pass
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#listContainer.
|
| 48 |
+
def enterListContainer(self, ctx:OmegaConfGrammarParser.ListContainerContext):
|
| 49 |
+
pass
|
| 50 |
+
|
| 51 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#listContainer.
|
| 52 |
+
def exitListContainer(self, ctx:OmegaConfGrammarParser.ListContainerContext):
|
| 53 |
+
pass
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#dictContainer.
|
| 57 |
+
def enterDictContainer(self, ctx:OmegaConfGrammarParser.DictContainerContext):
|
| 58 |
+
pass
|
| 59 |
+
|
| 60 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#dictContainer.
|
| 61 |
+
def exitDictContainer(self, ctx:OmegaConfGrammarParser.DictContainerContext):
|
| 62 |
+
pass
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#dictKeyValuePair.
|
| 66 |
+
def enterDictKeyValuePair(self, ctx:OmegaConfGrammarParser.DictKeyValuePairContext):
|
| 67 |
+
pass
|
| 68 |
+
|
| 69 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#dictKeyValuePair.
|
| 70 |
+
def exitDictKeyValuePair(self, ctx:OmegaConfGrammarParser.DictKeyValuePairContext):
|
| 71 |
+
pass
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#sequence.
|
| 75 |
+
def enterSequence(self, ctx:OmegaConfGrammarParser.SequenceContext):
|
| 76 |
+
pass
|
| 77 |
+
|
| 78 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#sequence.
|
| 79 |
+
def exitSequence(self, ctx:OmegaConfGrammarParser.SequenceContext):
|
| 80 |
+
pass
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#interpolation.
|
| 84 |
+
def enterInterpolation(self, ctx:OmegaConfGrammarParser.InterpolationContext):
|
| 85 |
+
pass
|
| 86 |
+
|
| 87 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#interpolation.
|
| 88 |
+
def exitInterpolation(self, ctx:OmegaConfGrammarParser.InterpolationContext):
|
| 89 |
+
pass
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#interpolationNode.
|
| 93 |
+
def enterInterpolationNode(self, ctx:OmegaConfGrammarParser.InterpolationNodeContext):
|
| 94 |
+
pass
|
| 95 |
+
|
| 96 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#interpolationNode.
|
| 97 |
+
def exitInterpolationNode(self, ctx:OmegaConfGrammarParser.InterpolationNodeContext):
|
| 98 |
+
pass
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#interpolationResolver.
|
| 102 |
+
def enterInterpolationResolver(self, ctx:OmegaConfGrammarParser.InterpolationResolverContext):
|
| 103 |
+
pass
|
| 104 |
+
|
| 105 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#interpolationResolver.
|
| 106 |
+
def exitInterpolationResolver(self, ctx:OmegaConfGrammarParser.InterpolationResolverContext):
|
| 107 |
+
pass
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#configKey.
|
| 111 |
+
def enterConfigKey(self, ctx:OmegaConfGrammarParser.ConfigKeyContext):
|
| 112 |
+
pass
|
| 113 |
+
|
| 114 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#configKey.
|
| 115 |
+
def exitConfigKey(self, ctx:OmegaConfGrammarParser.ConfigKeyContext):
|
| 116 |
+
pass
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#resolverName.
|
| 120 |
+
def enterResolverName(self, ctx:OmegaConfGrammarParser.ResolverNameContext):
|
| 121 |
+
pass
|
| 122 |
+
|
| 123 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#resolverName.
|
| 124 |
+
def exitResolverName(self, ctx:OmegaConfGrammarParser.ResolverNameContext):
|
| 125 |
+
pass
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#quotedValue.
|
| 129 |
+
def enterQuotedValue(self, ctx:OmegaConfGrammarParser.QuotedValueContext):
|
| 130 |
+
pass
|
| 131 |
+
|
| 132 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#quotedValue.
|
| 133 |
+
def exitQuotedValue(self, ctx:OmegaConfGrammarParser.QuotedValueContext):
|
| 134 |
+
pass
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#primitive.
|
| 138 |
+
def enterPrimitive(self, ctx:OmegaConfGrammarParser.PrimitiveContext):
|
| 139 |
+
pass
|
| 140 |
+
|
| 141 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#primitive.
|
| 142 |
+
def exitPrimitive(self, ctx:OmegaConfGrammarParser.PrimitiveContext):
|
| 143 |
+
pass
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
# Enter a parse tree produced by OmegaConfGrammarParser#dictKey.
|
| 147 |
+
def enterDictKey(self, ctx:OmegaConfGrammarParser.DictKeyContext):
|
| 148 |
+
pass
|
| 149 |
+
|
| 150 |
+
# Exit a parse tree produced by OmegaConfGrammarParser#dictKey.
|
| 151 |
+
def exitDictKey(self, ctx:OmegaConfGrammarParser.DictKeyContext):
|
| 152 |
+
pass
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
del OmegaConfGrammarParser
|
lib/python3.12/site-packages/omegaconf/grammar/gen/OmegaConfGrammarParserVisitor.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Generated from /tmp/build-via-sdist-fm63w174/omegaconf-2.3.0/omegaconf/grammar/OmegaConfGrammarParser.g4 by ANTLR 4.9.3
|
| 2 |
+
from antlr4 import *
|
| 3 |
+
if __name__ is not None and "." in __name__:
|
| 4 |
+
from .OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 5 |
+
else:
|
| 6 |
+
from OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 7 |
+
|
| 8 |
+
# This class defines a complete generic visitor for a parse tree produced by OmegaConfGrammarParser.
|
| 9 |
+
|
| 10 |
+
class OmegaConfGrammarParserVisitor(ParseTreeVisitor):
|
| 11 |
+
|
| 12 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#configValue.
|
| 13 |
+
def visitConfigValue(self, ctx:OmegaConfGrammarParser.ConfigValueContext):
|
| 14 |
+
return self.visitChildren(ctx)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#singleElement.
|
| 18 |
+
def visitSingleElement(self, ctx:OmegaConfGrammarParser.SingleElementContext):
|
| 19 |
+
return self.visitChildren(ctx)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#text.
|
| 23 |
+
def visitText(self, ctx:OmegaConfGrammarParser.TextContext):
|
| 24 |
+
return self.visitChildren(ctx)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#element.
|
| 28 |
+
def visitElement(self, ctx:OmegaConfGrammarParser.ElementContext):
|
| 29 |
+
return self.visitChildren(ctx)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#listContainer.
|
| 33 |
+
def visitListContainer(self, ctx:OmegaConfGrammarParser.ListContainerContext):
|
| 34 |
+
return self.visitChildren(ctx)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#dictContainer.
|
| 38 |
+
def visitDictContainer(self, ctx:OmegaConfGrammarParser.DictContainerContext):
|
| 39 |
+
return self.visitChildren(ctx)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#dictKeyValuePair.
|
| 43 |
+
def visitDictKeyValuePair(self, ctx:OmegaConfGrammarParser.DictKeyValuePairContext):
|
| 44 |
+
return self.visitChildren(ctx)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#sequence.
|
| 48 |
+
def visitSequence(self, ctx:OmegaConfGrammarParser.SequenceContext):
|
| 49 |
+
return self.visitChildren(ctx)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#interpolation.
|
| 53 |
+
def visitInterpolation(self, ctx:OmegaConfGrammarParser.InterpolationContext):
|
| 54 |
+
return self.visitChildren(ctx)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#interpolationNode.
|
| 58 |
+
def visitInterpolationNode(self, ctx:OmegaConfGrammarParser.InterpolationNodeContext):
|
| 59 |
+
return self.visitChildren(ctx)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#interpolationResolver.
|
| 63 |
+
def visitInterpolationResolver(self, ctx:OmegaConfGrammarParser.InterpolationResolverContext):
|
| 64 |
+
return self.visitChildren(ctx)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#configKey.
|
| 68 |
+
def visitConfigKey(self, ctx:OmegaConfGrammarParser.ConfigKeyContext):
|
| 69 |
+
return self.visitChildren(ctx)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#resolverName.
|
| 73 |
+
def visitResolverName(self, ctx:OmegaConfGrammarParser.ResolverNameContext):
|
| 74 |
+
return self.visitChildren(ctx)
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#quotedValue.
|
| 78 |
+
def visitQuotedValue(self, ctx:OmegaConfGrammarParser.QuotedValueContext):
|
| 79 |
+
return self.visitChildren(ctx)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#primitive.
|
| 83 |
+
def visitPrimitive(self, ctx:OmegaConfGrammarParser.PrimitiveContext):
|
| 84 |
+
return self.visitChildren(ctx)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
# Visit a parse tree produced by OmegaConfGrammarParser#dictKey.
|
| 88 |
+
def visitDictKey(self, ctx:OmegaConfGrammarParser.DictKeyContext):
|
| 89 |
+
return self.visitChildren(ctx)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
del OmegaConfGrammarParser
|
lib/python3.12/site-packages/omegaconf/grammar/gen/__init__.py
ADDED
|
File without changes
|
lib/python3.12/site-packages/omegaconf/grammar_parser.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
import threading
|
| 3 |
+
from typing import Any
|
| 4 |
+
|
| 5 |
+
from antlr4 import CommonTokenStream, InputStream, ParserRuleContext
|
| 6 |
+
from antlr4.error.ErrorListener import ErrorListener
|
| 7 |
+
|
| 8 |
+
from .errors import GrammarParseError
|
| 9 |
+
|
| 10 |
+
# Import from visitor in order to check the presence of generated grammar files
|
| 11 |
+
# files in a single place.
|
| 12 |
+
from .grammar_visitor import ( # type: ignore
|
| 13 |
+
OmegaConfGrammarLexer,
|
| 14 |
+
OmegaConfGrammarParser,
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
# Used to cache grammar objects to avoid re-creating them on each call to `parse()`.
|
| 18 |
+
# We use a per-thread cache to make it thread-safe.
|
| 19 |
+
_grammar_cache = threading.local()
|
| 20 |
+
|
| 21 |
+
# Build regex pattern to efficiently identify typical interpolations.
|
| 22 |
+
# See test `test_match_simple_interpolation_pattern` for examples.
|
| 23 |
+
_config_key = r"[$\w]+" # foo, $0, $bar, $foo_$bar123$
|
| 24 |
+
_key_maybe_brackets = f"{_config_key}|\\[{_config_key}\\]" # foo, [foo], [$bar]
|
| 25 |
+
_node_access = f"\\.{_key_maybe_brackets}" # .foo, [foo], [$bar]
|
| 26 |
+
_node_path = f"(\\.)*({_key_maybe_brackets})({_node_access})*" # [foo].bar, .foo[bar]
|
| 27 |
+
_node_inter = f"\\${{\\s*{_node_path}\\s*}}" # node interpolation ${foo.bar}
|
| 28 |
+
_id = "[a-zA-Z_][\\w\\-]*" # foo, foo_bar, foo-bar, abc123
|
| 29 |
+
_resolver_name = f"({_id}(\\.{_id})*)?" # foo, ns.bar3, ns_1.ns_2.b0z
|
| 30 |
+
_arg = r"[a-zA-Z_0-9/\-\+.$%*@?|]+" # string representing a resolver argument
|
| 31 |
+
_args = f"{_arg}(\\s*,\\s*{_arg})*" # list of resolver arguments
|
| 32 |
+
_resolver_inter = f"\\${{\\s*{_resolver_name}\\s*:\\s*{_args}?\\s*}}" # ${foo:bar}
|
| 33 |
+
_inter = f"({_node_inter}|{_resolver_inter})" # any kind of interpolation
|
| 34 |
+
_outer = "([^$]|\\$(?!{))+" # any character except $ (unless not followed by {)
|
| 35 |
+
SIMPLE_INTERPOLATION_PATTERN = re.compile(
|
| 36 |
+
f"({_outer})?({_inter}({_outer})?)+$", flags=re.ASCII
|
| 37 |
+
)
|
| 38 |
+
# NOTE: SIMPLE_INTERPOLATION_PATTERN must not generate false positive matches:
|
| 39 |
+
# it must not accept anything that isn't a valid interpolation (per the
|
| 40 |
+
# interpolation grammar defined in `omegaconf/grammar/*.g4`).
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class OmegaConfErrorListener(ErrorListener): # type: ignore
|
| 44 |
+
def syntaxError(
|
| 45 |
+
self,
|
| 46 |
+
recognizer: Any,
|
| 47 |
+
offending_symbol: Any,
|
| 48 |
+
line: Any,
|
| 49 |
+
column: Any,
|
| 50 |
+
msg: Any,
|
| 51 |
+
e: Any,
|
| 52 |
+
) -> None:
|
| 53 |
+
raise GrammarParseError(str(e) if msg is None else msg) from e
|
| 54 |
+
|
| 55 |
+
def reportAmbiguity(
|
| 56 |
+
self,
|
| 57 |
+
recognizer: Any,
|
| 58 |
+
dfa: Any,
|
| 59 |
+
startIndex: Any,
|
| 60 |
+
stopIndex: Any,
|
| 61 |
+
exact: Any,
|
| 62 |
+
ambigAlts: Any,
|
| 63 |
+
configs: Any,
|
| 64 |
+
) -> None:
|
| 65 |
+
raise GrammarParseError("ANTLR error: Ambiguity") # pragma: no cover
|
| 66 |
+
|
| 67 |
+
def reportAttemptingFullContext(
|
| 68 |
+
self,
|
| 69 |
+
recognizer: Any,
|
| 70 |
+
dfa: Any,
|
| 71 |
+
startIndex: Any,
|
| 72 |
+
stopIndex: Any,
|
| 73 |
+
conflictingAlts: Any,
|
| 74 |
+
configs: Any,
|
| 75 |
+
) -> None:
|
| 76 |
+
# Note: for now we raise an error to be safe. However this is mostly a
|
| 77 |
+
# performance warning, so in the future this may be relaxed if we need
|
| 78 |
+
# to change the grammar in such a way that this warning cannot be
|
| 79 |
+
# avoided (another option would be to switch to SLL parsing mode).
|
| 80 |
+
raise GrammarParseError(
|
| 81 |
+
"ANTLR error: Attempting Full Context"
|
| 82 |
+
) # pragma: no cover
|
| 83 |
+
|
| 84 |
+
def reportContextSensitivity(
|
| 85 |
+
self,
|
| 86 |
+
recognizer: Any,
|
| 87 |
+
dfa: Any,
|
| 88 |
+
startIndex: Any,
|
| 89 |
+
stopIndex: Any,
|
| 90 |
+
prediction: Any,
|
| 91 |
+
configs: Any,
|
| 92 |
+
) -> None:
|
| 93 |
+
raise GrammarParseError("ANTLR error: ContextSensitivity") # pragma: no cover
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def parse(
|
| 97 |
+
value: str, parser_rule: str = "configValue", lexer_mode: str = "DEFAULT_MODE"
|
| 98 |
+
) -> ParserRuleContext:
|
| 99 |
+
"""
|
| 100 |
+
Parse interpolated string `value` (and return the parse tree).
|
| 101 |
+
"""
|
| 102 |
+
l_mode = getattr(OmegaConfGrammarLexer, lexer_mode)
|
| 103 |
+
istream = InputStream(value)
|
| 104 |
+
|
| 105 |
+
cached = getattr(_grammar_cache, "data", None)
|
| 106 |
+
if cached is None:
|
| 107 |
+
error_listener = OmegaConfErrorListener()
|
| 108 |
+
lexer = OmegaConfGrammarLexer(istream)
|
| 109 |
+
lexer.removeErrorListeners()
|
| 110 |
+
lexer.addErrorListener(error_listener)
|
| 111 |
+
lexer.mode(l_mode)
|
| 112 |
+
token_stream = CommonTokenStream(lexer)
|
| 113 |
+
parser = OmegaConfGrammarParser(token_stream)
|
| 114 |
+
parser.removeErrorListeners()
|
| 115 |
+
parser.addErrorListener(error_listener)
|
| 116 |
+
|
| 117 |
+
# The two lines below could be enabled in the future if we decide to switch
|
| 118 |
+
# to SLL prediction mode. Warning though, it has not been fully tested yet!
|
| 119 |
+
# from antlr4 import PredictionMode
|
| 120 |
+
# parser._interp.predictionMode = PredictionMode.SLL
|
| 121 |
+
|
| 122 |
+
# Note that although the input stream `istream` is implicitly cached within
|
| 123 |
+
# the lexer, it will be replaced by a new input next time the lexer is re-used.
|
| 124 |
+
_grammar_cache.data = lexer, token_stream, parser
|
| 125 |
+
|
| 126 |
+
else:
|
| 127 |
+
lexer, token_stream, parser = cached
|
| 128 |
+
# Replace the old input stream with the new one.
|
| 129 |
+
lexer.inputStream = istream
|
| 130 |
+
# Initialize the lexer / token stream / parser to process the new input.
|
| 131 |
+
lexer.mode(l_mode)
|
| 132 |
+
token_stream.setTokenSource(lexer)
|
| 133 |
+
parser.reset()
|
| 134 |
+
|
| 135 |
+
try:
|
| 136 |
+
return getattr(parser, parser_rule)()
|
| 137 |
+
except Exception as exc:
|
| 138 |
+
if type(exc) is Exception and str(exc) == "Empty Stack":
|
| 139 |
+
# This exception is raised by antlr when trying to pop a mode while
|
| 140 |
+
# no mode has been pushed. We convert it into an `GrammarParseError`
|
| 141 |
+
# to facilitate exception handling from the caller.
|
| 142 |
+
raise GrammarParseError("Empty Stack")
|
| 143 |
+
else:
|
| 144 |
+
raise
|
lib/python3.12/site-packages/omegaconf/grammar_visitor.py
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import warnings
|
| 3 |
+
from itertools import zip_longest
|
| 4 |
+
from typing import (
|
| 5 |
+
TYPE_CHECKING,
|
| 6 |
+
Any,
|
| 7 |
+
Callable,
|
| 8 |
+
Dict,
|
| 9 |
+
Generator,
|
| 10 |
+
List,
|
| 11 |
+
Optional,
|
| 12 |
+
Set,
|
| 13 |
+
Tuple,
|
| 14 |
+
Union,
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
from antlr4 import TerminalNode
|
| 18 |
+
|
| 19 |
+
from .errors import InterpolationResolutionError
|
| 20 |
+
|
| 21 |
+
if TYPE_CHECKING:
|
| 22 |
+
from .base import Node # noqa F401
|
| 23 |
+
|
| 24 |
+
try:
|
| 25 |
+
from omegaconf.grammar.gen.OmegaConfGrammarLexer import OmegaConfGrammarLexer
|
| 26 |
+
from omegaconf.grammar.gen.OmegaConfGrammarParser import OmegaConfGrammarParser
|
| 27 |
+
from omegaconf.grammar.gen.OmegaConfGrammarParserVisitor import (
|
| 28 |
+
OmegaConfGrammarParserVisitor,
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
except ModuleNotFoundError: # pragma: no cover
|
| 32 |
+
print(
|
| 33 |
+
"Error importing OmegaConf's generated parsers, run `python setup.py antlr` to regenerate.",
|
| 34 |
+
file=sys.stderr,
|
| 35 |
+
)
|
| 36 |
+
sys.exit(1)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
class GrammarVisitor(OmegaConfGrammarParserVisitor):
|
| 40 |
+
def __init__(
|
| 41 |
+
self,
|
| 42 |
+
node_interpolation_callback: Callable[
|
| 43 |
+
[str, Optional[Set[int]]],
|
| 44 |
+
Optional["Node"],
|
| 45 |
+
],
|
| 46 |
+
resolver_interpolation_callback: Callable[..., Any],
|
| 47 |
+
memo: Optional[Set[int]],
|
| 48 |
+
**kw: Dict[Any, Any],
|
| 49 |
+
):
|
| 50 |
+
"""
|
| 51 |
+
Constructor.
|
| 52 |
+
|
| 53 |
+
:param node_interpolation_callback: Callback function that is called when
|
| 54 |
+
needing to resolve a node interpolation. This function should take a single
|
| 55 |
+
string input which is the key's dot path (ex: `"foo.bar"`).
|
| 56 |
+
|
| 57 |
+
:param resolver_interpolation_callback: Callback function that is called when
|
| 58 |
+
needing to resolve a resolver interpolation. This function should accept
|
| 59 |
+
three keyword arguments: `name` (str, the name of the resolver),
|
| 60 |
+
`args` (tuple, the inputs to the resolver), and `args_str` (tuple,
|
| 61 |
+
the string representation of the inputs to the resolver).
|
| 62 |
+
|
| 63 |
+
:param kw: Additional keyword arguments to be forwarded to parent class.
|
| 64 |
+
"""
|
| 65 |
+
super().__init__(**kw)
|
| 66 |
+
self.node_interpolation_callback = node_interpolation_callback
|
| 67 |
+
self.resolver_interpolation_callback = resolver_interpolation_callback
|
| 68 |
+
self.memo = memo
|
| 69 |
+
|
| 70 |
+
def aggregateResult(self, aggregate: List[Any], nextResult: Any) -> List[Any]:
|
| 71 |
+
raise NotImplementedError
|
| 72 |
+
|
| 73 |
+
def defaultResult(self) -> List[Any]:
|
| 74 |
+
# Raising an exception because not currently used (like `aggregateResult()`).
|
| 75 |
+
raise NotImplementedError
|
| 76 |
+
|
| 77 |
+
def visitConfigKey(self, ctx: OmegaConfGrammarParser.ConfigKeyContext) -> str:
|
| 78 |
+
from ._utils import _get_value
|
| 79 |
+
|
| 80 |
+
# interpolation | ID | INTER_KEY
|
| 81 |
+
assert ctx.getChildCount() == 1
|
| 82 |
+
child = ctx.getChild(0)
|
| 83 |
+
if isinstance(child, OmegaConfGrammarParser.InterpolationContext):
|
| 84 |
+
res = _get_value(self.visitInterpolation(child))
|
| 85 |
+
if not isinstance(res, str):
|
| 86 |
+
raise InterpolationResolutionError(
|
| 87 |
+
f"The following interpolation is used to denote a config key and "
|
| 88 |
+
f"thus should return a string, but instead returned `{res}` of "
|
| 89 |
+
f"type `{type(res)}`: {ctx.getChild(0).getText()}"
|
| 90 |
+
)
|
| 91 |
+
return res
|
| 92 |
+
else:
|
| 93 |
+
assert isinstance(child, TerminalNode) and isinstance(
|
| 94 |
+
child.symbol.text, str
|
| 95 |
+
)
|
| 96 |
+
return child.symbol.text
|
| 97 |
+
|
| 98 |
+
def visitConfigValue(self, ctx: OmegaConfGrammarParser.ConfigValueContext) -> Any:
|
| 99 |
+
# text EOF
|
| 100 |
+
assert ctx.getChildCount() == 2
|
| 101 |
+
return self.visit(ctx.getChild(0))
|
| 102 |
+
|
| 103 |
+
def visitDictKey(self, ctx: OmegaConfGrammarParser.DictKeyContext) -> Any:
|
| 104 |
+
return self._createPrimitive(ctx)
|
| 105 |
+
|
| 106 |
+
def visitDictContainer(
|
| 107 |
+
self, ctx: OmegaConfGrammarParser.DictContainerContext
|
| 108 |
+
) -> Dict[Any, Any]:
|
| 109 |
+
# BRACE_OPEN (dictKeyValuePair (COMMA dictKeyValuePair)*)? BRACE_CLOSE
|
| 110 |
+
assert ctx.getChildCount() >= 2
|
| 111 |
+
return dict(
|
| 112 |
+
self.visitDictKeyValuePair(ctx.getChild(i))
|
| 113 |
+
for i in range(1, ctx.getChildCount() - 1, 2)
|
| 114 |
+
)
|
| 115 |
+
|
| 116 |
+
def visitElement(self, ctx: OmegaConfGrammarParser.ElementContext) -> Any:
|
| 117 |
+
# primitive | quotedValue | listContainer | dictContainer
|
| 118 |
+
assert ctx.getChildCount() == 1
|
| 119 |
+
return self.visit(ctx.getChild(0))
|
| 120 |
+
|
| 121 |
+
def visitInterpolation(
|
| 122 |
+
self, ctx: OmegaConfGrammarParser.InterpolationContext
|
| 123 |
+
) -> Any:
|
| 124 |
+
assert ctx.getChildCount() == 1 # interpolationNode | interpolationResolver
|
| 125 |
+
return self.visit(ctx.getChild(0))
|
| 126 |
+
|
| 127 |
+
def visitInterpolationNode(
|
| 128 |
+
self, ctx: OmegaConfGrammarParser.InterpolationNodeContext
|
| 129 |
+
) -> Optional["Node"]:
|
| 130 |
+
# INTER_OPEN
|
| 131 |
+
# DOT* // relative interpolation?
|
| 132 |
+
# (configKey | BRACKET_OPEN configKey BRACKET_CLOSE) // foo, [foo]
|
| 133 |
+
# (DOT configKey | BRACKET_OPEN configKey BRACKET_CLOSE)* // .foo, [foo], .foo[bar], [foo].bar[baz]
|
| 134 |
+
# INTER_CLOSE;
|
| 135 |
+
|
| 136 |
+
assert ctx.getChildCount() >= 3
|
| 137 |
+
|
| 138 |
+
inter_key_tokens = [] # parsed elements of the dot path
|
| 139 |
+
for child in ctx.getChildren():
|
| 140 |
+
if isinstance(child, TerminalNode):
|
| 141 |
+
s = child.symbol
|
| 142 |
+
if s.type in [
|
| 143 |
+
OmegaConfGrammarLexer.DOT,
|
| 144 |
+
OmegaConfGrammarLexer.BRACKET_OPEN,
|
| 145 |
+
OmegaConfGrammarLexer.BRACKET_CLOSE,
|
| 146 |
+
]:
|
| 147 |
+
inter_key_tokens.append(s.text)
|
| 148 |
+
else:
|
| 149 |
+
assert s.type in (
|
| 150 |
+
OmegaConfGrammarLexer.INTER_OPEN,
|
| 151 |
+
OmegaConfGrammarLexer.INTER_CLOSE,
|
| 152 |
+
)
|
| 153 |
+
else:
|
| 154 |
+
assert isinstance(child, OmegaConfGrammarParser.ConfigKeyContext)
|
| 155 |
+
inter_key_tokens.append(self.visitConfigKey(child))
|
| 156 |
+
|
| 157 |
+
inter_key = "".join(inter_key_tokens)
|
| 158 |
+
return self.node_interpolation_callback(inter_key, self.memo)
|
| 159 |
+
|
| 160 |
+
def visitInterpolationResolver(
|
| 161 |
+
self, ctx: OmegaConfGrammarParser.InterpolationResolverContext
|
| 162 |
+
) -> Any:
|
| 163 |
+
|
| 164 |
+
# INTER_OPEN resolverName COLON sequence? BRACE_CLOSE
|
| 165 |
+
assert 4 <= ctx.getChildCount() <= 5
|
| 166 |
+
|
| 167 |
+
resolver_name = self.visit(ctx.getChild(1))
|
| 168 |
+
maybe_seq = ctx.getChild(3)
|
| 169 |
+
args = []
|
| 170 |
+
args_str = []
|
| 171 |
+
if isinstance(maybe_seq, TerminalNode): # means there are no args
|
| 172 |
+
assert maybe_seq.symbol.type == OmegaConfGrammarLexer.BRACE_CLOSE
|
| 173 |
+
else:
|
| 174 |
+
assert isinstance(maybe_seq, OmegaConfGrammarParser.SequenceContext)
|
| 175 |
+
for val, txt in self.visitSequence(maybe_seq):
|
| 176 |
+
args.append(val)
|
| 177 |
+
args_str.append(txt)
|
| 178 |
+
|
| 179 |
+
return self.resolver_interpolation_callback(
|
| 180 |
+
name=resolver_name,
|
| 181 |
+
args=tuple(args),
|
| 182 |
+
args_str=tuple(args_str),
|
| 183 |
+
)
|
| 184 |
+
|
| 185 |
+
def visitDictKeyValuePair(
|
| 186 |
+
self, ctx: OmegaConfGrammarParser.DictKeyValuePairContext
|
| 187 |
+
) -> Tuple[Any, Any]:
|
| 188 |
+
from ._utils import _get_value
|
| 189 |
+
|
| 190 |
+
assert ctx.getChildCount() == 3 # dictKey COLON element
|
| 191 |
+
key = self.visit(ctx.getChild(0))
|
| 192 |
+
colon = ctx.getChild(1)
|
| 193 |
+
assert (
|
| 194 |
+
isinstance(colon, TerminalNode)
|
| 195 |
+
and colon.symbol.type == OmegaConfGrammarLexer.COLON
|
| 196 |
+
)
|
| 197 |
+
value = _get_value(self.visitElement(ctx.getChild(2)))
|
| 198 |
+
return key, value
|
| 199 |
+
|
| 200 |
+
def visitListContainer(
|
| 201 |
+
self, ctx: OmegaConfGrammarParser.ListContainerContext
|
| 202 |
+
) -> List[Any]:
|
| 203 |
+
# BRACKET_OPEN sequence? BRACKET_CLOSE;
|
| 204 |
+
assert ctx.getChildCount() in (2, 3)
|
| 205 |
+
if ctx.getChildCount() == 2:
|
| 206 |
+
return []
|
| 207 |
+
sequence = ctx.getChild(1)
|
| 208 |
+
assert isinstance(sequence, OmegaConfGrammarParser.SequenceContext)
|
| 209 |
+
return list(val for val, _ in self.visitSequence(sequence)) # ignore raw text
|
| 210 |
+
|
| 211 |
+
def visitPrimitive(self, ctx: OmegaConfGrammarParser.PrimitiveContext) -> Any:
|
| 212 |
+
return self._createPrimitive(ctx)
|
| 213 |
+
|
| 214 |
+
def visitQuotedValue(self, ctx: OmegaConfGrammarParser.QuotedValueContext) -> str:
|
| 215 |
+
# (QUOTE_OPEN_SINGLE | QUOTE_OPEN_DOUBLE) text? MATCHING_QUOTE_CLOSE
|
| 216 |
+
n = ctx.getChildCount()
|
| 217 |
+
assert n in [2, 3]
|
| 218 |
+
return str(self.visit(ctx.getChild(1))) if n == 3 else ""
|
| 219 |
+
|
| 220 |
+
def visitResolverName(self, ctx: OmegaConfGrammarParser.ResolverNameContext) -> str:
|
| 221 |
+
from ._utils import _get_value
|
| 222 |
+
|
| 223 |
+
# (interpolation | ID) (DOT (interpolation | ID))*
|
| 224 |
+
assert ctx.getChildCount() >= 1
|
| 225 |
+
items = []
|
| 226 |
+
for child in list(ctx.getChildren())[::2]:
|
| 227 |
+
if isinstance(child, TerminalNode):
|
| 228 |
+
assert child.symbol.type == OmegaConfGrammarLexer.ID
|
| 229 |
+
items.append(child.symbol.text)
|
| 230 |
+
else:
|
| 231 |
+
assert isinstance(child, OmegaConfGrammarParser.InterpolationContext)
|
| 232 |
+
item = _get_value(self.visitInterpolation(child))
|
| 233 |
+
if not isinstance(item, str):
|
| 234 |
+
raise InterpolationResolutionError(
|
| 235 |
+
f"The name of a resolver must be a string, but the interpolation "
|
| 236 |
+
f"{child.getText()} resolved to `{item}` which is of type "
|
| 237 |
+
f"{type(item)}"
|
| 238 |
+
)
|
| 239 |
+
items.append(item)
|
| 240 |
+
return ".".join(items)
|
| 241 |
+
|
| 242 |
+
def visitSequence(
|
| 243 |
+
self, ctx: OmegaConfGrammarParser.SequenceContext
|
| 244 |
+
) -> Generator[Any, None, None]:
|
| 245 |
+
from ._utils import _get_value
|
| 246 |
+
|
| 247 |
+
# (element (COMMA element?)*) | (COMMA element?)+
|
| 248 |
+
assert ctx.getChildCount() >= 1
|
| 249 |
+
|
| 250 |
+
# DEPRECATED: remove in 2.2 (revert #571)
|
| 251 |
+
def empty_str_warning() -> None:
|
| 252 |
+
txt = ctx.getText()
|
| 253 |
+
warnings.warn(
|
| 254 |
+
f"In the sequence `{txt}` some elements are missing: please replace "
|
| 255 |
+
f"them with empty quoted strings. "
|
| 256 |
+
f"See https://github.com/omry/omegaconf/issues/572 for details.",
|
| 257 |
+
category=UserWarning,
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
is_previous_comma = True # whether previous child was a comma (init to True)
|
| 261 |
+
for child in ctx.getChildren():
|
| 262 |
+
if isinstance(child, OmegaConfGrammarParser.ElementContext):
|
| 263 |
+
# Also preserve the original text representation of `child` so
|
| 264 |
+
# as to allow backward compatibility with old resolvers (registered
|
| 265 |
+
# with `legacy_register_resolver()`). Note that we cannot just cast
|
| 266 |
+
# the value to string later as for instance `null` would become "None".
|
| 267 |
+
yield _get_value(self.visitElement(child)), child.getText()
|
| 268 |
+
is_previous_comma = False
|
| 269 |
+
else:
|
| 270 |
+
assert (
|
| 271 |
+
isinstance(child, TerminalNode)
|
| 272 |
+
and child.symbol.type == OmegaConfGrammarLexer.COMMA
|
| 273 |
+
)
|
| 274 |
+
if is_previous_comma:
|
| 275 |
+
empty_str_warning()
|
| 276 |
+
yield "", ""
|
| 277 |
+
else:
|
| 278 |
+
is_previous_comma = True
|
| 279 |
+
if is_previous_comma:
|
| 280 |
+
# Trailing comma.
|
| 281 |
+
empty_str_warning()
|
| 282 |
+
yield "", ""
|
| 283 |
+
|
| 284 |
+
def visitSingleElement(
|
| 285 |
+
self, ctx: OmegaConfGrammarParser.SingleElementContext
|
| 286 |
+
) -> Any:
|
| 287 |
+
# element EOF
|
| 288 |
+
assert ctx.getChildCount() == 2
|
| 289 |
+
return self.visit(ctx.getChild(0))
|
| 290 |
+
|
| 291 |
+
def visitText(self, ctx: OmegaConfGrammarParser.TextContext) -> Any:
|
| 292 |
+
# (interpolation | ANY_STR | ESC | ESC_INTER | TOP_ESC | QUOTED_ESC)+
|
| 293 |
+
|
| 294 |
+
# Single interpolation? If yes, return its resolved value "as is".
|
| 295 |
+
if ctx.getChildCount() == 1:
|
| 296 |
+
c = ctx.getChild(0)
|
| 297 |
+
if isinstance(c, OmegaConfGrammarParser.InterpolationContext):
|
| 298 |
+
return self.visitInterpolation(c)
|
| 299 |
+
|
| 300 |
+
# Otherwise, concatenate string representations together.
|
| 301 |
+
return self._unescape(list(ctx.getChildren()))
|
| 302 |
+
|
| 303 |
+
def _createPrimitive(
|
| 304 |
+
self,
|
| 305 |
+
ctx: Union[
|
| 306 |
+
OmegaConfGrammarParser.PrimitiveContext,
|
| 307 |
+
OmegaConfGrammarParser.DictKeyContext,
|
| 308 |
+
],
|
| 309 |
+
) -> Any:
|
| 310 |
+
# (ID | NULL | INT | FLOAT | BOOL | UNQUOTED_CHAR | COLON | ESC | WS | interpolation)+
|
| 311 |
+
if ctx.getChildCount() == 1:
|
| 312 |
+
child = ctx.getChild(0)
|
| 313 |
+
if isinstance(child, OmegaConfGrammarParser.InterpolationContext):
|
| 314 |
+
return self.visitInterpolation(child)
|
| 315 |
+
assert isinstance(child, TerminalNode)
|
| 316 |
+
symbol = child.symbol
|
| 317 |
+
# Parse primitive types.
|
| 318 |
+
if symbol.type in (
|
| 319 |
+
OmegaConfGrammarLexer.ID,
|
| 320 |
+
OmegaConfGrammarLexer.UNQUOTED_CHAR,
|
| 321 |
+
OmegaConfGrammarLexer.COLON,
|
| 322 |
+
):
|
| 323 |
+
return symbol.text
|
| 324 |
+
elif symbol.type == OmegaConfGrammarLexer.NULL:
|
| 325 |
+
return None
|
| 326 |
+
elif symbol.type == OmegaConfGrammarLexer.INT:
|
| 327 |
+
return int(symbol.text)
|
| 328 |
+
elif symbol.type == OmegaConfGrammarLexer.FLOAT:
|
| 329 |
+
return float(symbol.text)
|
| 330 |
+
elif symbol.type == OmegaConfGrammarLexer.BOOL:
|
| 331 |
+
return symbol.text.lower() == "true"
|
| 332 |
+
elif symbol.type == OmegaConfGrammarLexer.ESC:
|
| 333 |
+
return self._unescape([child])
|
| 334 |
+
elif symbol.type == OmegaConfGrammarLexer.WS: # pragma: no cover
|
| 335 |
+
# A single WS should have been "consumed" by another token.
|
| 336 |
+
raise AssertionError("WS should never be reached")
|
| 337 |
+
assert False, symbol.type
|
| 338 |
+
# Concatenation of multiple items ==> un-escape the concatenation.
|
| 339 |
+
return self._unescape(list(ctx.getChildren()))
|
| 340 |
+
|
| 341 |
+
def _unescape(
|
| 342 |
+
self,
|
| 343 |
+
seq: List[Union[TerminalNode, OmegaConfGrammarParser.InterpolationContext]],
|
| 344 |
+
) -> str:
|
| 345 |
+
"""
|
| 346 |
+
Concatenate all symbols / interpolations in `seq`, unescaping symbols as needed.
|
| 347 |
+
|
| 348 |
+
Interpolations are resolved and cast to string *WITHOUT* escaping their result
|
| 349 |
+
(it is assumed that whatever escaping is required was already handled during the
|
| 350 |
+
resolving of the interpolation).
|
| 351 |
+
"""
|
| 352 |
+
chrs = []
|
| 353 |
+
for node, next_node in zip_longest(seq, seq[1:]):
|
| 354 |
+
if isinstance(node, TerminalNode):
|
| 355 |
+
s = node.symbol
|
| 356 |
+
if s.type == OmegaConfGrammarLexer.ESC_INTER:
|
| 357 |
+
# `ESC_INTER` is of the form `\\...\${`: the formula below computes
|
| 358 |
+
# the number of characters to keep at the end of the string to remove
|
| 359 |
+
# the correct number of backslashes.
|
| 360 |
+
text = s.text[-(len(s.text) // 2 + 1) :]
|
| 361 |
+
elif (
|
| 362 |
+
# Character sequence identified as requiring un-escaping.
|
| 363 |
+
s.type == OmegaConfGrammarLexer.ESC
|
| 364 |
+
or (
|
| 365 |
+
# At top level, we need to un-escape backslashes that precede
|
| 366 |
+
# an interpolation.
|
| 367 |
+
s.type == OmegaConfGrammarLexer.TOP_ESC
|
| 368 |
+
and isinstance(
|
| 369 |
+
next_node, OmegaConfGrammarParser.InterpolationContext
|
| 370 |
+
)
|
| 371 |
+
)
|
| 372 |
+
or (
|
| 373 |
+
# In a quoted sring, we need to un-escape backslashes that
|
| 374 |
+
# either end the string, or are followed by an interpolation.
|
| 375 |
+
s.type == OmegaConfGrammarLexer.QUOTED_ESC
|
| 376 |
+
and (
|
| 377 |
+
next_node is None
|
| 378 |
+
or isinstance(
|
| 379 |
+
next_node, OmegaConfGrammarParser.InterpolationContext
|
| 380 |
+
)
|
| 381 |
+
)
|
| 382 |
+
)
|
| 383 |
+
):
|
| 384 |
+
text = s.text[1::2] # un-escape the sequence
|
| 385 |
+
else:
|
| 386 |
+
text = s.text # keep the original text
|
| 387 |
+
else:
|
| 388 |
+
assert isinstance(node, OmegaConfGrammarParser.InterpolationContext)
|
| 389 |
+
text = str(self.visitInterpolation(node))
|
| 390 |
+
chrs.append(text)
|
| 391 |
+
|
| 392 |
+
return "".join(chrs)
|
lib/python3.12/site-packages/omegaconf/listconfig.py
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import itertools
|
| 3 |
+
from typing import (
|
| 4 |
+
Any,
|
| 5 |
+
Callable,
|
| 6 |
+
Dict,
|
| 7 |
+
Iterable,
|
| 8 |
+
Iterator,
|
| 9 |
+
List,
|
| 10 |
+
MutableSequence,
|
| 11 |
+
Optional,
|
| 12 |
+
Tuple,
|
| 13 |
+
Type,
|
| 14 |
+
Union,
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
from ._utils import (
|
| 18 |
+
ValueKind,
|
| 19 |
+
_is_missing_literal,
|
| 20 |
+
_is_none,
|
| 21 |
+
_resolve_optional,
|
| 22 |
+
format_and_raise,
|
| 23 |
+
get_value_kind,
|
| 24 |
+
is_int,
|
| 25 |
+
is_primitive_list,
|
| 26 |
+
is_structured_config,
|
| 27 |
+
type_str,
|
| 28 |
+
)
|
| 29 |
+
from .base import Box, ContainerMetadata, Node
|
| 30 |
+
from .basecontainer import BaseContainer
|
| 31 |
+
from .errors import (
|
| 32 |
+
ConfigAttributeError,
|
| 33 |
+
ConfigTypeError,
|
| 34 |
+
ConfigValueError,
|
| 35 |
+
KeyValidationError,
|
| 36 |
+
MissingMandatoryValue,
|
| 37 |
+
ReadonlyConfigError,
|
| 38 |
+
ValidationError,
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
class ListConfig(BaseContainer, MutableSequence[Any]):
|
| 43 |
+
|
| 44 |
+
_content: Union[List[Node], None, str]
|
| 45 |
+
|
| 46 |
+
def __init__(
|
| 47 |
+
self,
|
| 48 |
+
content: Union[List[Any], Tuple[Any, ...], "ListConfig", str, None],
|
| 49 |
+
key: Any = None,
|
| 50 |
+
parent: Optional[Box] = None,
|
| 51 |
+
element_type: Union[Type[Any], Any] = Any,
|
| 52 |
+
is_optional: bool = True,
|
| 53 |
+
ref_type: Union[Type[Any], Any] = Any,
|
| 54 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 55 |
+
) -> None:
|
| 56 |
+
try:
|
| 57 |
+
if isinstance(content, ListConfig):
|
| 58 |
+
if flags is None:
|
| 59 |
+
flags = content._metadata.flags
|
| 60 |
+
super().__init__(
|
| 61 |
+
parent=parent,
|
| 62 |
+
metadata=ContainerMetadata(
|
| 63 |
+
ref_type=ref_type,
|
| 64 |
+
object_type=list,
|
| 65 |
+
key=key,
|
| 66 |
+
optional=is_optional,
|
| 67 |
+
element_type=element_type,
|
| 68 |
+
key_type=int,
|
| 69 |
+
flags=flags,
|
| 70 |
+
),
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
if isinstance(content, ListConfig):
|
| 74 |
+
metadata = copy.deepcopy(content._metadata)
|
| 75 |
+
metadata.key = key
|
| 76 |
+
metadata.ref_type = ref_type
|
| 77 |
+
metadata.optional = is_optional
|
| 78 |
+
metadata.element_type = element_type
|
| 79 |
+
self.__dict__["_metadata"] = metadata
|
| 80 |
+
self._set_value(value=content, flags=flags)
|
| 81 |
+
except Exception as ex:
|
| 82 |
+
format_and_raise(node=None, key=key, value=None, cause=ex, msg=str(ex))
|
| 83 |
+
|
| 84 |
+
def _validate_get(self, key: Any, value: Any = None) -> None:
|
| 85 |
+
if not isinstance(key, (int, slice)):
|
| 86 |
+
raise KeyValidationError(
|
| 87 |
+
"ListConfig indices must be integers or slices, not $KEY_TYPE"
|
| 88 |
+
)
|
| 89 |
+
|
| 90 |
+
def _validate_set(self, key: Any, value: Any) -> None:
|
| 91 |
+
from omegaconf import OmegaConf
|
| 92 |
+
|
| 93 |
+
self._validate_get(key, value)
|
| 94 |
+
|
| 95 |
+
if self._get_flag("readonly"):
|
| 96 |
+
raise ReadonlyConfigError("ListConfig is read-only")
|
| 97 |
+
|
| 98 |
+
if 0 <= key < self.__len__():
|
| 99 |
+
target = self._get_node(key)
|
| 100 |
+
if target is not None:
|
| 101 |
+
assert isinstance(target, Node)
|
| 102 |
+
if value is None and not target._is_optional():
|
| 103 |
+
raise ValidationError(
|
| 104 |
+
"$FULL_KEY is not optional and cannot be assigned None"
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
vk = get_value_kind(value)
|
| 108 |
+
if vk == ValueKind.MANDATORY_MISSING:
|
| 109 |
+
return
|
| 110 |
+
else:
|
| 111 |
+
is_optional, target_type = _resolve_optional(self._metadata.element_type)
|
| 112 |
+
value_type = OmegaConf.get_type(value)
|
| 113 |
+
|
| 114 |
+
if (value_type is None and not is_optional) or (
|
| 115 |
+
is_structured_config(target_type)
|
| 116 |
+
and value_type is not None
|
| 117 |
+
and not issubclass(value_type, target_type)
|
| 118 |
+
):
|
| 119 |
+
msg = (
|
| 120 |
+
f"Invalid type assigned: {type_str(value_type)} is not a "
|
| 121 |
+
f"subclass of {type_str(target_type)}. value: {value}"
|
| 122 |
+
)
|
| 123 |
+
raise ValidationError(msg)
|
| 124 |
+
|
| 125 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "ListConfig":
|
| 126 |
+
res = ListConfig(None)
|
| 127 |
+
res.__dict__["_metadata"] = copy.deepcopy(self.__dict__["_metadata"], memo=memo)
|
| 128 |
+
res.__dict__["_flags_cache"] = copy.deepcopy(
|
| 129 |
+
self.__dict__["_flags_cache"], memo=memo
|
| 130 |
+
)
|
| 131 |
+
|
| 132 |
+
src_content = self.__dict__["_content"]
|
| 133 |
+
if isinstance(src_content, list):
|
| 134 |
+
content_copy: List[Optional[Node]] = []
|
| 135 |
+
for v in src_content:
|
| 136 |
+
old_parent = v.__dict__["_parent"]
|
| 137 |
+
try:
|
| 138 |
+
v.__dict__["_parent"] = None
|
| 139 |
+
vc = copy.deepcopy(v, memo=memo)
|
| 140 |
+
vc.__dict__["_parent"] = res
|
| 141 |
+
content_copy.append(vc)
|
| 142 |
+
finally:
|
| 143 |
+
v.__dict__["_parent"] = old_parent
|
| 144 |
+
else:
|
| 145 |
+
# None and strings can be assigned as is
|
| 146 |
+
content_copy = src_content
|
| 147 |
+
|
| 148 |
+
res.__dict__["_content"] = content_copy
|
| 149 |
+
res.__dict__["_parent"] = self.__dict__["_parent"]
|
| 150 |
+
|
| 151 |
+
return res
|
| 152 |
+
|
| 153 |
+
def copy(self) -> "ListConfig":
|
| 154 |
+
return copy.copy(self)
|
| 155 |
+
|
| 156 |
+
# hide content while inspecting in debugger
|
| 157 |
+
def __dir__(self) -> Iterable[str]:
|
| 158 |
+
if self._is_missing() or self._is_none():
|
| 159 |
+
return []
|
| 160 |
+
return [str(x) for x in range(0, len(self))]
|
| 161 |
+
|
| 162 |
+
def __setattr__(self, key: str, value: Any) -> None:
|
| 163 |
+
self._format_and_raise(
|
| 164 |
+
key=key,
|
| 165 |
+
value=value,
|
| 166 |
+
cause=ConfigAttributeError("ListConfig does not support attribute access"),
|
| 167 |
+
)
|
| 168 |
+
assert False
|
| 169 |
+
|
| 170 |
+
def __getattr__(self, key: str) -> Any:
|
| 171 |
+
# PyCharm is sometimes inspecting __members__, be sure to tell it we don't have that.
|
| 172 |
+
if key == "__members__":
|
| 173 |
+
raise AttributeError()
|
| 174 |
+
|
| 175 |
+
if key == "__name__":
|
| 176 |
+
raise AttributeError()
|
| 177 |
+
|
| 178 |
+
if is_int(key):
|
| 179 |
+
return self.__getitem__(int(key))
|
| 180 |
+
else:
|
| 181 |
+
self._format_and_raise(
|
| 182 |
+
key=key,
|
| 183 |
+
value=None,
|
| 184 |
+
cause=ConfigAttributeError(
|
| 185 |
+
"ListConfig does not support attribute access"
|
| 186 |
+
),
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
+
def __getitem__(self, index: Union[int, slice]) -> Any:
|
| 190 |
+
try:
|
| 191 |
+
if self._is_missing():
|
| 192 |
+
raise MissingMandatoryValue("ListConfig is missing")
|
| 193 |
+
self._validate_get(index, None)
|
| 194 |
+
if self._is_none():
|
| 195 |
+
raise TypeError(
|
| 196 |
+
"ListConfig object representing None is not subscriptable"
|
| 197 |
+
)
|
| 198 |
+
|
| 199 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 200 |
+
if isinstance(index, slice):
|
| 201 |
+
result = []
|
| 202 |
+
start, stop, step = self._correct_index_params(index)
|
| 203 |
+
for slice_idx in itertools.islice(
|
| 204 |
+
range(0, len(self)), start, stop, step
|
| 205 |
+
):
|
| 206 |
+
val = self._resolve_with_default(
|
| 207 |
+
key=slice_idx, value=self.__dict__["_content"][slice_idx]
|
| 208 |
+
)
|
| 209 |
+
result.append(val)
|
| 210 |
+
if index.step and index.step < 0:
|
| 211 |
+
result.reverse()
|
| 212 |
+
return result
|
| 213 |
+
else:
|
| 214 |
+
return self._resolve_with_default(
|
| 215 |
+
key=index, value=self.__dict__["_content"][index]
|
| 216 |
+
)
|
| 217 |
+
except Exception as e:
|
| 218 |
+
self._format_and_raise(key=index, value=None, cause=e)
|
| 219 |
+
|
| 220 |
+
def _correct_index_params(self, index: slice) -> Tuple[int, int, int]:
|
| 221 |
+
start = index.start
|
| 222 |
+
stop = index.stop
|
| 223 |
+
step = index.step
|
| 224 |
+
if index.start and index.start < 0:
|
| 225 |
+
start = self.__len__() + index.start
|
| 226 |
+
if index.stop and index.stop < 0:
|
| 227 |
+
stop = self.__len__() + index.stop
|
| 228 |
+
if index.step and index.step < 0:
|
| 229 |
+
step = abs(step)
|
| 230 |
+
if start and stop:
|
| 231 |
+
if start > stop:
|
| 232 |
+
start, stop = stop + 1, start + 1
|
| 233 |
+
else:
|
| 234 |
+
start = stop = 0
|
| 235 |
+
elif not start and stop:
|
| 236 |
+
start = list(range(self.__len__() - 1, stop, -step))[0]
|
| 237 |
+
stop = None
|
| 238 |
+
elif start and not stop:
|
| 239 |
+
stop = start + 1
|
| 240 |
+
start = (stop - 1) % step
|
| 241 |
+
else:
|
| 242 |
+
start = (self.__len__() - 1) % step
|
| 243 |
+
return start, stop, step
|
| 244 |
+
|
| 245 |
+
def _set_at_index(self, index: Union[int, slice], value: Any) -> None:
|
| 246 |
+
self._set_item_impl(index, value)
|
| 247 |
+
|
| 248 |
+
def __setitem__(self, index: Union[int, slice], value: Any) -> None:
|
| 249 |
+
try:
|
| 250 |
+
if isinstance(index, slice):
|
| 251 |
+
_ = iter(value) # check iterable
|
| 252 |
+
self_indices = index.indices(len(self))
|
| 253 |
+
indexes = range(*self_indices)
|
| 254 |
+
|
| 255 |
+
# Ensure lengths match for extended slice assignment
|
| 256 |
+
if index.step not in (None, 1):
|
| 257 |
+
if len(indexes) != len(value):
|
| 258 |
+
raise ValueError(
|
| 259 |
+
f"attempt to assign sequence of size {len(value)}"
|
| 260 |
+
f" to extended slice of size {len(indexes)}"
|
| 261 |
+
)
|
| 262 |
+
|
| 263 |
+
# Initialize insertion offsets for empty slices
|
| 264 |
+
if len(indexes) == 0:
|
| 265 |
+
curr_index = self_indices[0] - 1
|
| 266 |
+
val_i = -1
|
| 267 |
+
|
| 268 |
+
work_copy = self.copy() # For atomicity manipulate a copy
|
| 269 |
+
|
| 270 |
+
# Delete and optionally replace non empty slices
|
| 271 |
+
only_removed = 0
|
| 272 |
+
for val_i, i in enumerate(indexes):
|
| 273 |
+
curr_index = i - only_removed
|
| 274 |
+
del work_copy[curr_index]
|
| 275 |
+
if val_i < len(value):
|
| 276 |
+
work_copy.insert(curr_index, value[val_i])
|
| 277 |
+
else:
|
| 278 |
+
only_removed += 1
|
| 279 |
+
|
| 280 |
+
# Insert any remaining input items
|
| 281 |
+
for val_i in range(val_i + 1, len(value)):
|
| 282 |
+
curr_index += 1
|
| 283 |
+
work_copy.insert(curr_index, value[val_i])
|
| 284 |
+
|
| 285 |
+
# Reinitialize self with work_copy
|
| 286 |
+
self.clear()
|
| 287 |
+
self.extend(work_copy)
|
| 288 |
+
else:
|
| 289 |
+
self._set_at_index(index, value)
|
| 290 |
+
except Exception as e:
|
| 291 |
+
self._format_and_raise(key=index, value=value, cause=e)
|
| 292 |
+
|
| 293 |
+
def append(self, item: Any) -> None:
|
| 294 |
+
content = self.__dict__["_content"]
|
| 295 |
+
index = len(content)
|
| 296 |
+
content.append(None)
|
| 297 |
+
try:
|
| 298 |
+
self._set_item_impl(index, item)
|
| 299 |
+
except Exception as e:
|
| 300 |
+
del content[index]
|
| 301 |
+
self._format_and_raise(key=index, value=item, cause=e)
|
| 302 |
+
assert False
|
| 303 |
+
|
| 304 |
+
def _update_keys(self) -> None:
|
| 305 |
+
for i in range(len(self)):
|
| 306 |
+
node = self._get_node(i)
|
| 307 |
+
if node is not None:
|
| 308 |
+
assert isinstance(node, Node)
|
| 309 |
+
node._metadata.key = i
|
| 310 |
+
|
| 311 |
+
def insert(self, index: int, item: Any) -> None:
|
| 312 |
+
from omegaconf.omegaconf import _maybe_wrap
|
| 313 |
+
|
| 314 |
+
try:
|
| 315 |
+
if self._get_flag("readonly"):
|
| 316 |
+
raise ReadonlyConfigError("Cannot insert into a read-only ListConfig")
|
| 317 |
+
if self._is_none():
|
| 318 |
+
raise TypeError(
|
| 319 |
+
"Cannot insert into ListConfig object representing None"
|
| 320 |
+
)
|
| 321 |
+
if self._is_missing():
|
| 322 |
+
raise MissingMandatoryValue("Cannot insert into missing ListConfig")
|
| 323 |
+
|
| 324 |
+
try:
|
| 325 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 326 |
+
# insert place holder
|
| 327 |
+
self.__dict__["_content"].insert(index, None)
|
| 328 |
+
is_optional, ref_type = _resolve_optional(self._metadata.element_type)
|
| 329 |
+
node = _maybe_wrap(
|
| 330 |
+
ref_type=ref_type,
|
| 331 |
+
key=index,
|
| 332 |
+
value=item,
|
| 333 |
+
is_optional=is_optional,
|
| 334 |
+
parent=self,
|
| 335 |
+
)
|
| 336 |
+
self._validate_set(key=index, value=node)
|
| 337 |
+
self._set_at_index(index, node)
|
| 338 |
+
self._update_keys()
|
| 339 |
+
except Exception:
|
| 340 |
+
del self.__dict__["_content"][index]
|
| 341 |
+
self._update_keys()
|
| 342 |
+
raise
|
| 343 |
+
except Exception as e:
|
| 344 |
+
self._format_and_raise(key=index, value=item, cause=e)
|
| 345 |
+
assert False
|
| 346 |
+
|
| 347 |
+
def extend(self, lst: Iterable[Any]) -> None:
|
| 348 |
+
assert isinstance(lst, (tuple, list, ListConfig))
|
| 349 |
+
for x in lst:
|
| 350 |
+
self.append(x)
|
| 351 |
+
|
| 352 |
+
def remove(self, x: Any) -> None:
|
| 353 |
+
del self[self.index(x)]
|
| 354 |
+
|
| 355 |
+
def __delitem__(self, key: Union[int, slice]) -> None:
|
| 356 |
+
if self._get_flag("readonly"):
|
| 357 |
+
self._format_and_raise(
|
| 358 |
+
key=key,
|
| 359 |
+
value=None,
|
| 360 |
+
cause=ReadonlyConfigError(
|
| 361 |
+
"Cannot delete item from read-only ListConfig"
|
| 362 |
+
),
|
| 363 |
+
)
|
| 364 |
+
del self.__dict__["_content"][key]
|
| 365 |
+
self._update_keys()
|
| 366 |
+
|
| 367 |
+
def clear(self) -> None:
|
| 368 |
+
del self[:]
|
| 369 |
+
|
| 370 |
+
def index(
|
| 371 |
+
self, x: Any, start: Optional[int] = None, end: Optional[int] = None
|
| 372 |
+
) -> int:
|
| 373 |
+
if start is None:
|
| 374 |
+
start = 0
|
| 375 |
+
if end is None:
|
| 376 |
+
end = len(self)
|
| 377 |
+
assert start >= 0
|
| 378 |
+
assert end <= len(self)
|
| 379 |
+
found_idx = -1
|
| 380 |
+
for idx in range(start, end):
|
| 381 |
+
item = self[idx]
|
| 382 |
+
if x == item:
|
| 383 |
+
found_idx = idx
|
| 384 |
+
break
|
| 385 |
+
if found_idx != -1:
|
| 386 |
+
return found_idx
|
| 387 |
+
else:
|
| 388 |
+
self._format_and_raise(
|
| 389 |
+
key=None,
|
| 390 |
+
value=None,
|
| 391 |
+
cause=ConfigValueError("Item not found in ListConfig"),
|
| 392 |
+
)
|
| 393 |
+
assert False
|
| 394 |
+
|
| 395 |
+
def count(self, x: Any) -> int:
|
| 396 |
+
c = 0
|
| 397 |
+
for item in self:
|
| 398 |
+
if item == x:
|
| 399 |
+
c = c + 1
|
| 400 |
+
return c
|
| 401 |
+
|
| 402 |
+
def _get_node(
|
| 403 |
+
self,
|
| 404 |
+
key: Union[int, slice],
|
| 405 |
+
validate_access: bool = True,
|
| 406 |
+
validate_key: bool = True,
|
| 407 |
+
throw_on_missing_value: bool = False,
|
| 408 |
+
throw_on_missing_key: bool = False,
|
| 409 |
+
) -> Union[Optional[Node], List[Optional[Node]]]:
|
| 410 |
+
try:
|
| 411 |
+
if self._is_none():
|
| 412 |
+
raise TypeError(
|
| 413 |
+
"Cannot get_node from a ListConfig object representing None"
|
| 414 |
+
)
|
| 415 |
+
if self._is_missing():
|
| 416 |
+
raise MissingMandatoryValue("Cannot get_node from a missing ListConfig")
|
| 417 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 418 |
+
if validate_access:
|
| 419 |
+
self._validate_get(key)
|
| 420 |
+
|
| 421 |
+
value = self.__dict__["_content"][key]
|
| 422 |
+
if value is not None:
|
| 423 |
+
if isinstance(key, slice):
|
| 424 |
+
assert isinstance(value, list)
|
| 425 |
+
for v in value:
|
| 426 |
+
if throw_on_missing_value and v._is_missing():
|
| 427 |
+
raise MissingMandatoryValue("Missing mandatory value")
|
| 428 |
+
else:
|
| 429 |
+
assert isinstance(value, Node)
|
| 430 |
+
if throw_on_missing_value and value._is_missing():
|
| 431 |
+
raise MissingMandatoryValue("Missing mandatory value: $KEY")
|
| 432 |
+
return value
|
| 433 |
+
except (IndexError, TypeError, MissingMandatoryValue, KeyValidationError) as e:
|
| 434 |
+
if isinstance(e, MissingMandatoryValue) and throw_on_missing_value:
|
| 435 |
+
raise
|
| 436 |
+
if validate_access:
|
| 437 |
+
self._format_and_raise(key=key, value=None, cause=e)
|
| 438 |
+
assert False
|
| 439 |
+
else:
|
| 440 |
+
return None
|
| 441 |
+
|
| 442 |
+
def get(self, index: int, default_value: Any = None) -> Any:
|
| 443 |
+
try:
|
| 444 |
+
if self._is_none():
|
| 445 |
+
raise TypeError("Cannot get from a ListConfig object representing None")
|
| 446 |
+
if self._is_missing():
|
| 447 |
+
raise MissingMandatoryValue("Cannot get from a missing ListConfig")
|
| 448 |
+
self._validate_get(index, None)
|
| 449 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 450 |
+
return self._resolve_with_default(
|
| 451 |
+
key=index,
|
| 452 |
+
value=self.__dict__["_content"][index],
|
| 453 |
+
default_value=default_value,
|
| 454 |
+
)
|
| 455 |
+
except Exception as e:
|
| 456 |
+
self._format_and_raise(key=index, value=None, cause=e)
|
| 457 |
+
assert False
|
| 458 |
+
|
| 459 |
+
def pop(self, index: int = -1) -> Any:
|
| 460 |
+
try:
|
| 461 |
+
if self._get_flag("readonly"):
|
| 462 |
+
raise ReadonlyConfigError("Cannot pop from read-only ListConfig")
|
| 463 |
+
if self._is_none():
|
| 464 |
+
raise TypeError("Cannot pop from a ListConfig object representing None")
|
| 465 |
+
if self._is_missing():
|
| 466 |
+
raise MissingMandatoryValue("Cannot pop from a missing ListConfig")
|
| 467 |
+
|
| 468 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 469 |
+
node = self._get_child(index)
|
| 470 |
+
assert isinstance(node, Node)
|
| 471 |
+
ret = self._resolve_with_default(key=index, value=node, default_value=None)
|
| 472 |
+
del self.__dict__["_content"][index]
|
| 473 |
+
self._update_keys()
|
| 474 |
+
return ret
|
| 475 |
+
except KeyValidationError as e:
|
| 476 |
+
self._format_and_raise(
|
| 477 |
+
key=index, value=None, cause=e, type_override=ConfigTypeError
|
| 478 |
+
)
|
| 479 |
+
assert False
|
| 480 |
+
except Exception as e:
|
| 481 |
+
self._format_and_raise(key=index, value=None, cause=e)
|
| 482 |
+
assert False
|
| 483 |
+
|
| 484 |
+
def sort(
|
| 485 |
+
self, key: Optional[Callable[[Any], Any]] = None, reverse: bool = False
|
| 486 |
+
) -> None:
|
| 487 |
+
try:
|
| 488 |
+
if self._get_flag("readonly"):
|
| 489 |
+
raise ReadonlyConfigError("Cannot sort a read-only ListConfig")
|
| 490 |
+
if self._is_none():
|
| 491 |
+
raise TypeError("Cannot sort a ListConfig object representing None")
|
| 492 |
+
if self._is_missing():
|
| 493 |
+
raise MissingMandatoryValue("Cannot sort a missing ListConfig")
|
| 494 |
+
|
| 495 |
+
if key is None:
|
| 496 |
+
|
| 497 |
+
def key1(x: Any) -> Any:
|
| 498 |
+
return x._value()
|
| 499 |
+
|
| 500 |
+
else:
|
| 501 |
+
|
| 502 |
+
def key1(x: Any) -> Any:
|
| 503 |
+
return key(x._value()) # type: ignore
|
| 504 |
+
|
| 505 |
+
assert isinstance(self.__dict__["_content"], list)
|
| 506 |
+
self.__dict__["_content"].sort(key=key1, reverse=reverse)
|
| 507 |
+
|
| 508 |
+
except Exception as e:
|
| 509 |
+
self._format_and_raise(key=None, value=None, cause=e)
|
| 510 |
+
assert False
|
| 511 |
+
|
| 512 |
+
def __eq__(self, other: Any) -> bool:
|
| 513 |
+
if isinstance(other, (list, tuple)) or other is None:
|
| 514 |
+
other = ListConfig(other, flags={"allow_objects": True})
|
| 515 |
+
return ListConfig._list_eq(self, other)
|
| 516 |
+
if other is None or isinstance(other, ListConfig):
|
| 517 |
+
return ListConfig._list_eq(self, other)
|
| 518 |
+
if self._is_missing():
|
| 519 |
+
return _is_missing_literal(other)
|
| 520 |
+
return NotImplemented
|
| 521 |
+
|
| 522 |
+
def __ne__(self, other: Any) -> bool:
|
| 523 |
+
x = self.__eq__(other)
|
| 524 |
+
if x is not NotImplemented:
|
| 525 |
+
return not x
|
| 526 |
+
return NotImplemented
|
| 527 |
+
|
| 528 |
+
def __hash__(self) -> int:
|
| 529 |
+
return hash(str(self))
|
| 530 |
+
|
| 531 |
+
def __iter__(self) -> Iterator[Any]:
|
| 532 |
+
return self._iter_ex(resolve=True)
|
| 533 |
+
|
| 534 |
+
class ListIterator(Iterator[Any]):
|
| 535 |
+
def __init__(self, lst: Any, resolve: bool) -> None:
|
| 536 |
+
self.resolve = resolve
|
| 537 |
+
self.iterator = iter(lst.__dict__["_content"])
|
| 538 |
+
self.index = 0
|
| 539 |
+
from .nodes import ValueNode
|
| 540 |
+
|
| 541 |
+
self.ValueNode = ValueNode
|
| 542 |
+
|
| 543 |
+
def __next__(self) -> Any:
|
| 544 |
+
|
| 545 |
+
x = next(self.iterator)
|
| 546 |
+
if self.resolve:
|
| 547 |
+
x = x._dereference_node()
|
| 548 |
+
if x._is_missing():
|
| 549 |
+
raise MissingMandatoryValue(f"Missing value at index {self.index}")
|
| 550 |
+
|
| 551 |
+
self.index = self.index + 1
|
| 552 |
+
if isinstance(x, self.ValueNode):
|
| 553 |
+
return x._value()
|
| 554 |
+
else:
|
| 555 |
+
# Must be omegaconf.Container. not checking for perf reasons.
|
| 556 |
+
if x._is_none():
|
| 557 |
+
return None
|
| 558 |
+
return x
|
| 559 |
+
|
| 560 |
+
def __repr__(self) -> str: # pragma: no cover
|
| 561 |
+
return f"ListConfig.ListIterator(resolve={self.resolve})"
|
| 562 |
+
|
| 563 |
+
def _iter_ex(self, resolve: bool) -> Iterator[Any]:
|
| 564 |
+
try:
|
| 565 |
+
if self._is_none():
|
| 566 |
+
raise TypeError("Cannot iterate a ListConfig object representing None")
|
| 567 |
+
if self._is_missing():
|
| 568 |
+
raise MissingMandatoryValue("Cannot iterate a missing ListConfig")
|
| 569 |
+
|
| 570 |
+
return ListConfig.ListIterator(self, resolve)
|
| 571 |
+
except (TypeError, MissingMandatoryValue) as e:
|
| 572 |
+
self._format_and_raise(key=None, value=None, cause=e)
|
| 573 |
+
assert False
|
| 574 |
+
|
| 575 |
+
def __add__(self, other: Union[List[Any], "ListConfig"]) -> "ListConfig":
|
| 576 |
+
# res is sharing this list's parent to allow interpolation to work as expected
|
| 577 |
+
res = ListConfig(parent=self._get_parent(), content=[])
|
| 578 |
+
res.extend(self)
|
| 579 |
+
res.extend(other)
|
| 580 |
+
return res
|
| 581 |
+
|
| 582 |
+
def __radd__(self, other: Union[List[Any], "ListConfig"]) -> "ListConfig":
|
| 583 |
+
# res is sharing this list's parent to allow interpolation to work as expected
|
| 584 |
+
res = ListConfig(parent=self._get_parent(), content=[])
|
| 585 |
+
res.extend(other)
|
| 586 |
+
res.extend(self)
|
| 587 |
+
return res
|
| 588 |
+
|
| 589 |
+
def __iadd__(self, other: Iterable[Any]) -> "ListConfig":
|
| 590 |
+
self.extend(other)
|
| 591 |
+
return self
|
| 592 |
+
|
| 593 |
+
def __contains__(self, item: Any) -> bool:
|
| 594 |
+
if self._is_none():
|
| 595 |
+
raise TypeError(
|
| 596 |
+
"Cannot check if an item is in a ListConfig object representing None"
|
| 597 |
+
)
|
| 598 |
+
if self._is_missing():
|
| 599 |
+
raise MissingMandatoryValue(
|
| 600 |
+
"Cannot check if an item is in missing ListConfig"
|
| 601 |
+
)
|
| 602 |
+
|
| 603 |
+
lst = self.__dict__["_content"]
|
| 604 |
+
for x in lst:
|
| 605 |
+
x = x._dereference_node()
|
| 606 |
+
if x == item:
|
| 607 |
+
return True
|
| 608 |
+
return False
|
| 609 |
+
|
| 610 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 611 |
+
try:
|
| 612 |
+
previous_content = self.__dict__["_content"]
|
| 613 |
+
previous_metadata = self.__dict__["_metadata"]
|
| 614 |
+
self._set_value_impl(value, flags)
|
| 615 |
+
except Exception as e:
|
| 616 |
+
self.__dict__["_content"] = previous_content
|
| 617 |
+
self.__dict__["_metadata"] = previous_metadata
|
| 618 |
+
raise e
|
| 619 |
+
|
| 620 |
+
def _set_value_impl(
|
| 621 |
+
self, value: Any, flags: Optional[Dict[str, bool]] = None
|
| 622 |
+
) -> None:
|
| 623 |
+
from omegaconf import MISSING, flag_override
|
| 624 |
+
|
| 625 |
+
if flags is None:
|
| 626 |
+
flags = {}
|
| 627 |
+
|
| 628 |
+
vk = get_value_kind(value, strict_interpolation_validation=True)
|
| 629 |
+
if _is_none(value):
|
| 630 |
+
if not self._is_optional():
|
| 631 |
+
raise ValidationError(
|
| 632 |
+
"Non optional ListConfig cannot be constructed from None"
|
| 633 |
+
)
|
| 634 |
+
self.__dict__["_content"] = None
|
| 635 |
+
self._metadata.object_type = None
|
| 636 |
+
elif vk is ValueKind.MANDATORY_MISSING:
|
| 637 |
+
self.__dict__["_content"] = MISSING
|
| 638 |
+
self._metadata.object_type = None
|
| 639 |
+
elif vk == ValueKind.INTERPOLATION:
|
| 640 |
+
self.__dict__["_content"] = value
|
| 641 |
+
self._metadata.object_type = None
|
| 642 |
+
else:
|
| 643 |
+
if not (is_primitive_list(value) or isinstance(value, ListConfig)):
|
| 644 |
+
type_ = type(value)
|
| 645 |
+
msg = f"Invalid value assigned: {type_.__name__} is not a ListConfig, list or tuple."
|
| 646 |
+
raise ValidationError(msg)
|
| 647 |
+
|
| 648 |
+
self.__dict__["_content"] = []
|
| 649 |
+
if isinstance(value, ListConfig):
|
| 650 |
+
self._metadata.flags = copy.deepcopy(flags)
|
| 651 |
+
# disable struct and readonly for the construction phase
|
| 652 |
+
# retaining other flags like allow_objects. The real flags are restored at the end of this function
|
| 653 |
+
with flag_override(self, ["struct", "readonly"], False):
|
| 654 |
+
for item in value._iter_ex(resolve=False):
|
| 655 |
+
self.append(item)
|
| 656 |
+
elif is_primitive_list(value):
|
| 657 |
+
with flag_override(self, ["struct", "readonly"], False):
|
| 658 |
+
for item in value:
|
| 659 |
+
self.append(item)
|
| 660 |
+
self._metadata.object_type = list
|
| 661 |
+
|
| 662 |
+
@staticmethod
|
| 663 |
+
def _list_eq(l1: Optional["ListConfig"], l2: Optional["ListConfig"]) -> bool:
|
| 664 |
+
l1_none = l1.__dict__["_content"] is None
|
| 665 |
+
l2_none = l2.__dict__["_content"] is None
|
| 666 |
+
if l1_none and l2_none:
|
| 667 |
+
return True
|
| 668 |
+
if l1_none != l2_none:
|
| 669 |
+
return False
|
| 670 |
+
|
| 671 |
+
assert isinstance(l1, ListConfig)
|
| 672 |
+
assert isinstance(l2, ListConfig)
|
| 673 |
+
if len(l1) != len(l2):
|
| 674 |
+
return False
|
| 675 |
+
for i in range(len(l1)):
|
| 676 |
+
if not BaseContainer._item_eq(l1, i, l2, i):
|
| 677 |
+
return False
|
| 678 |
+
|
| 679 |
+
return True
|
lib/python3.12/site-packages/omegaconf/nodes.py
ADDED
|
@@ -0,0 +1,545 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import math
|
| 3 |
+
import sys
|
| 4 |
+
from abc import abstractmethod
|
| 5 |
+
from enum import Enum
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
from typing import Any, Dict, Optional, Type, Union
|
| 8 |
+
|
| 9 |
+
from omegaconf._utils import (
|
| 10 |
+
ValueKind,
|
| 11 |
+
_is_interpolation,
|
| 12 |
+
get_type_of,
|
| 13 |
+
get_value_kind,
|
| 14 |
+
is_primitive_container,
|
| 15 |
+
type_str,
|
| 16 |
+
)
|
| 17 |
+
from omegaconf.base import Box, DictKeyType, Metadata, Node
|
| 18 |
+
from omegaconf.errors import ReadonlyConfigError, UnsupportedValueType, ValidationError
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class ValueNode(Node):
|
| 22 |
+
_val: Any
|
| 23 |
+
|
| 24 |
+
def __init__(self, parent: Optional[Box], value: Any, metadata: Metadata):
|
| 25 |
+
from omegaconf import read_write
|
| 26 |
+
|
| 27 |
+
super().__init__(parent=parent, metadata=metadata)
|
| 28 |
+
with read_write(self):
|
| 29 |
+
self._set_value(value) # lgtm [py/init-calls-subclass]
|
| 30 |
+
|
| 31 |
+
def _value(self) -> Any:
|
| 32 |
+
return self._val
|
| 33 |
+
|
| 34 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 35 |
+
if self._get_flag("readonly"):
|
| 36 |
+
raise ReadonlyConfigError("Cannot set value of read-only config node")
|
| 37 |
+
|
| 38 |
+
if isinstance(value, str) and get_value_kind(
|
| 39 |
+
value, strict_interpolation_validation=True
|
| 40 |
+
) in (
|
| 41 |
+
ValueKind.INTERPOLATION,
|
| 42 |
+
ValueKind.MANDATORY_MISSING,
|
| 43 |
+
):
|
| 44 |
+
self._val = value
|
| 45 |
+
else:
|
| 46 |
+
self._val = self.validate_and_convert(value)
|
| 47 |
+
|
| 48 |
+
def _strict_validate_type(self, value: Any) -> None:
|
| 49 |
+
ref_type = self._metadata.ref_type
|
| 50 |
+
if isinstance(ref_type, type) and type(value) is not ref_type:
|
| 51 |
+
type_hint = type_str(self._metadata.type_hint)
|
| 52 |
+
raise ValidationError(
|
| 53 |
+
f"Value '$VALUE' of type '$VALUE_TYPE' is incompatible with type hint '{type_hint}'"
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
def validate_and_convert(self, value: Any) -> Any:
|
| 57 |
+
"""
|
| 58 |
+
Validates input and converts to canonical form
|
| 59 |
+
:param value: input value
|
| 60 |
+
:return: converted value ("100" may be converted to 100 for example)
|
| 61 |
+
"""
|
| 62 |
+
if value is None:
|
| 63 |
+
if self._is_optional():
|
| 64 |
+
return None
|
| 65 |
+
ref_type_str = type_str(self._metadata.ref_type)
|
| 66 |
+
raise ValidationError(
|
| 67 |
+
f"Incompatible value '{value}' for field of type '{ref_type_str}'"
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
# Subclasses can assume that `value` is not None in
|
| 71 |
+
# `_validate_and_convert_impl()` and in `_strict_validate_type()`.
|
| 72 |
+
if self._get_flag("convert") is False:
|
| 73 |
+
self._strict_validate_type(value)
|
| 74 |
+
return value
|
| 75 |
+
else:
|
| 76 |
+
return self._validate_and_convert_impl(value)
|
| 77 |
+
|
| 78 |
+
@abstractmethod
|
| 79 |
+
def _validate_and_convert_impl(self, value: Any) -> Any:
|
| 80 |
+
...
|
| 81 |
+
|
| 82 |
+
def __str__(self) -> str:
|
| 83 |
+
return str(self._val)
|
| 84 |
+
|
| 85 |
+
def __repr__(self) -> str:
|
| 86 |
+
return repr(self._val) if hasattr(self, "_val") else "__INVALID__"
|
| 87 |
+
|
| 88 |
+
def __eq__(self, other: Any) -> bool:
|
| 89 |
+
if isinstance(other, AnyNode):
|
| 90 |
+
return self._val == other._val # type: ignore
|
| 91 |
+
else:
|
| 92 |
+
return self._val == other # type: ignore
|
| 93 |
+
|
| 94 |
+
def __ne__(self, other: Any) -> bool:
|
| 95 |
+
x = self.__eq__(other)
|
| 96 |
+
assert x is not NotImplemented
|
| 97 |
+
return not x
|
| 98 |
+
|
| 99 |
+
def __hash__(self) -> int:
|
| 100 |
+
return hash(self._val)
|
| 101 |
+
|
| 102 |
+
def _deepcopy_impl(self, res: Any, memo: Dict[int, Any]) -> None:
|
| 103 |
+
res.__dict__["_metadata"] = copy.deepcopy(self._metadata, memo=memo)
|
| 104 |
+
# shallow copy for value to support non-copyable value
|
| 105 |
+
res.__dict__["_val"] = self._val
|
| 106 |
+
|
| 107 |
+
# parent is retained, but not copied
|
| 108 |
+
res.__dict__["_parent"] = self._parent
|
| 109 |
+
|
| 110 |
+
def _is_optional(self) -> bool:
|
| 111 |
+
return self._metadata.optional
|
| 112 |
+
|
| 113 |
+
def _is_interpolation(self) -> bool:
|
| 114 |
+
return _is_interpolation(self._value())
|
| 115 |
+
|
| 116 |
+
def _get_full_key(self, key: Optional[Union[DictKeyType, int]]) -> str:
|
| 117 |
+
parent = self._get_parent()
|
| 118 |
+
if parent is None:
|
| 119 |
+
if self._metadata.key is None:
|
| 120 |
+
return ""
|
| 121 |
+
else:
|
| 122 |
+
return str(self._metadata.key)
|
| 123 |
+
else:
|
| 124 |
+
return parent._get_full_key(self._metadata.key)
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
class AnyNode(ValueNode):
|
| 128 |
+
def __init__(
|
| 129 |
+
self,
|
| 130 |
+
value: Any = None,
|
| 131 |
+
key: Any = None,
|
| 132 |
+
parent: Optional[Box] = None,
|
| 133 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 134 |
+
):
|
| 135 |
+
super().__init__(
|
| 136 |
+
parent=parent,
|
| 137 |
+
value=value,
|
| 138 |
+
metadata=Metadata(
|
| 139 |
+
ref_type=Any, object_type=None, key=key, optional=True, flags=flags
|
| 140 |
+
),
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
def _validate_and_convert_impl(self, value: Any) -> Any:
|
| 144 |
+
from ._utils import is_primitive_type_annotation
|
| 145 |
+
|
| 146 |
+
# allow_objects is internal and not an official API. use at your own risk.
|
| 147 |
+
# Please be aware that this support is subject to change without notice.
|
| 148 |
+
# If this is deemed useful and supportable it may become an official API.
|
| 149 |
+
|
| 150 |
+
if self._get_flag(
|
| 151 |
+
"allow_objects"
|
| 152 |
+
) is not True and not is_primitive_type_annotation(value):
|
| 153 |
+
t = get_type_of(value)
|
| 154 |
+
raise UnsupportedValueType(
|
| 155 |
+
f"Value '{t.__name__}' is not a supported primitive type"
|
| 156 |
+
)
|
| 157 |
+
return value
|
| 158 |
+
|
| 159 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "AnyNode":
|
| 160 |
+
res = AnyNode()
|
| 161 |
+
self._deepcopy_impl(res, memo)
|
| 162 |
+
return res
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
class StringNode(ValueNode):
|
| 166 |
+
def __init__(
|
| 167 |
+
self,
|
| 168 |
+
value: Any = None,
|
| 169 |
+
key: Any = None,
|
| 170 |
+
parent: Optional[Box] = None,
|
| 171 |
+
is_optional: bool = True,
|
| 172 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 173 |
+
):
|
| 174 |
+
super().__init__(
|
| 175 |
+
parent=parent,
|
| 176 |
+
value=value,
|
| 177 |
+
metadata=Metadata(
|
| 178 |
+
key=key,
|
| 179 |
+
optional=is_optional,
|
| 180 |
+
ref_type=str,
|
| 181 |
+
object_type=str,
|
| 182 |
+
flags=flags,
|
| 183 |
+
),
|
| 184 |
+
)
|
| 185 |
+
|
| 186 |
+
def _validate_and_convert_impl(self, value: Any) -> str:
|
| 187 |
+
from omegaconf import OmegaConf
|
| 188 |
+
|
| 189 |
+
if (
|
| 190 |
+
OmegaConf.is_config(value)
|
| 191 |
+
or is_primitive_container(value)
|
| 192 |
+
or isinstance(value, bytes)
|
| 193 |
+
):
|
| 194 |
+
raise ValidationError("Cannot convert '$VALUE_TYPE' to string: '$VALUE'")
|
| 195 |
+
return str(value)
|
| 196 |
+
|
| 197 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "StringNode":
|
| 198 |
+
res = StringNode()
|
| 199 |
+
self._deepcopy_impl(res, memo)
|
| 200 |
+
return res
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
class PathNode(ValueNode):
|
| 204 |
+
def __init__(
|
| 205 |
+
self,
|
| 206 |
+
value: Any = None,
|
| 207 |
+
key: Any = None,
|
| 208 |
+
parent: Optional[Box] = None,
|
| 209 |
+
is_optional: bool = True,
|
| 210 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 211 |
+
):
|
| 212 |
+
super().__init__(
|
| 213 |
+
parent=parent,
|
| 214 |
+
value=value,
|
| 215 |
+
metadata=Metadata(
|
| 216 |
+
key=key,
|
| 217 |
+
optional=is_optional,
|
| 218 |
+
ref_type=Path,
|
| 219 |
+
object_type=Path,
|
| 220 |
+
flags=flags,
|
| 221 |
+
),
|
| 222 |
+
)
|
| 223 |
+
|
| 224 |
+
def _strict_validate_type(self, value: Any) -> None:
|
| 225 |
+
if not isinstance(value, Path):
|
| 226 |
+
raise ValidationError(
|
| 227 |
+
"Value '$VALUE' of type '$VALUE_TYPE' is not an instance of 'pathlib.Path'"
|
| 228 |
+
)
|
| 229 |
+
|
| 230 |
+
def _validate_and_convert_impl(self, value: Any) -> Path:
|
| 231 |
+
if not isinstance(value, (str, Path)):
|
| 232 |
+
raise ValidationError(
|
| 233 |
+
"Value '$VALUE' of type '$VALUE_TYPE' could not be converted to Path"
|
| 234 |
+
)
|
| 235 |
+
|
| 236 |
+
return Path(value)
|
| 237 |
+
|
| 238 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "PathNode":
|
| 239 |
+
res = PathNode()
|
| 240 |
+
self._deepcopy_impl(res, memo)
|
| 241 |
+
return res
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
class IntegerNode(ValueNode):
|
| 245 |
+
def __init__(
|
| 246 |
+
self,
|
| 247 |
+
value: Any = None,
|
| 248 |
+
key: Any = None,
|
| 249 |
+
parent: Optional[Box] = None,
|
| 250 |
+
is_optional: bool = True,
|
| 251 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 252 |
+
):
|
| 253 |
+
super().__init__(
|
| 254 |
+
parent=parent,
|
| 255 |
+
value=value,
|
| 256 |
+
metadata=Metadata(
|
| 257 |
+
key=key,
|
| 258 |
+
optional=is_optional,
|
| 259 |
+
ref_type=int,
|
| 260 |
+
object_type=int,
|
| 261 |
+
flags=flags,
|
| 262 |
+
),
|
| 263 |
+
)
|
| 264 |
+
|
| 265 |
+
def _validate_and_convert_impl(self, value: Any) -> int:
|
| 266 |
+
try:
|
| 267 |
+
if type(value) in (str, int):
|
| 268 |
+
val = int(value)
|
| 269 |
+
else:
|
| 270 |
+
raise ValueError()
|
| 271 |
+
except ValueError:
|
| 272 |
+
raise ValidationError(
|
| 273 |
+
"Value '$VALUE' of type '$VALUE_TYPE' could not be converted to Integer"
|
| 274 |
+
)
|
| 275 |
+
return val
|
| 276 |
+
|
| 277 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "IntegerNode":
|
| 278 |
+
res = IntegerNode()
|
| 279 |
+
self._deepcopy_impl(res, memo)
|
| 280 |
+
return res
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
class BytesNode(ValueNode):
|
| 284 |
+
def __init__(
|
| 285 |
+
self,
|
| 286 |
+
value: Any = None,
|
| 287 |
+
key: Any = None,
|
| 288 |
+
parent: Optional[Box] = None,
|
| 289 |
+
is_optional: bool = True,
|
| 290 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 291 |
+
):
|
| 292 |
+
super().__init__(
|
| 293 |
+
parent=parent,
|
| 294 |
+
value=value,
|
| 295 |
+
metadata=Metadata(
|
| 296 |
+
key=key,
|
| 297 |
+
optional=is_optional,
|
| 298 |
+
ref_type=bytes,
|
| 299 |
+
object_type=bytes,
|
| 300 |
+
flags=flags,
|
| 301 |
+
),
|
| 302 |
+
)
|
| 303 |
+
|
| 304 |
+
def _validate_and_convert_impl(self, value: Any) -> bytes:
|
| 305 |
+
if not isinstance(value, bytes):
|
| 306 |
+
raise ValidationError(
|
| 307 |
+
"Value '$VALUE' of type '$VALUE_TYPE' is not of type 'bytes'"
|
| 308 |
+
)
|
| 309 |
+
return value
|
| 310 |
+
|
| 311 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "BytesNode":
|
| 312 |
+
res = BytesNode()
|
| 313 |
+
self._deepcopy_impl(res, memo)
|
| 314 |
+
return res
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
class FloatNode(ValueNode):
|
| 318 |
+
def __init__(
|
| 319 |
+
self,
|
| 320 |
+
value: Any = None,
|
| 321 |
+
key: Any = None,
|
| 322 |
+
parent: Optional[Box] = None,
|
| 323 |
+
is_optional: bool = True,
|
| 324 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 325 |
+
):
|
| 326 |
+
super().__init__(
|
| 327 |
+
parent=parent,
|
| 328 |
+
value=value,
|
| 329 |
+
metadata=Metadata(
|
| 330 |
+
key=key,
|
| 331 |
+
optional=is_optional,
|
| 332 |
+
ref_type=float,
|
| 333 |
+
object_type=float,
|
| 334 |
+
flags=flags,
|
| 335 |
+
),
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
def _validate_and_convert_impl(self, value: Any) -> float:
|
| 339 |
+
try:
|
| 340 |
+
if type(value) in (float, str, int):
|
| 341 |
+
return float(value)
|
| 342 |
+
else:
|
| 343 |
+
raise ValueError()
|
| 344 |
+
except ValueError:
|
| 345 |
+
raise ValidationError(
|
| 346 |
+
"Value '$VALUE' of type '$VALUE_TYPE' could not be converted to Float"
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
def __eq__(self, other: Any) -> bool:
|
| 350 |
+
if isinstance(other, ValueNode):
|
| 351 |
+
other_val = other._val
|
| 352 |
+
else:
|
| 353 |
+
other_val = other
|
| 354 |
+
if self._val is None and other is None:
|
| 355 |
+
return True
|
| 356 |
+
if self._val is None and other is not None:
|
| 357 |
+
return False
|
| 358 |
+
if self._val is not None and other is None:
|
| 359 |
+
return False
|
| 360 |
+
nan1 = math.isnan(self._val) if isinstance(self._val, float) else False
|
| 361 |
+
nan2 = math.isnan(other_val) if isinstance(other_val, float) else False
|
| 362 |
+
return self._val == other_val or (nan1 and nan2)
|
| 363 |
+
|
| 364 |
+
def __hash__(self) -> int:
|
| 365 |
+
return hash(self._val)
|
| 366 |
+
|
| 367 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "FloatNode":
|
| 368 |
+
res = FloatNode()
|
| 369 |
+
self._deepcopy_impl(res, memo)
|
| 370 |
+
return res
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
class BooleanNode(ValueNode):
|
| 374 |
+
def __init__(
|
| 375 |
+
self,
|
| 376 |
+
value: Any = None,
|
| 377 |
+
key: Any = None,
|
| 378 |
+
parent: Optional[Box] = None,
|
| 379 |
+
is_optional: bool = True,
|
| 380 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 381 |
+
):
|
| 382 |
+
super().__init__(
|
| 383 |
+
parent=parent,
|
| 384 |
+
value=value,
|
| 385 |
+
metadata=Metadata(
|
| 386 |
+
key=key,
|
| 387 |
+
optional=is_optional,
|
| 388 |
+
ref_type=bool,
|
| 389 |
+
object_type=bool,
|
| 390 |
+
flags=flags,
|
| 391 |
+
),
|
| 392 |
+
)
|
| 393 |
+
|
| 394 |
+
def _validate_and_convert_impl(self, value: Any) -> bool:
|
| 395 |
+
if isinstance(value, bool):
|
| 396 |
+
return value
|
| 397 |
+
if isinstance(value, int):
|
| 398 |
+
return value != 0
|
| 399 |
+
elif isinstance(value, str):
|
| 400 |
+
try:
|
| 401 |
+
return self._validate_and_convert_impl(int(value))
|
| 402 |
+
except ValueError as e:
|
| 403 |
+
if value.lower() in ("yes", "y", "on", "true"):
|
| 404 |
+
return True
|
| 405 |
+
elif value.lower() in ("no", "n", "off", "false"):
|
| 406 |
+
return False
|
| 407 |
+
else:
|
| 408 |
+
raise ValidationError(
|
| 409 |
+
"Value '$VALUE' is not a valid bool (type $VALUE_TYPE)"
|
| 410 |
+
).with_traceback(sys.exc_info()[2]) from e
|
| 411 |
+
else:
|
| 412 |
+
raise ValidationError(
|
| 413 |
+
"Value '$VALUE' is not a valid bool (type $VALUE_TYPE)"
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "BooleanNode":
|
| 417 |
+
res = BooleanNode()
|
| 418 |
+
self._deepcopy_impl(res, memo)
|
| 419 |
+
return res
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
class EnumNode(ValueNode): # lgtm [py/missing-equals] : Intentional.
|
| 423 |
+
"""
|
| 424 |
+
NOTE: EnumNode is serialized to yaml as a string ("Color.BLUE"), not as a fully qualified yaml type.
|
| 425 |
+
this means serialization to YAML of a typed config (with EnumNode) will not retain the type of the Enum
|
| 426 |
+
when loaded.
|
| 427 |
+
This is intentional, Please open an issue against OmegaConf if you wish to discuss this decision.
|
| 428 |
+
"""
|
| 429 |
+
|
| 430 |
+
def __init__(
|
| 431 |
+
self,
|
| 432 |
+
enum_type: Type[Enum],
|
| 433 |
+
value: Optional[Union[Enum, str]] = None,
|
| 434 |
+
key: Any = None,
|
| 435 |
+
parent: Optional[Box] = None,
|
| 436 |
+
is_optional: bool = True,
|
| 437 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 438 |
+
):
|
| 439 |
+
if not isinstance(enum_type, type) or not issubclass(enum_type, Enum):
|
| 440 |
+
raise ValidationError(
|
| 441 |
+
f"EnumNode can only operate on Enum subclasses ({enum_type})"
|
| 442 |
+
)
|
| 443 |
+
self.fields: Dict[str, str] = {}
|
| 444 |
+
self.enum_type: Type[Enum] = enum_type
|
| 445 |
+
for name, constant in enum_type.__members__.items():
|
| 446 |
+
self.fields[name] = constant.value
|
| 447 |
+
super().__init__(
|
| 448 |
+
parent=parent,
|
| 449 |
+
value=value,
|
| 450 |
+
metadata=Metadata(
|
| 451 |
+
key=key,
|
| 452 |
+
optional=is_optional,
|
| 453 |
+
ref_type=enum_type,
|
| 454 |
+
object_type=enum_type,
|
| 455 |
+
flags=flags,
|
| 456 |
+
),
|
| 457 |
+
)
|
| 458 |
+
|
| 459 |
+
def _strict_validate_type(self, value: Any) -> None:
|
| 460 |
+
ref_type = self._metadata.ref_type
|
| 461 |
+
if not isinstance(value, ref_type):
|
| 462 |
+
type_hint = type_str(self._metadata.type_hint)
|
| 463 |
+
raise ValidationError(
|
| 464 |
+
f"Value '$VALUE' of type '$VALUE_TYPE' is incompatible with type hint '{type_hint}'"
|
| 465 |
+
)
|
| 466 |
+
|
| 467 |
+
def _validate_and_convert_impl(self, value: Any) -> Enum:
|
| 468 |
+
return self.validate_and_convert_to_enum(enum_type=self.enum_type, value=value)
|
| 469 |
+
|
| 470 |
+
@staticmethod
|
| 471 |
+
def validate_and_convert_to_enum(enum_type: Type[Enum], value: Any) -> Enum:
|
| 472 |
+
if not isinstance(value, (str, int)) and not isinstance(value, enum_type):
|
| 473 |
+
raise ValidationError(
|
| 474 |
+
f"Value $VALUE ($VALUE_TYPE) is not a valid input for {enum_type}"
|
| 475 |
+
)
|
| 476 |
+
|
| 477 |
+
if isinstance(value, enum_type):
|
| 478 |
+
return value
|
| 479 |
+
|
| 480 |
+
try:
|
| 481 |
+
if isinstance(value, (float, bool)):
|
| 482 |
+
raise ValueError
|
| 483 |
+
|
| 484 |
+
if isinstance(value, int):
|
| 485 |
+
return enum_type(value)
|
| 486 |
+
|
| 487 |
+
if isinstance(value, str):
|
| 488 |
+
prefix = f"{enum_type.__name__}."
|
| 489 |
+
if value.startswith(prefix):
|
| 490 |
+
value = value[len(prefix) :]
|
| 491 |
+
return enum_type[value]
|
| 492 |
+
|
| 493 |
+
assert False
|
| 494 |
+
|
| 495 |
+
except (ValueError, KeyError) as e:
|
| 496 |
+
valid = ", ".join([x for x in enum_type.__members__.keys()])
|
| 497 |
+
raise ValidationError(
|
| 498 |
+
f"Invalid value '$VALUE', expected one of [{valid}]"
|
| 499 |
+
).with_traceback(sys.exc_info()[2]) from e
|
| 500 |
+
|
| 501 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "EnumNode":
|
| 502 |
+
res = EnumNode(enum_type=self.enum_type)
|
| 503 |
+
self._deepcopy_impl(res, memo)
|
| 504 |
+
return res
|
| 505 |
+
|
| 506 |
+
|
| 507 |
+
class InterpolationResultNode(ValueNode):
|
| 508 |
+
"""
|
| 509 |
+
Special node type, used to wrap interpolation results.
|
| 510 |
+
"""
|
| 511 |
+
|
| 512 |
+
def __init__(
|
| 513 |
+
self,
|
| 514 |
+
value: Any,
|
| 515 |
+
key: Any = None,
|
| 516 |
+
parent: Optional[Box] = None,
|
| 517 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 518 |
+
):
|
| 519 |
+
super().__init__(
|
| 520 |
+
parent=parent,
|
| 521 |
+
value=value,
|
| 522 |
+
metadata=Metadata(
|
| 523 |
+
ref_type=Any, object_type=None, key=key, optional=True, flags=flags
|
| 524 |
+
),
|
| 525 |
+
)
|
| 526 |
+
# In general we should not try to write into interpolation results.
|
| 527 |
+
if flags is None or "readonly" not in flags:
|
| 528 |
+
self._set_flag("readonly", True)
|
| 529 |
+
|
| 530 |
+
def _set_value(self, value: Any, flags: Optional[Dict[str, bool]] = None) -> None:
|
| 531 |
+
if self._get_flag("readonly"):
|
| 532 |
+
raise ReadonlyConfigError("Cannot set value of read-only config node")
|
| 533 |
+
self._val = self.validate_and_convert(value)
|
| 534 |
+
|
| 535 |
+
def _validate_and_convert_impl(self, value: Any) -> Any:
|
| 536 |
+
# Interpolation results may be anything.
|
| 537 |
+
return value
|
| 538 |
+
|
| 539 |
+
def __deepcopy__(self, memo: Dict[int, Any]) -> "InterpolationResultNode":
|
| 540 |
+
# Currently there should be no need to deep-copy such nodes.
|
| 541 |
+
raise NotImplementedError
|
| 542 |
+
|
| 543 |
+
def _is_interpolation(self) -> bool:
|
| 544 |
+
# The result of an interpolation cannot be itself an interpolation.
|
| 545 |
+
return False
|
lib/python3.12/site-packages/omegaconf/omegaconf.py
ADDED
|
@@ -0,0 +1,1157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""OmegaConf module"""
|
| 2 |
+
import copy
|
| 3 |
+
import inspect
|
| 4 |
+
import io
|
| 5 |
+
import os
|
| 6 |
+
import pathlib
|
| 7 |
+
import sys
|
| 8 |
+
import warnings
|
| 9 |
+
from collections import defaultdict
|
| 10 |
+
from contextlib import contextmanager
|
| 11 |
+
from enum import Enum
|
| 12 |
+
from textwrap import dedent
|
| 13 |
+
from typing import (
|
| 14 |
+
IO,
|
| 15 |
+
Any,
|
| 16 |
+
Callable,
|
| 17 |
+
Dict,
|
| 18 |
+
Generator,
|
| 19 |
+
Iterable,
|
| 20 |
+
List,
|
| 21 |
+
Optional,
|
| 22 |
+
Set,
|
| 23 |
+
Tuple,
|
| 24 |
+
Type,
|
| 25 |
+
Union,
|
| 26 |
+
overload,
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
import yaml
|
| 30 |
+
|
| 31 |
+
from . import DictConfig, DictKeyType, ListConfig
|
| 32 |
+
from ._utils import (
|
| 33 |
+
_DEFAULT_MARKER_,
|
| 34 |
+
_ensure_container,
|
| 35 |
+
_get_value,
|
| 36 |
+
format_and_raise,
|
| 37 |
+
get_dict_key_value_types,
|
| 38 |
+
get_list_element_type,
|
| 39 |
+
get_omega_conf_dumper,
|
| 40 |
+
get_type_of,
|
| 41 |
+
is_attr_class,
|
| 42 |
+
is_dataclass,
|
| 43 |
+
is_dict_annotation,
|
| 44 |
+
is_int,
|
| 45 |
+
is_list_annotation,
|
| 46 |
+
is_primitive_container,
|
| 47 |
+
is_primitive_dict,
|
| 48 |
+
is_primitive_list,
|
| 49 |
+
is_structured_config,
|
| 50 |
+
is_tuple_annotation,
|
| 51 |
+
is_union_annotation,
|
| 52 |
+
nullcontext,
|
| 53 |
+
split_key,
|
| 54 |
+
type_str,
|
| 55 |
+
)
|
| 56 |
+
from .base import Box, Container, Node, SCMode, UnionNode
|
| 57 |
+
from .basecontainer import BaseContainer
|
| 58 |
+
from .errors import (
|
| 59 |
+
MissingMandatoryValue,
|
| 60 |
+
OmegaConfBaseException,
|
| 61 |
+
UnsupportedInterpolationType,
|
| 62 |
+
ValidationError,
|
| 63 |
+
)
|
| 64 |
+
from .nodes import (
|
| 65 |
+
AnyNode,
|
| 66 |
+
BooleanNode,
|
| 67 |
+
BytesNode,
|
| 68 |
+
EnumNode,
|
| 69 |
+
FloatNode,
|
| 70 |
+
IntegerNode,
|
| 71 |
+
PathNode,
|
| 72 |
+
StringNode,
|
| 73 |
+
ValueNode,
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
MISSING: Any = "???"
|
| 77 |
+
|
| 78 |
+
Resolver = Callable[..., Any]
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def II(interpolation: str) -> Any:
|
| 82 |
+
"""
|
| 83 |
+
Equivalent to ``${interpolation}``
|
| 84 |
+
|
| 85 |
+
:param interpolation:
|
| 86 |
+
:return: input ``${node}`` with type Any
|
| 87 |
+
"""
|
| 88 |
+
return "${" + interpolation + "}"
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def SI(interpolation: str) -> Any:
|
| 92 |
+
"""
|
| 93 |
+
Use this for String interpolation, for example ``"http://${host}:${port}"``
|
| 94 |
+
|
| 95 |
+
:param interpolation: interpolation string
|
| 96 |
+
:return: input interpolation with type ``Any``
|
| 97 |
+
"""
|
| 98 |
+
return interpolation
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def register_default_resolvers() -> None:
|
| 102 |
+
from omegaconf.resolvers import oc
|
| 103 |
+
|
| 104 |
+
OmegaConf.register_new_resolver("oc.create", oc.create)
|
| 105 |
+
OmegaConf.register_new_resolver("oc.decode", oc.decode)
|
| 106 |
+
OmegaConf.register_new_resolver("oc.deprecated", oc.deprecated)
|
| 107 |
+
OmegaConf.register_new_resolver("oc.env", oc.env)
|
| 108 |
+
OmegaConf.register_new_resolver("oc.select", oc.select)
|
| 109 |
+
OmegaConf.register_new_resolver("oc.dict.keys", oc.dict.keys)
|
| 110 |
+
OmegaConf.register_new_resolver("oc.dict.values", oc.dict.values)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
class OmegaConf:
|
| 114 |
+
"""OmegaConf primary class"""
|
| 115 |
+
|
| 116 |
+
def __init__(self) -> None:
|
| 117 |
+
raise NotImplementedError("Use one of the static construction functions")
|
| 118 |
+
|
| 119 |
+
@staticmethod
|
| 120 |
+
def structured(
|
| 121 |
+
obj: Any,
|
| 122 |
+
parent: Optional[BaseContainer] = None,
|
| 123 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 124 |
+
) -> Any:
|
| 125 |
+
return OmegaConf.create(obj, parent, flags)
|
| 126 |
+
|
| 127 |
+
@staticmethod
|
| 128 |
+
@overload
|
| 129 |
+
def create(
|
| 130 |
+
obj: str,
|
| 131 |
+
parent: Optional[BaseContainer] = None,
|
| 132 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 133 |
+
) -> Union[DictConfig, ListConfig]:
|
| 134 |
+
...
|
| 135 |
+
|
| 136 |
+
@staticmethod
|
| 137 |
+
@overload
|
| 138 |
+
def create(
|
| 139 |
+
obj: Union[List[Any], Tuple[Any, ...]],
|
| 140 |
+
parent: Optional[BaseContainer] = None,
|
| 141 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 142 |
+
) -> ListConfig:
|
| 143 |
+
...
|
| 144 |
+
|
| 145 |
+
@staticmethod
|
| 146 |
+
@overload
|
| 147 |
+
def create(
|
| 148 |
+
obj: DictConfig,
|
| 149 |
+
parent: Optional[BaseContainer] = None,
|
| 150 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 151 |
+
) -> DictConfig:
|
| 152 |
+
...
|
| 153 |
+
|
| 154 |
+
@staticmethod
|
| 155 |
+
@overload
|
| 156 |
+
def create(
|
| 157 |
+
obj: ListConfig,
|
| 158 |
+
parent: Optional[BaseContainer] = None,
|
| 159 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 160 |
+
) -> ListConfig:
|
| 161 |
+
...
|
| 162 |
+
|
| 163 |
+
@staticmethod
|
| 164 |
+
@overload
|
| 165 |
+
def create(
|
| 166 |
+
obj: Optional[Dict[Any, Any]] = None,
|
| 167 |
+
parent: Optional[BaseContainer] = None,
|
| 168 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 169 |
+
) -> DictConfig:
|
| 170 |
+
...
|
| 171 |
+
|
| 172 |
+
@staticmethod
|
| 173 |
+
def create( # noqa F811
|
| 174 |
+
obj: Any = _DEFAULT_MARKER_,
|
| 175 |
+
parent: Optional[BaseContainer] = None,
|
| 176 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 177 |
+
) -> Union[DictConfig, ListConfig]:
|
| 178 |
+
return OmegaConf._create_impl(
|
| 179 |
+
obj=obj,
|
| 180 |
+
parent=parent,
|
| 181 |
+
flags=flags,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
@staticmethod
|
| 185 |
+
def load(file_: Union[str, pathlib.Path, IO[Any]]) -> Union[DictConfig, ListConfig]:
|
| 186 |
+
from ._utils import get_yaml_loader
|
| 187 |
+
|
| 188 |
+
if isinstance(file_, (str, pathlib.Path)):
|
| 189 |
+
with io.open(os.path.abspath(file_), "r", encoding="utf-8") as f:
|
| 190 |
+
obj = yaml.load(f, Loader=get_yaml_loader())
|
| 191 |
+
elif getattr(file_, "read", None):
|
| 192 |
+
obj = yaml.load(file_, Loader=get_yaml_loader())
|
| 193 |
+
else:
|
| 194 |
+
raise TypeError("Unexpected file type")
|
| 195 |
+
|
| 196 |
+
if obj is not None and not isinstance(obj, (list, dict, str)):
|
| 197 |
+
raise IOError( # pragma: no cover
|
| 198 |
+
f"Invalid loaded object type: {type(obj).__name__}"
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
ret: Union[DictConfig, ListConfig]
|
| 202 |
+
if obj is None:
|
| 203 |
+
ret = OmegaConf.create()
|
| 204 |
+
else:
|
| 205 |
+
ret = OmegaConf.create(obj)
|
| 206 |
+
return ret
|
| 207 |
+
|
| 208 |
+
@staticmethod
|
| 209 |
+
def save(
|
| 210 |
+
config: Any, f: Union[str, pathlib.Path, IO[Any]], resolve: bool = False
|
| 211 |
+
) -> None:
|
| 212 |
+
"""
|
| 213 |
+
Save as configuration object to a file
|
| 214 |
+
|
| 215 |
+
:param config: omegaconf.Config object (DictConfig or ListConfig).
|
| 216 |
+
:param f: filename or file object
|
| 217 |
+
:param resolve: True to save a resolved config (defaults to False)
|
| 218 |
+
"""
|
| 219 |
+
if is_dataclass(config) or is_attr_class(config):
|
| 220 |
+
config = OmegaConf.create(config)
|
| 221 |
+
data = OmegaConf.to_yaml(config, resolve=resolve)
|
| 222 |
+
if isinstance(f, (str, pathlib.Path)):
|
| 223 |
+
with io.open(os.path.abspath(f), "w", encoding="utf-8") as file:
|
| 224 |
+
file.write(data)
|
| 225 |
+
elif hasattr(f, "write"):
|
| 226 |
+
f.write(data)
|
| 227 |
+
f.flush()
|
| 228 |
+
else:
|
| 229 |
+
raise TypeError("Unexpected file type")
|
| 230 |
+
|
| 231 |
+
@staticmethod
|
| 232 |
+
def from_cli(args_list: Optional[List[str]] = None) -> DictConfig:
|
| 233 |
+
if args_list is None:
|
| 234 |
+
# Skip program name
|
| 235 |
+
args_list = sys.argv[1:]
|
| 236 |
+
return OmegaConf.from_dotlist(args_list)
|
| 237 |
+
|
| 238 |
+
@staticmethod
|
| 239 |
+
def from_dotlist(dotlist: List[str]) -> DictConfig:
|
| 240 |
+
"""
|
| 241 |
+
Creates config from the content sys.argv or from the specified args list of not None
|
| 242 |
+
|
| 243 |
+
:param dotlist: A list of dotlist-style strings, e.g. ``["foo.bar=1", "baz=qux"]``.
|
| 244 |
+
:return: A ``DictConfig`` object created from the dotlist.
|
| 245 |
+
"""
|
| 246 |
+
conf = OmegaConf.create()
|
| 247 |
+
conf.merge_with_dotlist(dotlist)
|
| 248 |
+
return conf
|
| 249 |
+
|
| 250 |
+
@staticmethod
|
| 251 |
+
def merge(
|
| 252 |
+
*configs: Union[
|
| 253 |
+
DictConfig,
|
| 254 |
+
ListConfig,
|
| 255 |
+
Dict[DictKeyType, Any],
|
| 256 |
+
List[Any],
|
| 257 |
+
Tuple[Any, ...],
|
| 258 |
+
Any,
|
| 259 |
+
],
|
| 260 |
+
) -> Union[ListConfig, DictConfig]:
|
| 261 |
+
"""
|
| 262 |
+
Merge a list of previously created configs into a single one
|
| 263 |
+
|
| 264 |
+
:param configs: Input configs
|
| 265 |
+
:return: the merged config object.
|
| 266 |
+
"""
|
| 267 |
+
assert len(configs) > 0
|
| 268 |
+
target = copy.deepcopy(configs[0])
|
| 269 |
+
target = _ensure_container(target)
|
| 270 |
+
assert isinstance(target, (DictConfig, ListConfig))
|
| 271 |
+
|
| 272 |
+
with flag_override(target, "readonly", False):
|
| 273 |
+
target.merge_with(*configs[1:])
|
| 274 |
+
turned_readonly = target._get_flag("readonly") is True
|
| 275 |
+
|
| 276 |
+
if turned_readonly:
|
| 277 |
+
OmegaConf.set_readonly(target, True)
|
| 278 |
+
|
| 279 |
+
return target
|
| 280 |
+
|
| 281 |
+
@staticmethod
|
| 282 |
+
def unsafe_merge(
|
| 283 |
+
*configs: Union[
|
| 284 |
+
DictConfig,
|
| 285 |
+
ListConfig,
|
| 286 |
+
Dict[DictKeyType, Any],
|
| 287 |
+
List[Any],
|
| 288 |
+
Tuple[Any, ...],
|
| 289 |
+
Any,
|
| 290 |
+
],
|
| 291 |
+
) -> Union[ListConfig, DictConfig]:
|
| 292 |
+
"""
|
| 293 |
+
Merge a list of previously created configs into a single one
|
| 294 |
+
This is much faster than OmegaConf.merge() as the input configs are not copied.
|
| 295 |
+
However, the input configs must not be used after this operation as will become inconsistent.
|
| 296 |
+
|
| 297 |
+
:param configs: Input configs
|
| 298 |
+
:return: the merged config object.
|
| 299 |
+
"""
|
| 300 |
+
assert len(configs) > 0
|
| 301 |
+
target = configs[0]
|
| 302 |
+
target = _ensure_container(target)
|
| 303 |
+
assert isinstance(target, (DictConfig, ListConfig))
|
| 304 |
+
|
| 305 |
+
with flag_override(
|
| 306 |
+
target, ["readonly", "no_deepcopy_set_nodes"], [False, True]
|
| 307 |
+
):
|
| 308 |
+
target.merge_with(*configs[1:])
|
| 309 |
+
turned_readonly = target._get_flag("readonly") is True
|
| 310 |
+
|
| 311 |
+
if turned_readonly:
|
| 312 |
+
OmegaConf.set_readonly(target, True)
|
| 313 |
+
|
| 314 |
+
return target
|
| 315 |
+
|
| 316 |
+
@staticmethod
|
| 317 |
+
def register_resolver(name: str, resolver: Resolver) -> None:
|
| 318 |
+
warnings.warn(
|
| 319 |
+
dedent(
|
| 320 |
+
"""\
|
| 321 |
+
register_resolver() is deprecated.
|
| 322 |
+
See https://github.com/omry/omegaconf/issues/426 for migration instructions.
|
| 323 |
+
"""
|
| 324 |
+
),
|
| 325 |
+
stacklevel=2,
|
| 326 |
+
)
|
| 327 |
+
return OmegaConf.legacy_register_resolver(name, resolver)
|
| 328 |
+
|
| 329 |
+
# This function will eventually be deprecated and removed.
|
| 330 |
+
@staticmethod
|
| 331 |
+
def legacy_register_resolver(name: str, resolver: Resolver) -> None:
|
| 332 |
+
assert callable(resolver), "resolver must be callable"
|
| 333 |
+
# noinspection PyProtectedMember
|
| 334 |
+
assert (
|
| 335 |
+
name not in BaseContainer._resolvers
|
| 336 |
+
), f"resolver '{name}' is already registered"
|
| 337 |
+
|
| 338 |
+
def resolver_wrapper(
|
| 339 |
+
config: BaseContainer,
|
| 340 |
+
parent: BaseContainer,
|
| 341 |
+
node: Node,
|
| 342 |
+
args: Tuple[Any, ...],
|
| 343 |
+
args_str: Tuple[str, ...],
|
| 344 |
+
) -> Any:
|
| 345 |
+
cache = OmegaConf.get_cache(config)[name]
|
| 346 |
+
# "Un-escape " spaces and commas.
|
| 347 |
+
args_unesc = [x.replace(r"\ ", " ").replace(r"\,", ",") for x in args_str]
|
| 348 |
+
|
| 349 |
+
# Nested interpolations behave in a potentially surprising way with
|
| 350 |
+
# legacy resolvers (they remain as strings, e.g., "${foo}"). If any
|
| 351 |
+
# input looks like an interpolation we thus raise an exception.
|
| 352 |
+
try:
|
| 353 |
+
bad_arg = next(i for i in args_unesc if "${" in i)
|
| 354 |
+
except StopIteration:
|
| 355 |
+
pass
|
| 356 |
+
else:
|
| 357 |
+
raise ValueError(
|
| 358 |
+
f"Resolver '{name}' was called with argument '{bad_arg}' that appears "
|
| 359 |
+
f"to be an interpolation. Nested interpolations are not supported for "
|
| 360 |
+
f"resolvers registered with `[legacy_]register_resolver()`, please use "
|
| 361 |
+
f"`register_new_resolver()` instead (see "
|
| 362 |
+
f"https://github.com/omry/omegaconf/issues/426 for migration instructions)."
|
| 363 |
+
)
|
| 364 |
+
key = args_str
|
| 365 |
+
val = cache[key] if key in cache else resolver(*args_unesc)
|
| 366 |
+
cache[key] = val
|
| 367 |
+
return val
|
| 368 |
+
|
| 369 |
+
# noinspection PyProtectedMember
|
| 370 |
+
BaseContainer._resolvers[name] = resolver_wrapper
|
| 371 |
+
|
| 372 |
+
@staticmethod
|
| 373 |
+
def register_new_resolver(
|
| 374 |
+
name: str,
|
| 375 |
+
resolver: Resolver,
|
| 376 |
+
*,
|
| 377 |
+
replace: bool = False,
|
| 378 |
+
use_cache: bool = False,
|
| 379 |
+
) -> None:
|
| 380 |
+
"""
|
| 381 |
+
Register a resolver.
|
| 382 |
+
|
| 383 |
+
:param name: Name of the resolver.
|
| 384 |
+
:param resolver: Callable whose arguments are provided in the interpolation,
|
| 385 |
+
e.g., with ${foo:x,0,${y.z}} these arguments are respectively "x" (str),
|
| 386 |
+
0 (int) and the value of ``y.z``.
|
| 387 |
+
:param replace: If set to ``False`` (default), then a ``ValueError`` is raised if
|
| 388 |
+
an existing resolver has already been registered with the same name.
|
| 389 |
+
If set to ``True``, then the new resolver replaces the previous one.
|
| 390 |
+
NOTE: The cache on existing config objects is not affected, use
|
| 391 |
+
``OmegaConf.clear_cache(cfg)`` to clear it.
|
| 392 |
+
:param use_cache: Whether the resolver's outputs should be cached. The cache is
|
| 393 |
+
based only on the string literals representing the resolver arguments, e.g.,
|
| 394 |
+
${foo:${bar}} will always return the same value regardless of the value of
|
| 395 |
+
``bar`` if the cache is enabled for ``foo``.
|
| 396 |
+
"""
|
| 397 |
+
if not callable(resolver):
|
| 398 |
+
raise TypeError("resolver must be callable")
|
| 399 |
+
if not name:
|
| 400 |
+
raise ValueError("cannot use an empty resolver name")
|
| 401 |
+
|
| 402 |
+
if not replace and OmegaConf.has_resolver(name):
|
| 403 |
+
raise ValueError(f"resolver '{name}' is already registered")
|
| 404 |
+
|
| 405 |
+
try:
|
| 406 |
+
sig: Optional[inspect.Signature] = inspect.signature(resolver)
|
| 407 |
+
except ValueError:
|
| 408 |
+
sig = None
|
| 409 |
+
|
| 410 |
+
def _should_pass(special: str) -> bool:
|
| 411 |
+
ret = sig is not None and special in sig.parameters
|
| 412 |
+
if ret and use_cache:
|
| 413 |
+
raise ValueError(
|
| 414 |
+
f"use_cache=True is incompatible with functions that receive the {special}"
|
| 415 |
+
)
|
| 416 |
+
return ret
|
| 417 |
+
|
| 418 |
+
pass_parent = _should_pass("_parent_")
|
| 419 |
+
pass_node = _should_pass("_node_")
|
| 420 |
+
pass_root = _should_pass("_root_")
|
| 421 |
+
|
| 422 |
+
def resolver_wrapper(
|
| 423 |
+
config: BaseContainer,
|
| 424 |
+
parent: Container,
|
| 425 |
+
node: Node,
|
| 426 |
+
args: Tuple[Any, ...],
|
| 427 |
+
args_str: Tuple[str, ...],
|
| 428 |
+
) -> Any:
|
| 429 |
+
if use_cache:
|
| 430 |
+
cache = OmegaConf.get_cache(config)[name]
|
| 431 |
+
try:
|
| 432 |
+
return cache[args_str]
|
| 433 |
+
except KeyError:
|
| 434 |
+
pass
|
| 435 |
+
|
| 436 |
+
# Call resolver.
|
| 437 |
+
kwargs: Dict[str, Node] = {}
|
| 438 |
+
if pass_parent:
|
| 439 |
+
kwargs["_parent_"] = parent
|
| 440 |
+
if pass_node:
|
| 441 |
+
kwargs["_node_"] = node
|
| 442 |
+
if pass_root:
|
| 443 |
+
kwargs["_root_"] = config
|
| 444 |
+
|
| 445 |
+
ret = resolver(*args, **kwargs)
|
| 446 |
+
|
| 447 |
+
if use_cache:
|
| 448 |
+
cache[args_str] = ret
|
| 449 |
+
return ret
|
| 450 |
+
|
| 451 |
+
# noinspection PyProtectedMember
|
| 452 |
+
BaseContainer._resolvers[name] = resolver_wrapper
|
| 453 |
+
|
| 454 |
+
@classmethod
|
| 455 |
+
def has_resolver(cls, name: str) -> bool:
|
| 456 |
+
return cls._get_resolver(name) is not None
|
| 457 |
+
|
| 458 |
+
# noinspection PyProtectedMember
|
| 459 |
+
@staticmethod
|
| 460 |
+
def clear_resolvers() -> None:
|
| 461 |
+
"""
|
| 462 |
+
Clear(remove) all OmegaConf resolvers, then re-register OmegaConf's default resolvers.
|
| 463 |
+
"""
|
| 464 |
+
BaseContainer._resolvers = {}
|
| 465 |
+
register_default_resolvers()
|
| 466 |
+
|
| 467 |
+
@classmethod
|
| 468 |
+
def clear_resolver(cls, name: str) -> bool:
|
| 469 |
+
"""
|
| 470 |
+
Clear(remove) any resolver only if it exists.
|
| 471 |
+
|
| 472 |
+
Returns a bool: True if resolver is removed and False if not removed.
|
| 473 |
+
|
| 474 |
+
.. warning:
|
| 475 |
+
This method can remove deafult resolvers as well.
|
| 476 |
+
|
| 477 |
+
:param name: Name of the resolver.
|
| 478 |
+
:return: A bool (``True`` if resolver is removed, ``False`` if not found before removing).
|
| 479 |
+
"""
|
| 480 |
+
if cls.has_resolver(name):
|
| 481 |
+
BaseContainer._resolvers.pop(name)
|
| 482 |
+
return True
|
| 483 |
+
else:
|
| 484 |
+
# return False if resolver does not exist
|
| 485 |
+
return False
|
| 486 |
+
|
| 487 |
+
@staticmethod
|
| 488 |
+
def get_cache(conf: BaseContainer) -> Dict[str, Any]:
|
| 489 |
+
return conf._metadata.resolver_cache
|
| 490 |
+
|
| 491 |
+
@staticmethod
|
| 492 |
+
def set_cache(conf: BaseContainer, cache: Dict[str, Any]) -> None:
|
| 493 |
+
conf._metadata.resolver_cache = copy.deepcopy(cache)
|
| 494 |
+
|
| 495 |
+
@staticmethod
|
| 496 |
+
def clear_cache(conf: BaseContainer) -> None:
|
| 497 |
+
OmegaConf.set_cache(conf, defaultdict(dict, {}))
|
| 498 |
+
|
| 499 |
+
@staticmethod
|
| 500 |
+
def copy_cache(from_config: BaseContainer, to_config: BaseContainer) -> None:
|
| 501 |
+
OmegaConf.set_cache(to_config, OmegaConf.get_cache(from_config))
|
| 502 |
+
|
| 503 |
+
@staticmethod
|
| 504 |
+
def set_readonly(conf: Node, value: Optional[bool]) -> None:
|
| 505 |
+
# noinspection PyProtectedMember
|
| 506 |
+
conf._set_flag("readonly", value)
|
| 507 |
+
|
| 508 |
+
@staticmethod
|
| 509 |
+
def is_readonly(conf: Node) -> Optional[bool]:
|
| 510 |
+
# noinspection PyProtectedMember
|
| 511 |
+
return conf._get_flag("readonly")
|
| 512 |
+
|
| 513 |
+
@staticmethod
|
| 514 |
+
def set_struct(conf: Container, value: Optional[bool]) -> None:
|
| 515 |
+
# noinspection PyProtectedMember
|
| 516 |
+
conf._set_flag("struct", value)
|
| 517 |
+
|
| 518 |
+
@staticmethod
|
| 519 |
+
def is_struct(conf: Container) -> Optional[bool]:
|
| 520 |
+
# noinspection PyProtectedMember
|
| 521 |
+
return conf._get_flag("struct")
|
| 522 |
+
|
| 523 |
+
@staticmethod
|
| 524 |
+
def masked_copy(conf: DictConfig, keys: Union[str, List[str]]) -> DictConfig:
|
| 525 |
+
"""
|
| 526 |
+
Create a masked copy of of this config that contains a subset of the keys
|
| 527 |
+
|
| 528 |
+
:param conf: DictConfig object
|
| 529 |
+
:param keys: keys to preserve in the copy
|
| 530 |
+
:return: The masked ``DictConfig`` object.
|
| 531 |
+
"""
|
| 532 |
+
from .dictconfig import DictConfig
|
| 533 |
+
|
| 534 |
+
if not isinstance(conf, DictConfig):
|
| 535 |
+
raise ValueError("masked_copy is only supported for DictConfig")
|
| 536 |
+
|
| 537 |
+
if isinstance(keys, str):
|
| 538 |
+
keys = [keys]
|
| 539 |
+
content = {key: value for key, value in conf.items_ex(resolve=False, keys=keys)}
|
| 540 |
+
return DictConfig(content=content)
|
| 541 |
+
|
| 542 |
+
@staticmethod
|
| 543 |
+
def to_container(
|
| 544 |
+
cfg: Any,
|
| 545 |
+
*,
|
| 546 |
+
resolve: bool = False,
|
| 547 |
+
throw_on_missing: bool = False,
|
| 548 |
+
enum_to_str: bool = False,
|
| 549 |
+
structured_config_mode: SCMode = SCMode.DICT,
|
| 550 |
+
) -> Union[Dict[DictKeyType, Any], List[Any], None, str, Any]:
|
| 551 |
+
"""
|
| 552 |
+
Resursively converts an OmegaConf config to a primitive container (dict or list).
|
| 553 |
+
|
| 554 |
+
:param cfg: the config to convert
|
| 555 |
+
:param resolve: True to resolve all values
|
| 556 |
+
:param throw_on_missing: When True, raise MissingMandatoryValue if any missing values are present.
|
| 557 |
+
When False (the default), replace missing values with the string "???" in the output container.
|
| 558 |
+
:param enum_to_str: True to convert Enum keys and values to strings
|
| 559 |
+
:param structured_config_mode: Specify how Structured Configs (DictConfigs backed by a dataclass) are handled.
|
| 560 |
+
- By default (``structured_config_mode=SCMode.DICT``) structured configs are converted to plain dicts.
|
| 561 |
+
- If ``structured_config_mode=SCMode.DICT_CONFIG``, structured config nodes will remain as DictConfig.
|
| 562 |
+
- If ``structured_config_mode=SCMode.INSTANTIATE``, this function will instantiate structured configs
|
| 563 |
+
(DictConfigs backed by a dataclass), by creating an instance of the underlying dataclass.
|
| 564 |
+
|
| 565 |
+
See also OmegaConf.to_object.
|
| 566 |
+
:return: A dict or a list representing this config as a primitive container.
|
| 567 |
+
"""
|
| 568 |
+
if not OmegaConf.is_config(cfg):
|
| 569 |
+
raise ValueError(
|
| 570 |
+
f"Input cfg is not an OmegaConf config object ({type_str(type(cfg))})"
|
| 571 |
+
)
|
| 572 |
+
|
| 573 |
+
return BaseContainer._to_content(
|
| 574 |
+
cfg,
|
| 575 |
+
resolve=resolve,
|
| 576 |
+
throw_on_missing=throw_on_missing,
|
| 577 |
+
enum_to_str=enum_to_str,
|
| 578 |
+
structured_config_mode=structured_config_mode,
|
| 579 |
+
)
|
| 580 |
+
|
| 581 |
+
@staticmethod
|
| 582 |
+
def to_object(cfg: Any) -> Union[Dict[DictKeyType, Any], List[Any], None, str, Any]:
|
| 583 |
+
"""
|
| 584 |
+
Resursively converts an OmegaConf config to a primitive container (dict or list).
|
| 585 |
+
Any DictConfig objects backed by dataclasses or attrs classes are instantiated
|
| 586 |
+
as instances of those backing classes.
|
| 587 |
+
|
| 588 |
+
This is an alias for OmegaConf.to_container(..., resolve=True, throw_on_missing=True,
|
| 589 |
+
structured_config_mode=SCMode.INSTANTIATE)
|
| 590 |
+
|
| 591 |
+
:param cfg: the config to convert
|
| 592 |
+
:return: A dict or a list or dataclass representing this config.
|
| 593 |
+
"""
|
| 594 |
+
return OmegaConf.to_container(
|
| 595 |
+
cfg=cfg,
|
| 596 |
+
resolve=True,
|
| 597 |
+
throw_on_missing=True,
|
| 598 |
+
enum_to_str=False,
|
| 599 |
+
structured_config_mode=SCMode.INSTANTIATE,
|
| 600 |
+
)
|
| 601 |
+
|
| 602 |
+
@staticmethod
|
| 603 |
+
def is_missing(cfg: Any, key: DictKeyType) -> bool:
|
| 604 |
+
assert isinstance(cfg, Container)
|
| 605 |
+
try:
|
| 606 |
+
node = cfg._get_child(key)
|
| 607 |
+
if node is None:
|
| 608 |
+
return False
|
| 609 |
+
assert isinstance(node, Node)
|
| 610 |
+
return node._is_missing()
|
| 611 |
+
except (UnsupportedInterpolationType, KeyError, AttributeError):
|
| 612 |
+
return False
|
| 613 |
+
|
| 614 |
+
@staticmethod
|
| 615 |
+
def is_interpolation(node: Any, key: Optional[Union[int, str]] = None) -> bool:
|
| 616 |
+
if key is not None:
|
| 617 |
+
assert isinstance(node, Container)
|
| 618 |
+
target = node._get_child(key)
|
| 619 |
+
else:
|
| 620 |
+
target = node
|
| 621 |
+
if target is not None:
|
| 622 |
+
assert isinstance(target, Node)
|
| 623 |
+
return target._is_interpolation()
|
| 624 |
+
return False
|
| 625 |
+
|
| 626 |
+
@staticmethod
|
| 627 |
+
def is_list(obj: Any) -> bool:
|
| 628 |
+
from . import ListConfig
|
| 629 |
+
|
| 630 |
+
return isinstance(obj, ListConfig)
|
| 631 |
+
|
| 632 |
+
@staticmethod
|
| 633 |
+
def is_dict(obj: Any) -> bool:
|
| 634 |
+
from . import DictConfig
|
| 635 |
+
|
| 636 |
+
return isinstance(obj, DictConfig)
|
| 637 |
+
|
| 638 |
+
@staticmethod
|
| 639 |
+
def is_config(obj: Any) -> bool:
|
| 640 |
+
from . import Container
|
| 641 |
+
|
| 642 |
+
return isinstance(obj, Container)
|
| 643 |
+
|
| 644 |
+
@staticmethod
|
| 645 |
+
def get_type(obj: Any, key: Optional[str] = None) -> Optional[Type[Any]]:
|
| 646 |
+
if key is not None:
|
| 647 |
+
c = obj._get_child(key)
|
| 648 |
+
else:
|
| 649 |
+
c = obj
|
| 650 |
+
return OmegaConf._get_obj_type(c)
|
| 651 |
+
|
| 652 |
+
@staticmethod
|
| 653 |
+
def select(
|
| 654 |
+
cfg: Container,
|
| 655 |
+
key: str,
|
| 656 |
+
*,
|
| 657 |
+
default: Any = _DEFAULT_MARKER_,
|
| 658 |
+
throw_on_resolution_failure: bool = True,
|
| 659 |
+
throw_on_missing: bool = False,
|
| 660 |
+
) -> Any:
|
| 661 |
+
"""
|
| 662 |
+
:param cfg: Config node to select from
|
| 663 |
+
:param key: Key to select
|
| 664 |
+
:param default: Default value to return if key is not found
|
| 665 |
+
:param throw_on_resolution_failure: Raise an exception if an interpolation
|
| 666 |
+
resolution error occurs, otherwise return None
|
| 667 |
+
:param throw_on_missing: Raise an exception if an attempt to select a missing key (with the value '???')
|
| 668 |
+
is made, otherwise return None
|
| 669 |
+
:return: selected value or None if not found.
|
| 670 |
+
"""
|
| 671 |
+
from ._impl import select_value
|
| 672 |
+
|
| 673 |
+
try:
|
| 674 |
+
return select_value(
|
| 675 |
+
cfg=cfg,
|
| 676 |
+
key=key,
|
| 677 |
+
default=default,
|
| 678 |
+
throw_on_resolution_failure=throw_on_resolution_failure,
|
| 679 |
+
throw_on_missing=throw_on_missing,
|
| 680 |
+
)
|
| 681 |
+
except Exception as e:
|
| 682 |
+
format_and_raise(node=cfg, key=key, value=None, cause=e, msg=str(e))
|
| 683 |
+
|
| 684 |
+
@staticmethod
|
| 685 |
+
def update(
|
| 686 |
+
cfg: Container,
|
| 687 |
+
key: str,
|
| 688 |
+
value: Any = None,
|
| 689 |
+
*,
|
| 690 |
+
merge: bool = True,
|
| 691 |
+
force_add: bool = False,
|
| 692 |
+
) -> None:
|
| 693 |
+
"""
|
| 694 |
+
Updates a dot separated key sequence to a value
|
| 695 |
+
|
| 696 |
+
:param cfg: input config to update
|
| 697 |
+
:param key: key to update (can be a dot separated path)
|
| 698 |
+
:param value: value to set, if value if a list or a dict it will be merged or set
|
| 699 |
+
depending on merge_config_values
|
| 700 |
+
:param merge: If value is a dict or a list, True (default) to merge
|
| 701 |
+
into the destination, False to replace the destination.
|
| 702 |
+
:param force_add: insert the entire path regardless of Struct flag or Structured Config nodes.
|
| 703 |
+
"""
|
| 704 |
+
|
| 705 |
+
split = split_key(key)
|
| 706 |
+
root = cfg
|
| 707 |
+
for i in range(len(split) - 1):
|
| 708 |
+
k = split[i]
|
| 709 |
+
# if next_root is a primitive (string, int etc) replace it with an empty map
|
| 710 |
+
next_root, key_ = _select_one(root, k, throw_on_missing=False)
|
| 711 |
+
if not isinstance(next_root, Container):
|
| 712 |
+
if force_add:
|
| 713 |
+
with flag_override(root, "struct", False):
|
| 714 |
+
root[key_] = {}
|
| 715 |
+
else:
|
| 716 |
+
root[key_] = {}
|
| 717 |
+
root = root[key_]
|
| 718 |
+
|
| 719 |
+
last = split[-1]
|
| 720 |
+
|
| 721 |
+
assert isinstance(
|
| 722 |
+
root, Container
|
| 723 |
+
), f"Unexpected type for root: {type(root).__name__}"
|
| 724 |
+
|
| 725 |
+
last_key: Union[str, int] = last
|
| 726 |
+
if isinstance(root, ListConfig):
|
| 727 |
+
last_key = int(last)
|
| 728 |
+
|
| 729 |
+
ctx = flag_override(root, "struct", False) if force_add else nullcontext()
|
| 730 |
+
with ctx:
|
| 731 |
+
if merge and (OmegaConf.is_config(value) or is_primitive_container(value)):
|
| 732 |
+
assert isinstance(root, BaseContainer)
|
| 733 |
+
node = root._get_child(last_key)
|
| 734 |
+
if OmegaConf.is_config(node):
|
| 735 |
+
assert isinstance(node, BaseContainer)
|
| 736 |
+
node.merge_with(value)
|
| 737 |
+
return
|
| 738 |
+
|
| 739 |
+
if OmegaConf.is_dict(root):
|
| 740 |
+
assert isinstance(last_key, str)
|
| 741 |
+
root.__setattr__(last_key, value)
|
| 742 |
+
elif OmegaConf.is_list(root):
|
| 743 |
+
assert isinstance(last_key, int)
|
| 744 |
+
root.__setitem__(last_key, value)
|
| 745 |
+
else:
|
| 746 |
+
assert False
|
| 747 |
+
|
| 748 |
+
@staticmethod
|
| 749 |
+
def to_yaml(cfg: Any, *, resolve: bool = False, sort_keys: bool = False) -> str:
|
| 750 |
+
"""
|
| 751 |
+
returns a yaml dump of this config object.
|
| 752 |
+
|
| 753 |
+
:param cfg: Config object, Structured Config type or instance
|
| 754 |
+
:param resolve: if True, will return a string with the interpolations resolved, otherwise
|
| 755 |
+
interpolations are preserved
|
| 756 |
+
:param sort_keys: If True, will print dict keys in sorted order. default False.
|
| 757 |
+
:return: A string containing the yaml representation.
|
| 758 |
+
"""
|
| 759 |
+
cfg = _ensure_container(cfg)
|
| 760 |
+
container = OmegaConf.to_container(cfg, resolve=resolve, enum_to_str=True)
|
| 761 |
+
return yaml.dump( # type: ignore
|
| 762 |
+
container,
|
| 763 |
+
default_flow_style=False,
|
| 764 |
+
allow_unicode=True,
|
| 765 |
+
sort_keys=sort_keys,
|
| 766 |
+
Dumper=get_omega_conf_dumper(),
|
| 767 |
+
)
|
| 768 |
+
|
| 769 |
+
@staticmethod
|
| 770 |
+
def resolve(cfg: Container) -> None:
|
| 771 |
+
"""
|
| 772 |
+
Resolves all interpolations in the given config object in-place.
|
| 773 |
+
|
| 774 |
+
:param cfg: An OmegaConf container (DictConfig, ListConfig)
|
| 775 |
+
Raises a ValueError if the input object is not an OmegaConf container.
|
| 776 |
+
"""
|
| 777 |
+
import omegaconf._impl
|
| 778 |
+
|
| 779 |
+
if not OmegaConf.is_config(cfg):
|
| 780 |
+
# Since this function is mutating the input object in-place, it doesn't make sense to
|
| 781 |
+
# auto-convert the input object to an OmegaConf container
|
| 782 |
+
raise ValueError(
|
| 783 |
+
f"Invalid config type ({type(cfg).__name__}), expected an OmegaConf Container"
|
| 784 |
+
)
|
| 785 |
+
omegaconf._impl._resolve(cfg)
|
| 786 |
+
|
| 787 |
+
@staticmethod
|
| 788 |
+
def missing_keys(cfg: Any) -> Set[str]:
|
| 789 |
+
"""
|
| 790 |
+
Returns a set of missing keys in a dotlist style.
|
| 791 |
+
|
| 792 |
+
:param cfg: An ``OmegaConf.Container``,
|
| 793 |
+
or a convertible object via ``OmegaConf.create`` (dict, list, ...).
|
| 794 |
+
:return: set of strings of the missing keys.
|
| 795 |
+
:raises ValueError: On input not representing a config.
|
| 796 |
+
"""
|
| 797 |
+
cfg = _ensure_container(cfg)
|
| 798 |
+
missings: Set[str] = set()
|
| 799 |
+
|
| 800 |
+
def gather(_cfg: Container) -> None:
|
| 801 |
+
itr: Iterable[Any]
|
| 802 |
+
if isinstance(_cfg, ListConfig):
|
| 803 |
+
itr = range(len(_cfg))
|
| 804 |
+
else:
|
| 805 |
+
itr = _cfg
|
| 806 |
+
|
| 807 |
+
for key in itr:
|
| 808 |
+
if OmegaConf.is_missing(_cfg, key):
|
| 809 |
+
missings.add(_cfg._get_full_key(key))
|
| 810 |
+
elif OmegaConf.is_config(_cfg[key]):
|
| 811 |
+
gather(_cfg[key])
|
| 812 |
+
|
| 813 |
+
gather(cfg)
|
| 814 |
+
return missings
|
| 815 |
+
|
| 816 |
+
# === private === #
|
| 817 |
+
|
| 818 |
+
@staticmethod
|
| 819 |
+
def _create_impl( # noqa F811
|
| 820 |
+
obj: Any = _DEFAULT_MARKER_,
|
| 821 |
+
parent: Optional[BaseContainer] = None,
|
| 822 |
+
flags: Optional[Dict[str, bool]] = None,
|
| 823 |
+
) -> Union[DictConfig, ListConfig]:
|
| 824 |
+
try:
|
| 825 |
+
from ._utils import get_yaml_loader
|
| 826 |
+
from .dictconfig import DictConfig
|
| 827 |
+
from .listconfig import ListConfig
|
| 828 |
+
|
| 829 |
+
if obj is _DEFAULT_MARKER_:
|
| 830 |
+
obj = {}
|
| 831 |
+
if isinstance(obj, str):
|
| 832 |
+
obj = yaml.load(obj, Loader=get_yaml_loader())
|
| 833 |
+
if obj is None:
|
| 834 |
+
return OmegaConf.create({}, parent=parent, flags=flags)
|
| 835 |
+
elif isinstance(obj, str):
|
| 836 |
+
return OmegaConf.create({obj: None}, parent=parent, flags=flags)
|
| 837 |
+
else:
|
| 838 |
+
assert isinstance(obj, (list, dict))
|
| 839 |
+
return OmegaConf.create(obj, parent=parent, flags=flags)
|
| 840 |
+
|
| 841 |
+
else:
|
| 842 |
+
if (
|
| 843 |
+
is_primitive_dict(obj)
|
| 844 |
+
or OmegaConf.is_dict(obj)
|
| 845 |
+
or is_structured_config(obj)
|
| 846 |
+
or obj is None
|
| 847 |
+
):
|
| 848 |
+
if isinstance(obj, DictConfig):
|
| 849 |
+
return DictConfig(
|
| 850 |
+
content=obj,
|
| 851 |
+
parent=parent,
|
| 852 |
+
ref_type=obj._metadata.ref_type,
|
| 853 |
+
is_optional=obj._metadata.optional,
|
| 854 |
+
key_type=obj._metadata.key_type,
|
| 855 |
+
element_type=obj._metadata.element_type,
|
| 856 |
+
flags=flags,
|
| 857 |
+
)
|
| 858 |
+
else:
|
| 859 |
+
obj_type = OmegaConf.get_type(obj)
|
| 860 |
+
key_type, element_type = get_dict_key_value_types(obj_type)
|
| 861 |
+
return DictConfig(
|
| 862 |
+
content=obj,
|
| 863 |
+
parent=parent,
|
| 864 |
+
key_type=key_type,
|
| 865 |
+
element_type=element_type,
|
| 866 |
+
flags=flags,
|
| 867 |
+
)
|
| 868 |
+
elif is_primitive_list(obj) or OmegaConf.is_list(obj):
|
| 869 |
+
if isinstance(obj, ListConfig):
|
| 870 |
+
return ListConfig(
|
| 871 |
+
content=obj,
|
| 872 |
+
parent=parent,
|
| 873 |
+
element_type=obj._metadata.element_type,
|
| 874 |
+
ref_type=obj._metadata.ref_type,
|
| 875 |
+
is_optional=obj._metadata.optional,
|
| 876 |
+
flags=flags,
|
| 877 |
+
)
|
| 878 |
+
else:
|
| 879 |
+
obj_type = OmegaConf.get_type(obj)
|
| 880 |
+
element_type = get_list_element_type(obj_type)
|
| 881 |
+
return ListConfig(
|
| 882 |
+
content=obj,
|
| 883 |
+
parent=parent,
|
| 884 |
+
element_type=element_type,
|
| 885 |
+
ref_type=Any,
|
| 886 |
+
is_optional=True,
|
| 887 |
+
flags=flags,
|
| 888 |
+
)
|
| 889 |
+
else:
|
| 890 |
+
if isinstance(obj, type):
|
| 891 |
+
raise ValidationError(
|
| 892 |
+
f"Input class '{obj.__name__}' is not a structured config. "
|
| 893 |
+
"did you forget to decorate it as a dataclass?"
|
| 894 |
+
)
|
| 895 |
+
else:
|
| 896 |
+
raise ValidationError(
|
| 897 |
+
f"Object of unsupported type: '{type(obj).__name__}'"
|
| 898 |
+
)
|
| 899 |
+
except OmegaConfBaseException as e:
|
| 900 |
+
format_and_raise(node=None, key=None, value=None, msg=str(e), cause=e)
|
| 901 |
+
assert False
|
| 902 |
+
|
| 903 |
+
@staticmethod
|
| 904 |
+
def _get_obj_type(c: Any) -> Optional[Type[Any]]:
|
| 905 |
+
if is_structured_config(c):
|
| 906 |
+
return get_type_of(c)
|
| 907 |
+
elif c is None:
|
| 908 |
+
return None
|
| 909 |
+
elif isinstance(c, DictConfig):
|
| 910 |
+
if c._is_none():
|
| 911 |
+
return None
|
| 912 |
+
elif c._is_missing():
|
| 913 |
+
return None
|
| 914 |
+
else:
|
| 915 |
+
if is_structured_config(c._metadata.object_type):
|
| 916 |
+
return c._metadata.object_type
|
| 917 |
+
else:
|
| 918 |
+
return dict
|
| 919 |
+
elif isinstance(c, ListConfig):
|
| 920 |
+
return list
|
| 921 |
+
elif isinstance(c, ValueNode):
|
| 922 |
+
return type(c._value())
|
| 923 |
+
elif isinstance(c, UnionNode):
|
| 924 |
+
return type(_get_value(c))
|
| 925 |
+
elif isinstance(c, dict):
|
| 926 |
+
return dict
|
| 927 |
+
elif isinstance(c, (list, tuple)):
|
| 928 |
+
return list
|
| 929 |
+
else:
|
| 930 |
+
return get_type_of(c)
|
| 931 |
+
|
| 932 |
+
@staticmethod
|
| 933 |
+
def _get_resolver(
|
| 934 |
+
name: str,
|
| 935 |
+
) -> Optional[
|
| 936 |
+
Callable[
|
| 937 |
+
[Container, Container, Node, Tuple[Any, ...], Tuple[str, ...]],
|
| 938 |
+
Any,
|
| 939 |
+
]
|
| 940 |
+
]:
|
| 941 |
+
# noinspection PyProtectedMember
|
| 942 |
+
return (
|
| 943 |
+
BaseContainer._resolvers[name] if name in BaseContainer._resolvers else None
|
| 944 |
+
)
|
| 945 |
+
|
| 946 |
+
|
| 947 |
+
# register all default resolvers
|
| 948 |
+
register_default_resolvers()
|
| 949 |
+
|
| 950 |
+
|
| 951 |
+
@contextmanager
|
| 952 |
+
def flag_override(
|
| 953 |
+
config: Node,
|
| 954 |
+
names: Union[List[str], str],
|
| 955 |
+
values: Union[List[Optional[bool]], Optional[bool]],
|
| 956 |
+
) -> Generator[Node, None, None]:
|
| 957 |
+
if isinstance(names, str):
|
| 958 |
+
names = [names]
|
| 959 |
+
if values is None or isinstance(values, bool):
|
| 960 |
+
values = [values]
|
| 961 |
+
|
| 962 |
+
prev_states = [config._get_node_flag(name) for name in names]
|
| 963 |
+
|
| 964 |
+
try:
|
| 965 |
+
config._set_flag(names, values)
|
| 966 |
+
yield config
|
| 967 |
+
finally:
|
| 968 |
+
config._set_flag(names, prev_states)
|
| 969 |
+
|
| 970 |
+
|
| 971 |
+
@contextmanager
|
| 972 |
+
def read_write(config: Node) -> Generator[Node, None, None]:
|
| 973 |
+
prev_state = config._get_node_flag("readonly")
|
| 974 |
+
try:
|
| 975 |
+
OmegaConf.set_readonly(config, False)
|
| 976 |
+
yield config
|
| 977 |
+
finally:
|
| 978 |
+
OmegaConf.set_readonly(config, prev_state)
|
| 979 |
+
|
| 980 |
+
|
| 981 |
+
@contextmanager
|
| 982 |
+
def open_dict(config: Container) -> Generator[Container, None, None]:
|
| 983 |
+
prev_state = config._get_node_flag("struct")
|
| 984 |
+
try:
|
| 985 |
+
OmegaConf.set_struct(config, False)
|
| 986 |
+
yield config
|
| 987 |
+
finally:
|
| 988 |
+
OmegaConf.set_struct(config, prev_state)
|
| 989 |
+
|
| 990 |
+
|
| 991 |
+
# === private === #
|
| 992 |
+
|
| 993 |
+
|
| 994 |
+
def _node_wrap(
|
| 995 |
+
parent: Optional[Box],
|
| 996 |
+
is_optional: bool,
|
| 997 |
+
value: Any,
|
| 998 |
+
key: Any,
|
| 999 |
+
ref_type: Any = Any,
|
| 1000 |
+
) -> Node:
|
| 1001 |
+
node: Node
|
| 1002 |
+
if is_dict_annotation(ref_type) or (is_primitive_dict(value) and ref_type is Any):
|
| 1003 |
+
key_type, element_type = get_dict_key_value_types(ref_type)
|
| 1004 |
+
node = DictConfig(
|
| 1005 |
+
content=value,
|
| 1006 |
+
key=key,
|
| 1007 |
+
parent=parent,
|
| 1008 |
+
ref_type=ref_type,
|
| 1009 |
+
is_optional=is_optional,
|
| 1010 |
+
key_type=key_type,
|
| 1011 |
+
element_type=element_type,
|
| 1012 |
+
)
|
| 1013 |
+
elif (is_list_annotation(ref_type) or is_tuple_annotation(ref_type)) or (
|
| 1014 |
+
type(value) in (list, tuple) and ref_type is Any
|
| 1015 |
+
):
|
| 1016 |
+
element_type = get_list_element_type(ref_type)
|
| 1017 |
+
node = ListConfig(
|
| 1018 |
+
content=value,
|
| 1019 |
+
key=key,
|
| 1020 |
+
parent=parent,
|
| 1021 |
+
is_optional=is_optional,
|
| 1022 |
+
element_type=element_type,
|
| 1023 |
+
ref_type=ref_type,
|
| 1024 |
+
)
|
| 1025 |
+
elif is_structured_config(ref_type) or is_structured_config(value):
|
| 1026 |
+
key_type, element_type = get_dict_key_value_types(value)
|
| 1027 |
+
node = DictConfig(
|
| 1028 |
+
ref_type=ref_type,
|
| 1029 |
+
is_optional=is_optional,
|
| 1030 |
+
content=value,
|
| 1031 |
+
key=key,
|
| 1032 |
+
parent=parent,
|
| 1033 |
+
key_type=key_type,
|
| 1034 |
+
element_type=element_type,
|
| 1035 |
+
)
|
| 1036 |
+
elif is_union_annotation(ref_type):
|
| 1037 |
+
node = UnionNode(
|
| 1038 |
+
content=value,
|
| 1039 |
+
ref_type=ref_type,
|
| 1040 |
+
is_optional=is_optional,
|
| 1041 |
+
key=key,
|
| 1042 |
+
parent=parent,
|
| 1043 |
+
)
|
| 1044 |
+
elif ref_type == Any or ref_type is None:
|
| 1045 |
+
node = AnyNode(value=value, key=key, parent=parent)
|
| 1046 |
+
elif isinstance(ref_type, type) and issubclass(ref_type, Enum):
|
| 1047 |
+
node = EnumNode(
|
| 1048 |
+
enum_type=ref_type,
|
| 1049 |
+
value=value,
|
| 1050 |
+
key=key,
|
| 1051 |
+
parent=parent,
|
| 1052 |
+
is_optional=is_optional,
|
| 1053 |
+
)
|
| 1054 |
+
elif ref_type == int:
|
| 1055 |
+
node = IntegerNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1056 |
+
elif ref_type == float:
|
| 1057 |
+
node = FloatNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1058 |
+
elif ref_type == bool:
|
| 1059 |
+
node = BooleanNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1060 |
+
elif ref_type == str:
|
| 1061 |
+
node = StringNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1062 |
+
elif ref_type == bytes:
|
| 1063 |
+
node = BytesNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1064 |
+
elif ref_type == pathlib.Path:
|
| 1065 |
+
node = PathNode(value=value, key=key, parent=parent, is_optional=is_optional)
|
| 1066 |
+
else:
|
| 1067 |
+
if parent is not None and parent._get_flag("allow_objects") is True:
|
| 1068 |
+
if type(value) in (list, tuple):
|
| 1069 |
+
node = ListConfig(
|
| 1070 |
+
content=value,
|
| 1071 |
+
key=key,
|
| 1072 |
+
parent=parent,
|
| 1073 |
+
ref_type=ref_type,
|
| 1074 |
+
is_optional=is_optional,
|
| 1075 |
+
)
|
| 1076 |
+
elif is_primitive_dict(value):
|
| 1077 |
+
node = DictConfig(
|
| 1078 |
+
content=value,
|
| 1079 |
+
key=key,
|
| 1080 |
+
parent=parent,
|
| 1081 |
+
ref_type=ref_type,
|
| 1082 |
+
is_optional=is_optional,
|
| 1083 |
+
)
|
| 1084 |
+
else:
|
| 1085 |
+
node = AnyNode(value=value, key=key, parent=parent)
|
| 1086 |
+
else:
|
| 1087 |
+
raise ValidationError(f"Unexpected type annotation: {type_str(ref_type)}")
|
| 1088 |
+
return node
|
| 1089 |
+
|
| 1090 |
+
|
| 1091 |
+
def _maybe_wrap(
|
| 1092 |
+
ref_type: Any,
|
| 1093 |
+
key: Any,
|
| 1094 |
+
value: Any,
|
| 1095 |
+
is_optional: bool,
|
| 1096 |
+
parent: Optional[BaseContainer],
|
| 1097 |
+
) -> Node:
|
| 1098 |
+
# if already a node, update key and parent and return as is.
|
| 1099 |
+
# NOTE: that this mutate the input node!
|
| 1100 |
+
if isinstance(value, Node):
|
| 1101 |
+
value._set_key(key)
|
| 1102 |
+
value._set_parent(parent)
|
| 1103 |
+
return value
|
| 1104 |
+
else:
|
| 1105 |
+
return _node_wrap(
|
| 1106 |
+
ref_type=ref_type,
|
| 1107 |
+
parent=parent,
|
| 1108 |
+
is_optional=is_optional,
|
| 1109 |
+
value=value,
|
| 1110 |
+
key=key,
|
| 1111 |
+
)
|
| 1112 |
+
|
| 1113 |
+
|
| 1114 |
+
def _select_one(
|
| 1115 |
+
c: Container, key: str, throw_on_missing: bool, throw_on_type_error: bool = True
|
| 1116 |
+
) -> Tuple[Optional[Node], Union[str, int]]:
|
| 1117 |
+
from .dictconfig import DictConfig
|
| 1118 |
+
from .listconfig import ListConfig
|
| 1119 |
+
|
| 1120 |
+
ret_key: Union[str, int] = key
|
| 1121 |
+
assert isinstance(c, Container), f"Unexpected type: {c}"
|
| 1122 |
+
if c._is_none():
|
| 1123 |
+
return None, ret_key
|
| 1124 |
+
|
| 1125 |
+
if isinstance(c, DictConfig):
|
| 1126 |
+
assert isinstance(ret_key, str)
|
| 1127 |
+
val = c._get_child(ret_key, validate_access=False)
|
| 1128 |
+
elif isinstance(c, ListConfig):
|
| 1129 |
+
assert isinstance(ret_key, str)
|
| 1130 |
+
if not is_int(ret_key):
|
| 1131 |
+
if throw_on_type_error:
|
| 1132 |
+
raise TypeError(
|
| 1133 |
+
f"Index '{ret_key}' ({type(ret_key).__name__}) is not an int"
|
| 1134 |
+
)
|
| 1135 |
+
else:
|
| 1136 |
+
val = None
|
| 1137 |
+
else:
|
| 1138 |
+
ret_key = int(ret_key)
|
| 1139 |
+
if ret_key < 0 or ret_key + 1 > len(c):
|
| 1140 |
+
val = None
|
| 1141 |
+
else:
|
| 1142 |
+
val = c._get_child(ret_key)
|
| 1143 |
+
else:
|
| 1144 |
+
assert False
|
| 1145 |
+
|
| 1146 |
+
if val is not None:
|
| 1147 |
+
assert isinstance(val, Node)
|
| 1148 |
+
if val._is_missing():
|
| 1149 |
+
if throw_on_missing:
|
| 1150 |
+
raise MissingMandatoryValue(
|
| 1151 |
+
f"Missing mandatory value: {c._get_full_key(ret_key)}"
|
| 1152 |
+
)
|
| 1153 |
+
else:
|
| 1154 |
+
return val, ret_key
|
| 1155 |
+
|
| 1156 |
+
assert val is None or isinstance(val, Node)
|
| 1157 |
+
return val, ret_key
|
lib/python3.12/site-packages/omegaconf/py.typed
ADDED
|
File without changes
|
lib/python3.12/site-packages/omegaconf/version.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys # pragma: no cover
|
| 2 |
+
|
| 3 |
+
__version__ = "2.3.0"
|
| 4 |
+
|
| 5 |
+
msg = """OmegaConf 2.0 and above is compatible with Python 3.6 and newer.
|
| 6 |
+
You have the following options:
|
| 7 |
+
1. Upgrade to Python 3.6 or newer.
|
| 8 |
+
This is highly recommended. new features will not be added to OmegaConf 1.4.
|
| 9 |
+
2. Continue using OmegaConf 1.4:
|
| 10 |
+
You can pip install 'OmegaConf<1.5' to do that.
|
| 11 |
+
"""
|
| 12 |
+
if sys.version_info < (3, 6):
|
| 13 |
+
raise ImportError(msg) # pragma: no cover
|
lib/python3.12/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (5.29 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc
ADDED
|
Binary file (421 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc
ADDED
|
Binary file (424 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc
ADDED
|
Binary file (664 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/batch.cpython-312.pyc
ADDED
|
Binary file (2.14 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc
ADDED
|
Binary file (721 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc
ADDED
|
Binary file (610 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc
ADDED
|
Binary file (564 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc
ADDED
|
Binary file (312 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/completion.cpython-312.pyc
ADDED
|
Binary file (1.02 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc
ADDED
|
Binary file (1.27 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc
ADDED
|
Binary file (2.26 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc
ADDED
|
Binary file (1.55 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc
ADDED
|
Binary file (1.02 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc
ADDED
|
Binary file (678 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc
ADDED
|
Binary file (1.05 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc
ADDED
|
Binary file (448 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc
ADDED
|
Binary file (4.17 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc
ADDED
|
Binary file (1.8 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc
ADDED
|
Binary file (808 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc
ADDED
|
Binary file (557 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_label_model_grader.cpython-312.pyc
ADDED
|
Binary file (2.17 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc
ADDED
|
Binary file (746 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc
ADDED
|
Binary file (1.8 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc
ADDED
|
Binary file (984 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_string_check_grader.cpython-312.pyc
ADDED
|
Binary file (748 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_string_check_grader_param.cpython-312.pyc
ADDED
|
Binary file (848 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_text_similarity_grader.cpython-312.pyc
ADDED
|
Binary file (963 Bytes). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_text_similarity_grader_param.cpython-312.pyc
ADDED
|
Binary file (1.02 kB). View file
|
|
|
lib/python3.12/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc
ADDED
|
Binary file (729 Bytes). View file
|
|
|