Separate built-in parsers from msgspec optional dependency; fix MsgspecParser type handling and conflict detection#54
Merged
HEROgold merged 2 commits intonested-levelsfrom Mar 2, 2026
Conversation
…ict detection Co-authored-by: HEROgold <21345384+HEROgold@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add support for nested configuration
Separate built-in parsers from msgspec optional dependency; fix MsgspecParser type handling and conflict detection
Mar 2, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR restructures confkit’s parser modules to avoid importing the optional msgspec dependency for INI/.env-only usage, and refines MsgspecParser write behavior (type preservation + stricter path conflict detection).
Changes:
- Moved built-in parsers (
ConfkitParser,IniParser,EnvParser) into a new zero-optional-deps module:confkit.parsers. - Updated
Config+ tests/examples to import built-in parsers fromconfkit.parsersand only importMsgspecParserfromconfkit.ext.parserswhen needed. - Updated
MsgspecParser.set()to store native Python types when safe, and raise on scalar-vs-section conflicts even at the final path element.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_two_instances.py | Update import path for IniParser to confkit.parsers. |
| tests/test_pydantic_models.py | Update import path for IniParser to confkit.parsers. |
| tests/test_nested_config.py | Split imports: MsgspecParser from confkit.ext.parsers, IniParser from confkit.parsers. |
| tests/test_multiple_configurations.py | Update import path for IniParser to confkit.parsers. |
| tests/test_msgspecparser_no_msgspec.py | Tighten ImportError assertion using re.escape() for exact message matching. |
| tests/test_metaclass.py | Update import path for IniParser to confkit.parsers. |
| tests/test_env_parser.py | Update import path for EnvParser to confkit.parsers. |
| tests/test_config_detect_parser.py | Split imports: MsgspecParser from confkit.ext.parsers, IniParser from confkit.parsers. |
| tests/test_config_decorators.py | Update import path for IniParser to confkit.parsers. |
| tests/test_config_classvars.py | Update import path for IniParser to confkit.parsers. |
| tests/test_config.py | Update import path for IniParser to confkit.parsers. |
| src/confkit/parsers.py | New module for built-in parsers/protocol without optional dependencies; adds % escaping to IniParser.set(). |
| src/confkit/ext/parsers.py | Now msgspec-only; improves _navigate_to_section conflict detection and stores native vs stringified BaseDataType values in set(). |
| src/confkit/config.py | Switch built-in parser imports to confkit.parsers; change _set() to pass values directly to parsers (no longer pre-sanitizing to str). |
| examples/nested_config.py | Remove deprecated set_parser(IniParser()) usage; rely on auto-detection from .ini. |
| .github/copilot-instructions.md | Docs update to reflect ConfkitParser protocol and built-in parser module locations. |
HEROgold
added a commit
that referenced
this pull request
Mar 2, 2026
* Add support for nested configuration * Update docs/examples/custom_data_type.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix docs: remove non-existent `Parser`/`set_parser` references (#53) * Initial plan * Fix documentation: remove non-existent Parser/set_parser references Co-authored-by: HEROgold <21345384+HEROgold@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: HEROgold <21345384+HEROgold@users.noreply.github.com> * mark as deprecation instead of private method * Raise ConfigPathConflictError when trying to path through a scalar. * fix ruff issue * ignore line len on deprecation warning * ruff fixes * add missing .env parse detection * Separate built-in parsers from msgspec optional dependency; fix MsgspecParser type handling and conflict detection (#54) * Initial plan * Move built-in parsers to confkit.parsers, fix type handling and conflict detection Co-authored-by: HEROgold <21345384+HEROgold@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: HEROgold <21345384+HEROgold@users.noreply.github.com> * fix docstr * fix ruff --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
confkit.ext.parsersunconditionally importedmsgspecat module load time, breaking INI-only usage without the optional extra.MsgspecParser._parse_valuealso corrupted string values like"001"→1(int), and scalar-vs-section path conflicts were silently dropped on writes.Parser module split
confkit/parsers.pyholdsConfkitParser(Protocol),IniParser,EnvParser— zero optional depsconfkit/ext/parsers.pynow contains onlyMsgspecParser; still raisesImportErrorimmediately withoutmsgspecconfig.pyand all tests/examples updated to import built-in parsers fromconfkit.parsersMsgspecParser type handling (replaces
_parse_value)Config._setnow passesBaseDataTypeobjects directly to parsers instead of converting tostrfirst.MsgspecParser.setstores native Python types whenstr(native) == str(data_type)(standard types), and the custom string representation when they differ (e.g.Hex(10)→"0xa", not10). This preserves round-trip correctness without guessing types from strings.IniParser.sethandles%escaping internally (moved fromConfig._sanitize_str).Scalar conflict detection
_navigate_to_section(create=True)now raisesConfigPathConflictErrorwhen the final path element is already a scalar — previously only intermediate elements triggered this, silently dropping writes.Other fixes
test_msgspecparser_no_msgspec.py: usesmatch=re.escape(expected_msg)inpytest.raises.github/copilot-instructions.md: correctedParserfacade reference →ConfkitParserprotocol inparsers.pyexamples/nested_config.py: removed deprecatedset_parser(IniParser())call (auto-detected from.iniextension)💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.