omegaconf 2.4.0.dev14__tar.gz → 2.4.0.dev15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {omegaconf-2.4.0.dev14/omegaconf.egg-info → omegaconf-2.4.0.dev15}/PKG-INFO +1 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/_impl.py +7 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/basecontainer.py +5 -4
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/dictconfig.py +30 -3
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar_visitor.py +4 -2
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/listconfig.py +1 -3
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/omegaconf.py +15 -3
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/version.py +1 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15/omegaconf.egg-info}/PKG-INFO +1 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/pyproject.toml +1 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/test_interpolation.py +54 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_basic_ops_dict.py +50 -6
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_basic_ops_list.py +7 -6
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_merge.py +57 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_omegaconf.py +15 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_select.py +18 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_update.py +17 -1
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/LICENSE +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/MANIFEST.in +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/README.md +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/build_helpers/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/build_helpers/bin/antlr-4.11.1-complete.jar +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/build_helpers/build_helpers.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/build_helpers/get_vendored.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/build_helpers/test_helpers.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/_utils.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/_yaml.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/base.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/errors.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/OmegaConfGrammarLexer.g4 +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/OmegaConfGrammarParser.g4 +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarLexer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarParser.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarParserListener.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarParserVisitor.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar_parser.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/nodes.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/py.typed +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/resolvers/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/resolvers/oc/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/resolvers/oc/dict.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/tupleconfig.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/typing.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/BufferedTokenStream.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/CommonTokenFactory.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/CommonTokenStream.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/FileStream.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/InputStream.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/IntervalSet.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/LL1Analyzer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/Lexer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/ListTokenSource.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/Parser.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/ParserInterpreter.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/ParserRuleContext.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/PredictionContext.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/Recognizer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/RuleContext.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/StdinStream.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/Token.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/TokenStreamRewriter.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/Utils.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/_pygrun.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATN.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNConfig.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNConfigSet.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNDeserializationOptions.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNDeserializer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNSimulator.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNState.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNType.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/LexerATNSimulator.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/LexerAction.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/LexerActionExecutor.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ParserATNSimulator.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/PredictionMode.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/SemanticContext.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/Transition.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/dfa/DFA.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/dfa/DFASerializer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/dfa/DFAState.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/dfa/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/DiagnosticErrorListener.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/ErrorListener.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/ErrorStrategy.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/Errors.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/Chunk.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/ParseTreeMatch.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/ParseTreePattern.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/ParseTreePatternMatcher.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/RuleTagToken.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/TokenTagToken.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/Tree.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/Trees.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/xpath/XPath.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/xpath/XPathLexer.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/xpath/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf.egg-info/SOURCES.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf.egg-info/dependency_links.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf.egg-info/requires.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf.egg-info/top_level.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/requirements/base.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/requirements/dev.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/requirements/docs.txt +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/setup.cfg +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/setup.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/conftest.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/data/2.0.6.pickle +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/data/2.1.0.rc1.pickle +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/data/load.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/data/save.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/dataclass_postponed_annotations.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/test_dataclass_example.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/test_postponed_annotations.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_create.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_decode.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_deprecated.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_dict.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_env.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/test_oc_select.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/test_custom_resolvers.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/test_resolver_annotation_validation.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/data/__init__.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/data/attr_classes.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/data/dataclasses.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/data/dataclasses_pre_311.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/test_structured_basic.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/test_structured_config.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_base_config.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_basic_ops_tuple.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_compare_dictconfig_vs_dict.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_config_eq.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_container_unions.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_create.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_errors.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_get_full_key.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_grammar.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_matrix.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_nested_containers.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_nodes.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_readonly.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_serialization.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_struct.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_structured_config_unions.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_to_container.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_to_yaml.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_tuple_integration.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_tuple_merge.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_tuple_structured.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_unions.py +0 -0
- {omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/test_utils.py +0 -0
|
@@ -22,7 +22,13 @@ def _resolve_container_value(cfg: Container, key: Any) -> None:
|
|
|
22
22
|
node = cfg._get_child(key)
|
|
23
23
|
assert isinstance(node, Node)
|
|
24
24
|
if node._is_interpolation():
|
|
25
|
-
|
|
25
|
+
try:
|
|
26
|
+
resolved = node._dereference_node()
|
|
27
|
+
except Exception as e:
|
|
28
|
+
# Attach the same key/object_type context that direct node access
|
|
29
|
+
# reports, so errors surfaced through OmegaConf.resolve() stay
|
|
30
|
+
# diagnosable.
|
|
31
|
+
cfg._format_and_raise(key=key, value=None, cause=e)
|
|
26
32
|
if isinstance(resolved, Container):
|
|
27
33
|
_resolve(resolved)
|
|
28
34
|
if isinstance(resolved, InterpolationResultNode):
|
|
@@ -417,16 +417,17 @@ class BaseContainer(Container, ABC):
|
|
|
417
417
|
ref_type=src_ref_type, object_type=src_type
|
|
418
418
|
)
|
|
419
419
|
|
|
420
|
-
if dest._is_interpolation() and src_was_missing_structured:
|
|
421
|
-
# Keep unresolved structured interpolations
|
|
422
|
-
# was originally MISSING; the synthesized prototype
|
|
423
|
-
# preserve type information during merge.
|
|
420
|
+
if (dest._is_interpolation() or dest._is_none()) and src_was_missing_structured:
|
|
421
|
+
# Keep unresolved structured interpolations and null values intact
|
|
422
|
+
# when the source was originally MISSING; the synthesized prototype
|
|
423
|
+
# only exists to preserve type information during merge.
|
|
424
424
|
_update_types(node=dest, ref_type=src_ref_type, object_type=src_type)
|
|
425
425
|
return
|
|
426
426
|
|
|
427
427
|
if (
|
|
428
428
|
(dest._is_interpolation() and not src_was_missing_structured)
|
|
429
429
|
or dest._is_missing()
|
|
430
|
+
or dest._is_none()
|
|
430
431
|
) and not src._is_missing():
|
|
431
432
|
expand(dest)
|
|
432
433
|
|
|
@@ -34,6 +34,7 @@ from ._utils import (
|
|
|
34
34
|
get_value_kind,
|
|
35
35
|
is_container_annotation,
|
|
36
36
|
is_dict,
|
|
37
|
+
is_int,
|
|
37
38
|
is_primitive_dict,
|
|
38
39
|
is_structured_config,
|
|
39
40
|
is_structured_config_frozen,
|
|
@@ -69,6 +70,7 @@ def _make_key_suggestion(key: Any, available: Iterable) -> str:
|
|
|
69
70
|
class DictConfig(BaseContainer, MutableMapping[Any, Any]):
|
|
70
71
|
_metadata: ContainerMetadata
|
|
71
72
|
_content: Union[Dict[DictKeyType, Node], None, str]
|
|
73
|
+
__hash__ = None # type: ignore[assignment]
|
|
72
74
|
|
|
73
75
|
def __init__(
|
|
74
76
|
self,
|
|
@@ -227,6 +229,8 @@ class DictConfig(BaseContainer, MutableMapping[Any, Any]):
|
|
|
227
229
|
self._validate_non_optional(None, src)
|
|
228
230
|
|
|
229
231
|
dest_obj_type = OmegaConf.get_type(dest)
|
|
232
|
+
if dest._is_none() and is_structured_config(dest._metadata.ref_type):
|
|
233
|
+
dest_obj_type = dest._metadata.ref_type
|
|
230
234
|
src_obj_type = OmegaConf.get_type(src)
|
|
231
235
|
|
|
232
236
|
if dest._is_missing() and src._metadata.object_type not in (dict, None):
|
|
@@ -334,8 +338,34 @@ class DictConfig(BaseContainer, MutableMapping[Any, Any]):
|
|
|
334
338
|
|
|
335
339
|
def __set_impl(self, key: DictKeyType, value: Any) -> None:
|
|
336
340
|
key = self._validate_and_normalize_key(key)
|
|
341
|
+
self._validate_non_ambiguous_key(key)
|
|
337
342
|
self._set_item_impl(key, value)
|
|
338
343
|
|
|
344
|
+
def _validate_non_ambiguous_key(self, key: DictKeyType) -> None:
|
|
345
|
+
content = self.__dict__["_content"]
|
|
346
|
+
if self._metadata.key_type is not Any or not isinstance(content, dict):
|
|
347
|
+
return
|
|
348
|
+
|
|
349
|
+
conflicting_key: Optional[DictKeyType] = None
|
|
350
|
+
if isinstance(key, str) and is_int(key):
|
|
351
|
+
numeric_key = int(key)
|
|
352
|
+
node = content.get(numeric_key)
|
|
353
|
+
if (
|
|
354
|
+
str(numeric_key) == key
|
|
355
|
+
and isinstance(node, Node)
|
|
356
|
+
and type(node._key()) is int
|
|
357
|
+
):
|
|
358
|
+
conflicting_key = numeric_key
|
|
359
|
+
elif type(key) is int and str(key) in content:
|
|
360
|
+
node = content.get(key)
|
|
361
|
+
if not isinstance(node, Node) or type(node._key()) is int:
|
|
362
|
+
conflicting_key = str(key)
|
|
363
|
+
|
|
364
|
+
if conflicting_key is not None:
|
|
365
|
+
raise KeyValidationError(
|
|
366
|
+
f"Conflicting integer and string keys: {conflicting_key!r} and {key!r}"
|
|
367
|
+
)
|
|
368
|
+
|
|
339
369
|
# hide content while inspecting in debugger
|
|
340
370
|
def __dir__(self) -> Iterable[str]:
|
|
341
371
|
if self._is_missing() or self._is_none():
|
|
@@ -634,9 +664,6 @@ class DictConfig(BaseContainer, MutableMapping[Any, Any]):
|
|
|
634
664
|
return not x
|
|
635
665
|
return NotImplemented
|
|
636
666
|
|
|
637
|
-
def __hash__(self) -> int:
|
|
638
|
-
return hash(str(self))
|
|
639
|
-
|
|
640
667
|
def _promote(self, type_or_prototype: Optional[Type[Any]]) -> None:
|
|
641
668
|
"""
|
|
642
669
|
Retypes a node.
|
|
@@ -86,10 +86,12 @@ class GrammarVisitor(OmegaConfGrammarParserVisitor):
|
|
|
86
86
|
if isinstance(child, OmegaConfGrammarParser.InterpolationContext):
|
|
87
87
|
child_text = child.getText()
|
|
88
88
|
res = _get_value(self.visitInterpolation(child))
|
|
89
|
-
if
|
|
89
|
+
if type(res) is int:
|
|
90
|
+
return str(res)
|
|
91
|
+
elif not isinstance(res, str):
|
|
90
92
|
raise InterpolationResolutionError(
|
|
91
93
|
f"The following interpolation is used to denote a config key and "
|
|
92
|
-
f"thus should return a string, but instead returned `{res}` of "
|
|
94
|
+
f"thus should return a string or integer, but instead returned `{res}` of "
|
|
93
95
|
f"type `{type(res)}`: {child_text}"
|
|
94
96
|
)
|
|
95
97
|
return res
|
|
@@ -47,6 +47,7 @@ from .errors import (
|
|
|
47
47
|
|
|
48
48
|
class ListConfig(BaseContainer, MutableSequence[Any]):
|
|
49
49
|
_content: Union[List[Node], None, str]
|
|
50
|
+
__hash__ = None # type: ignore[assignment]
|
|
50
51
|
|
|
51
52
|
def __init__(
|
|
52
53
|
self,
|
|
@@ -523,9 +524,6 @@ class ListConfig(BaseContainer, MutableSequence[Any]):
|
|
|
523
524
|
return not x
|
|
524
525
|
return NotImplemented
|
|
525
526
|
|
|
526
|
-
def __hash__(self) -> int:
|
|
527
|
-
return hash(str(self))
|
|
528
|
-
|
|
529
527
|
def __iter__(self) -> Iterator[Any]:
|
|
530
528
|
return self._iter_ex(resolve=True)
|
|
531
529
|
|
|
@@ -1423,7 +1423,9 @@ class OmegaConf:
|
|
|
1423
1423
|
)
|
|
1424
1424
|
|
|
1425
1425
|
last_key: Union[str, int] = last
|
|
1426
|
-
if OmegaConf.
|
|
1426
|
+
if OmegaConf.is_dict(root):
|
|
1427
|
+
_, last_key = _select_one(root, last, throw_on_missing=False)
|
|
1428
|
+
elif OmegaConf.is_sequence(root):
|
|
1427
1429
|
last_key = int(last)
|
|
1428
1430
|
|
|
1429
1431
|
ctx = flag_override(root, "struct", False) if force_add else nullcontext()
|
|
@@ -1438,8 +1440,10 @@ class OmegaConf:
|
|
|
1438
1440
|
return
|
|
1439
1441
|
|
|
1440
1442
|
if OmegaConf.is_dict(root):
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
+
if isinstance(last_key, int):
|
|
1444
|
+
root.__setitem__(last_key, value)
|
|
1445
|
+
else:
|
|
1446
|
+
root.__setattr__(last_key, value)
|
|
1443
1447
|
elif OmegaConf.is_sequence(root):
|
|
1444
1448
|
assert isinstance(last_key, int)
|
|
1445
1449
|
root.__setitem__(last_key, value)
|
|
@@ -1973,6 +1977,14 @@ def _select_one(
|
|
|
1973
1977
|
if isinstance(c, DictConfig):
|
|
1974
1978
|
assert isinstance(ret_key, str)
|
|
1975
1979
|
val = c._get_child(ret_key, validate_access=False)
|
|
1980
|
+
if val is None and is_int(ret_key):
|
|
1981
|
+
numeric_key = int(ret_key)
|
|
1982
|
+
raw_node = c._get_node(numeric_key, validate_access=False)
|
|
1983
|
+
if isinstance(raw_node, Node) and type(raw_node._key()) is int:
|
|
1984
|
+
val = c._get_child(numeric_key, validate_access=False)
|
|
1985
|
+
ret_key = numeric_key
|
|
1986
|
+
else:
|
|
1987
|
+
val = None
|
|
1976
1988
|
elif isinstance(c, (ListConfig, TupleConfig)):
|
|
1977
1989
|
assert isinstance(ret_key, str)
|
|
1978
1990
|
if not is_int(ret_key):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import sys # pragma: no cover
|
|
2
2
|
|
|
3
3
|
# Managed by bump-my-version; see pyproject.toml for bump commands.
|
|
4
|
-
__version__ = "2.4.0.
|
|
4
|
+
__version__ = "2.4.0.dev15"
|
|
5
5
|
|
|
6
6
|
msg = """OmegaConf 2.4 and above is compatible with Python 3.10 and newer.
|
|
7
7
|
You have the following options:
|
|
@@ -29,7 +29,7 @@ norecursedirs = ["subprojects", ".git", ".sl", ".venv"]
|
|
|
29
29
|
# Version source of truth. Use bump-my-version so configured files stay in sync.
|
|
30
30
|
# `bump-my-version bump pre_n` updates 2.4.0.dev13 to 2.4.0.dev14.
|
|
31
31
|
# `bump-my-version bump --new-version 2.4.0` sets the final release version.
|
|
32
|
-
current_version = "2.4.0.
|
|
32
|
+
current_version = "2.4.0.dev15"
|
|
33
33
|
parse = '''(?x)
|
|
34
34
|
(?P<major>\d+)
|
|
35
35
|
\.(?P<minor>\d+)
|
|
@@ -2,7 +2,7 @@ import copy
|
|
|
2
2
|
import re
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from textwrap import dedent
|
|
5
|
-
from typing import Any, Tuple
|
|
5
|
+
from typing import Any, Tuple, Union
|
|
6
6
|
|
|
7
7
|
from pytest import mark, param, raises
|
|
8
8
|
|
|
@@ -214,6 +214,59 @@ def test_interpolation_after_copy(copy_func: Any, data: Any, key: Any) -> None:
|
|
|
214
214
|
assert copy_func(dict_cfg._get_node(key))._dereference_node() == 10
|
|
215
215
|
|
|
216
216
|
|
|
217
|
+
@mark.parametrize("key", [param(1, id="int"), param("1", id="str")])
|
|
218
|
+
def test_interpolation_to_integer_key(key: Any) -> None:
|
|
219
|
+
cfg = OmegaConf.create({key: "value", "ref": "${1}"})
|
|
220
|
+
|
|
221
|
+
assert cfg.ref == "value"
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@mark.parametrize("resolution", [param(224, id="int"), param("224", id="str")])
|
|
225
|
+
def test_interpolation_with_nested_integer_key(resolution: Any) -> None:
|
|
226
|
+
cfg = OmegaConf.create(
|
|
227
|
+
{
|
|
228
|
+
"anchors": {"imagenet": {resolution: {"data": "value"}}},
|
|
229
|
+
"dataset": "imagenet",
|
|
230
|
+
"resolution": 224,
|
|
231
|
+
"ref": "${anchors.${dataset}.${resolution}.data}",
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
assert cfg.ref == "value"
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def test_interpolation_with_nested_integer_key_from_yaml() -> None:
|
|
239
|
+
cfg = OmegaConf.create(
|
|
240
|
+
dedent(
|
|
241
|
+
"""
|
|
242
|
+
anchors:
|
|
243
|
+
coco2014:
|
|
244
|
+
224:
|
|
245
|
+
data: [1, 2, 3]
|
|
246
|
+
dataset: coco2014
|
|
247
|
+
resolution: 224
|
|
248
|
+
ref: ${anchors.${dataset}.${resolution}.data}
|
|
249
|
+
"""
|
|
250
|
+
)
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
assert cfg.ref == [1, 2, 3]
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def test_interpolation_to_typed_integer_key() -> None:
|
|
257
|
+
values = DictConfig({1: "value"}, key_type=int)
|
|
258
|
+
cfg = OmegaConf.create({"values": values, "ref": "${values.1}"})
|
|
259
|
+
|
|
260
|
+
assert cfg.ref == "value"
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def test_interpolation_to_union_typed_integer_key() -> None:
|
|
264
|
+
values = DictConfig({1: 10}, element_type=Union[int, str])
|
|
265
|
+
cfg = OmegaConf.create({"values": values, "ref": "${values.1}"})
|
|
266
|
+
|
|
267
|
+
assert cfg.ref == 10
|
|
268
|
+
|
|
269
|
+
|
|
217
270
|
def test_resolve_interpolation_without_parent() -> None:
|
|
218
271
|
with raises(
|
|
219
272
|
IRE, match=re.escape("Cannot resolve interpolation for a node without a parent")
|
|
@@ -871,12 +871,13 @@ def test_dir(cfg: Any, key: Any, expected: Any) -> None:
|
|
|
871
871
|
assert dir(c._get_node(key)) == expected
|
|
872
872
|
|
|
873
873
|
|
|
874
|
-
def
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
874
|
+
def test_unhashable() -> None:
|
|
875
|
+
cfg = OmegaConf.create({"a": 10})
|
|
876
|
+
with raises(TypeError, match="unhashable"):
|
|
877
|
+
hash(cfg)
|
|
878
|
+
OmegaConf.set_readonly(cfg, True)
|
|
879
|
+
with raises(TypeError, match="unhashable"):
|
|
880
|
+
hash(cfg)
|
|
880
881
|
|
|
881
882
|
|
|
882
883
|
@mark.parametrize("default", ["default", 0, None])
|
|
@@ -988,6 +989,49 @@ def test_creation_with_invalid_key() -> None:
|
|
|
988
989
|
OmegaConf.create({object(): "a"})
|
|
989
990
|
|
|
990
991
|
|
|
992
|
+
@mark.parametrize(
|
|
993
|
+
"items",
|
|
994
|
+
[
|
|
995
|
+
param([(1, "numeric"), ("1", "string")], id="int-first"),
|
|
996
|
+
param([("1", "string"), (1, "numeric")], id="str-first"),
|
|
997
|
+
],
|
|
998
|
+
)
|
|
999
|
+
def test_creation_with_ambiguous_integer_key(items: Any) -> None:
|
|
1000
|
+
with raises(KeyValidationError, match="integer and string keys"):
|
|
1001
|
+
OmegaConf.create(dict(items))
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
@mark.parametrize(
|
|
1005
|
+
("initial_key", "new_key"),
|
|
1006
|
+
[param(1, "1", id="int-first"), param("1", 1, id="str-first")],
|
|
1007
|
+
)
|
|
1008
|
+
def test_setitem_with_ambiguous_integer_key(initial_key: Any, new_key: Any) -> None:
|
|
1009
|
+
cfg = OmegaConf.create({initial_key: "initial"})
|
|
1010
|
+
|
|
1011
|
+
with raises(KeyValidationError, match="integer and string keys"):
|
|
1012
|
+
cfg[new_key] = "new"
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
def test_float_and_string_keys_are_not_ambiguous() -> None:
|
|
1016
|
+
cfg = OmegaConf.create({1.5: "float", "1.5": "string"})
|
|
1017
|
+
|
|
1018
|
+
assert cfg[1.5] == "float"
|
|
1019
|
+
assert cfg["1.5"] == "string"
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
@mark.parametrize("stored_key", [param(True, id="bool"), param(1.0, id="float")])
|
|
1023
|
+
def test_setitem_integer_key_updates_equal_non_integer_key(stored_key: Any) -> None:
|
|
1024
|
+
cfg = OmegaConf.create({stored_key: "initial", "1": "string"})
|
|
1025
|
+
|
|
1026
|
+
cfg[1] = "updated"
|
|
1027
|
+
|
|
1028
|
+
assert cfg[stored_key] == "updated"
|
|
1029
|
+
assert cfg["1"] == "string"
|
|
1030
|
+
node = cfg._get_node(stored_key)
|
|
1031
|
+
assert node is not None
|
|
1032
|
+
assert type(node._key()) is type(stored_key)
|
|
1033
|
+
|
|
1034
|
+
|
|
991
1035
|
def test_setitem_with_invalid_key() -> None:
|
|
992
1036
|
cfg = OmegaConf.create()
|
|
993
1037
|
with raises(KeyValidationError):
|
|
@@ -858,12 +858,13 @@ def test_append_throws_not_changing_list() -> None:
|
|
|
858
858
|
assert c == [iv]
|
|
859
859
|
|
|
860
860
|
|
|
861
|
-
def
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
861
|
+
def test_unhashable() -> None:
|
|
862
|
+
cfg = OmegaConf.create([10])
|
|
863
|
+
with raises(TypeError, match="unhashable"):
|
|
864
|
+
hash(cfg)
|
|
865
|
+
OmegaConf.set_readonly(cfg, True)
|
|
866
|
+
with raises(TypeError, match="unhashable"):
|
|
867
|
+
hash(cfg)
|
|
867
868
|
|
|
868
869
|
|
|
869
870
|
@mark.parametrize(
|
|
@@ -459,6 +459,63 @@ def test_merge(
|
|
|
459
459
|
merge_function(*configs)
|
|
460
460
|
|
|
461
461
|
|
|
462
|
+
@mark.parametrize("merge", [OmegaConf.merge, OmegaConf.unsafe_merge])
|
|
463
|
+
@mark.parametrize(
|
|
464
|
+
("override", "expected_count"),
|
|
465
|
+
[param({}, 10, id="empty"), param({"count": 20}, 20, id="non-empty")],
|
|
466
|
+
)
|
|
467
|
+
def test_merge_none_structured_config_root(
|
|
468
|
+
merge: Any, override: Dict[str, Any], expected_count: int
|
|
469
|
+
) -> None:
|
|
470
|
+
class RuntimeObject: ...
|
|
471
|
+
|
|
472
|
+
@dataclass
|
|
473
|
+
class Value:
|
|
474
|
+
count: int = 10
|
|
475
|
+
inherited: int = "${..template}" # type: ignore[assignment]
|
|
476
|
+
payload: Any = field(default_factory=RuntimeObject)
|
|
477
|
+
|
|
478
|
+
@dataclass
|
|
479
|
+
class Config:
|
|
480
|
+
template: int = 30
|
|
481
|
+
value: Optional[Value] = None
|
|
482
|
+
|
|
483
|
+
cfg = OmegaConf.structured(Config, flags={"allow_objects": True})
|
|
484
|
+
value = cfg._get_node("value")
|
|
485
|
+
|
|
486
|
+
result = merge(value, override)
|
|
487
|
+
|
|
488
|
+
assert OmegaConf.get_type(result) is Value
|
|
489
|
+
assert result.count == expected_count
|
|
490
|
+
assert result.inherited == 30
|
|
491
|
+
assert isinstance(result.payload, RuntimeObject)
|
|
492
|
+
assert result._get_flag("allow_objects") is True
|
|
493
|
+
assert result._key() == "value"
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def test_merge_none_structured_config_root_rejects_incompatible_type() -> None:
|
|
497
|
+
destination = OmegaConf.structured(C)._get_node("x")
|
|
498
|
+
source = OmegaConf.structured(B)
|
|
499
|
+
|
|
500
|
+
with raises(ValidationError):
|
|
501
|
+
OmegaConf.merge(destination, source)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
def test_merge_missing_structured_config_into_none_root() -> None:
|
|
505
|
+
destination = OmegaConf.structured(C)._get_node("x")
|
|
506
|
+
source = OmegaConf.structured(B)._get_node("x")
|
|
507
|
+
|
|
508
|
+
result = OmegaConf.merge(destination, source)
|
|
509
|
+
|
|
510
|
+
assert result._is_none()
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def test_merge_none_dictconfig_root() -> None:
|
|
514
|
+
result = OmegaConf.merge(DictConfig(None), {"key": "value"})
|
|
515
|
+
|
|
516
|
+
assert result == {"key": "value"}
|
|
517
|
+
|
|
518
|
+
|
|
462
519
|
def test_merge_missing_structured_keeps_interpolation_target() -> None:
|
|
463
520
|
@dataclass
|
|
464
521
|
class Defaults:
|
|
@@ -572,6 +572,21 @@ def test_resolve_raises_on_resolver_arg_to_missing(restore_resolvers: Any) -> No
|
|
|
572
572
|
OmegaConf.resolve(cfg)
|
|
573
573
|
|
|
574
574
|
|
|
575
|
+
def test_resolve_error_keeps_key_and_object_type() -> None:
|
|
576
|
+
"""https://github.com/omry/omegaconf/issues/1330"""
|
|
577
|
+
cfg = OmegaConf.structured(StructuredWithMissing)
|
|
578
|
+
cfg.num = "${no_such_key}"
|
|
579
|
+
|
|
580
|
+
with raises(InterpolationKeyError) as direct:
|
|
581
|
+
cfg.num
|
|
582
|
+
with raises(InterpolationKeyError) as resolved:
|
|
583
|
+
OmegaConf.resolve(cfg)
|
|
584
|
+
|
|
585
|
+
assert resolved.value.full_key == direct.value.full_key == "num"
|
|
586
|
+
assert direct.value.object_type is StructuredWithMissing
|
|
587
|
+
assert resolved.value.object_type is StructuredWithMissing
|
|
588
|
+
|
|
589
|
+
|
|
575
590
|
def test_resolve_does_not_raise_when_resolver_returns_dict_config(
|
|
576
591
|
restore_resolvers: Any,
|
|
577
592
|
) -> None:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from contextlib import AbstractContextManager
|
|
2
|
-
from typing import Any, Optional
|
|
2
|
+
from typing import Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
from pytest import mark, param, raises, warns
|
|
5
5
|
|
|
@@ -7,6 +7,7 @@ from omegaconf import DictConfig, ListConfig, MissingMandatoryValue, OmegaConf
|
|
|
7
7
|
from omegaconf._impl import select_value
|
|
8
8
|
from omegaconf._utils import _ensure_container
|
|
9
9
|
from omegaconf.errors import InterpolationKeyError
|
|
10
|
+
from tests import Color
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def _register_resolver(register_func: Any, name: str, resolver: Any) -> None:
|
|
@@ -35,6 +36,16 @@ class TestSelect:
|
|
|
35
36
|
param({"a": ListConfig(None)}, "a.b", None, id="dict:nesting_into_none"),
|
|
36
37
|
# value returned
|
|
37
38
|
param({"c": 1}, "c", 1, id="dict:int"),
|
|
39
|
+
param({1: "one"}, "1", "one", id="dict:integer-key"),
|
|
40
|
+
param(
|
|
41
|
+
DictConfig({1: 10}, element_type=Union[int, str]),
|
|
42
|
+
"1",
|
|
43
|
+
10,
|
|
44
|
+
id="dict:union-typed-integer-key",
|
|
45
|
+
),
|
|
46
|
+
param({True: "bool"}, "1", None, id="dict:bool-key-not-coerced"),
|
|
47
|
+
param({1.5: "float"}, r"1\.5", None, id="dict:float-key-not-coerced"),
|
|
48
|
+
param({Color.RED: "red"}, "RED", None, id="dict:enum-key-not-coerced"),
|
|
38
49
|
param({"a": {"v": 1}}, "a.v", 1, id="dict:int"),
|
|
39
50
|
param({"a": {"v": 1}}, "a", {"v": 1}, id="dict:dict"),
|
|
40
51
|
param({"missing": "???"}, "missing", None, id="dict:missing"),
|
|
@@ -88,6 +99,12 @@ class TestSelect:
|
|
|
88
99
|
else:
|
|
89
100
|
assert OmegaConf.select(cfg, key) == expected
|
|
90
101
|
|
|
102
|
+
def test_can_select_integer_key(self, struct: Optional[bool]) -> None:
|
|
103
|
+
cfg = _ensure_container({1: "one"})
|
|
104
|
+
OmegaConf.set_struct(cfg, struct)
|
|
105
|
+
|
|
106
|
+
assert OmegaConf.can_select(cfg, "1")
|
|
107
|
+
|
|
91
108
|
@mark.parametrize(
|
|
92
109
|
"register_func",
|
|
93
110
|
[OmegaConf.legacy_register_resolver, OmegaConf.register_resolver],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any, Union
|
|
2
2
|
|
|
3
3
|
from pytest import mark, param, raises
|
|
4
4
|
|
|
@@ -18,6 +18,7 @@ from tests import Group, Package, User
|
|
|
18
18
|
[
|
|
19
19
|
# dict
|
|
20
20
|
param({"a": "b"}, "a", "c", {"a": "c"}, id="replace:string"),
|
|
21
|
+
param({1: "old"}, "1", "new", {1: "new"}, id="replace:integer-key"),
|
|
21
22
|
param({"a": "b"}, "c", "d", {"a": "b", "c": "d"}, id="add:string"),
|
|
22
23
|
param({"a": "b"}, "c", None, {"a": "b", "c": None}, id="none_value"),
|
|
23
24
|
param({}, "a", {}, {"a": {}}, id="dict:value:empty_dict"),
|
|
@@ -56,6 +57,13 @@ from tests import Group, Package, User
|
|
|
56
57
|
{"a": {"b": 1, "c": 2}},
|
|
57
58
|
id="dict_value:merge",
|
|
58
59
|
),
|
|
60
|
+
param(
|
|
61
|
+
{1: {"a": 1}},
|
|
62
|
+
"1",
|
|
63
|
+
{"b": 2},
|
|
64
|
+
{1: {"a": 1, "b": 2}},
|
|
65
|
+
id="dict_value:integer-key:merge",
|
|
66
|
+
),
|
|
59
67
|
# list
|
|
60
68
|
param({"a": [1, 2]}, "a", [2, 3], {"a": [2, 3]}, id="list:replace"),
|
|
61
69
|
param([1, 2, 3], "1", "abc", [1, "abc", 3], id="list:update"),
|
|
@@ -193,6 +201,14 @@ def test_update_list_index_error() -> None:
|
|
|
193
201
|
assert c == [1, 2, 3]
|
|
194
202
|
|
|
195
203
|
|
|
204
|
+
def test_update_union_typed_integer_key() -> None:
|
|
205
|
+
cfg = DictConfig({1: 10}, element_type=Union[int, str])
|
|
206
|
+
|
|
207
|
+
OmegaConf.update(cfg, "1", 20)
|
|
208
|
+
|
|
209
|
+
assert cfg == {1: 20}
|
|
210
|
+
|
|
211
|
+
|
|
196
212
|
def test_update_merge_by_default() -> None:
|
|
197
213
|
cfg = OmegaConf.create({"a": {"b": 10}})
|
|
198
214
|
OmegaConf.update(cfg, "a", {"c": 20})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarLexer.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/grammar/gen/OmegaConfGrammarParser.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/BufferedTokenStream.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/CommonTokenFactory.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/CommonTokenStream.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/ParserInterpreter.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/ParserRuleContext.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/PredictionContext.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/TokenStreamRewriter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ATNDeserializer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/LexerATNSimulator.py
RENAMED
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/LexerActionExecutor.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/ParserATNSimulator.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/PredictionMode.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/atn/SemanticContext.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/dfa/DFASerializer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/ErrorListener.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/error/ErrorStrategy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/ParseTreeMatch.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/ParseTreePattern.py
RENAMED
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/RuleTagToken.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/omegaconf/vendor/antlr4/tree/TokenTagToken.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/dataclass_postponed_annotations.py
RENAMED
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/examples/test_postponed_annotations.py
RENAMED
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/built_in_resolvers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/interpolation/test_custom_resolvers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/data/dataclasses_pre_311.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/test_structured_basic.py
RENAMED
|
File without changes
|
{omegaconf-2.4.0.dev14 → omegaconf-2.4.0.dev15}/tests/structured_conf/test_structured_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|