-
Notifications
You must be signed in to change notification settings - Fork 0
feat!: Add _imports_ key and rename globals to imports
#6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Remove _requires_ from non_arg_keys and special_keys as it was documented but never implemented. BREAKING CHANGE: _requires_ key is no longer recognized as a special key. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
WalkthroughThis PR replaces the previous globals/requires model with an imports mechanism. Config.init now accepts an imports parameter (internal _imports storage); a new _process_imports_key() consumes a YAML imports key and removes it from config data; parser/preprocessor now use imports as evaluation context; parse_overrides uses yaml.safe_load; requires was removed from non-arg handling and docs/tests updated to reference imports. Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/sparkwheel/config.py (1)
708-752: Consider logging or warning on failed imports.When
optional_importfails (returns_LazyRaiseplaceholder), the code silently stores it. User will only see the error when the import is accessed in an expression.This is acceptable for lazy error handling, but consider adding a debug log or docstring note about this behavior.
+ # Note: Failed imports return a lazy placeholder that raises on access. + # This provides clear error messages at expression evaluation time. for name, module_path in imports_config.items():
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (9)
docs/user-guide/advanced.md(2 hunks)docs/user-guide/basics.md(1 hunks)docs/user-guide/instantiation.md(0 hunks)src/sparkwheel/config.py(8 hunks)src/sparkwheel/items.py(1 hunks)src/sparkwheel/schema.py(1 hunks)tests/test_components.py(1 hunks)tests/test_config.py(1 hunks)tests/test_items.py(0 hunks)
💤 Files with no reviewable changes (2)
- docs/user-guide/instantiation.md
- tests/test_items.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
⚙️ CodeRabbit configuration file
Remember that documentation must be updated with the latest information.
Files:
docs/user-guide/basics.mddocs/user-guide/advanced.md
**/*.py
⚙️ CodeRabbit configuration file
Review the Python code for quality and correctness. Ensure variable names adhere to PEP8 style guides, are sensible and informative in regards to their function, though permitting simple names for loop and comprehension variables. Ensure routine names are meaningful in regards to their function and use verbs, adjectives, and nouns in a semantically appropriate way. Docstrings should be present for all definition which describe each variable, return value, and raised exception in the appropriate section of the Google-style of docstrings. Examine code for logical error or inconsistencies, and suggest what may be changed to addressed these. Suggest any enhancements for code improving efficiency, maintainability, comprehensibility, and correctness. Ensure new or modified definitions will be covered by existing or new unit tests.
Files:
src/sparkwheel/schema.pytests/test_components.pysrc/sparkwheel/items.pytests/test_config.pysrc/sparkwheel/config.py
🧬 Code graph analysis (2)
tests/test_config.py (1)
src/sparkwheel/config.py (2)
Config(115-835)resolve(577-668)
src/sparkwheel/config.py (3)
src/sparkwheel/utils/module.py (1)
optional_import(149-200)src/sparkwheel/preprocessor.py (1)
Preprocessor(21-353)src/sparkwheel/parser.py (2)
Parser(12-100)parse(59-71)
🔇 Additional comments (12)
tests/test_components.py (1)
114-114: LGTM!Assertion correctly validates
_mode_exclusion from kwargs, aligning withnon_arg_keysupdate.docs/user-guide/basics.md (1)
413-415: LGTM!Documentation correctly adds
_imports_to special keys and links to Advanced Features for details.src/sparkwheel/schema.py (1)
313-314: LGTM!Special keys correctly updated to include
_imports_and_args_, consistent withComponent.non_arg_keys.src/sparkwheel/items.py (1)
126-126: LGTM!Breaking change:
_requires_removed fromnon_arg_keys. Documented in PR objectives.docs/user-guide/advanced.md (2)
121-121: LGTM!
_imports_correctly documented as a special key.
292-342: LGTM!Comprehensive documentation of the imports mechanism. Examples clearly show both YAML-based
_imports_and Pythonimportsparameter approaches.tests/test_config.py (2)
137-148: LGTM!Tests properly renamed from
globalstoimports, verifying the new API.
150-229: LGTM!Comprehensive test coverage for
_imports_key handling: basic usage, multiple modules, dotted paths, removal after processing, interaction withimportsparameter, and graceful handling of invalid values.src/sparkwheel/config.py (4)
151-156: LGTM!Docstring correctly documents the renamed
importsparameter.
158-206: LGTM!Clean initialization of
_importswith proper handling of string module paths vs pre-imported objects.
686-700: LGTM!Correct placement of
_process_imports_key()call before parsing to ensure imports are available to expressions.
838-876: LGTM!Docstring accurately documents the switch from
ast.literal_evaltoyaml.safe_load, with clear examples of YAML syntax differences.
Add _imports_ key support in YAML configs to declare imports available
to all expressions:
```yaml
_imports_:
torch: torch
np: numpy
Path: pathlib.Path
device: "$torch.device('cuda')"
```
Also rename the Config parameter from globals to imports for consistency.
BREAKING CHANGE: Config(globals=...) is now Config(imports=...)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/sparkwheel/config.py (1)
686-753: Guard_process_imports_keyagainst non‑dict roots to avoid edge‑case errorsCurrently
_process_imports_keyassumesself._databehaves like a dict:imports_key = "_imports_" if imports_key not in self._data: return imports_config = self._data.pop(imports_key)If someone constructs
Configwith a non‑dict root (e.g., a list) and then callsresolve(), this can raise in surprising ways:
- For a list root that happens to contain the string
"_imports_",imports_key in self._dataisTrue, andself._data.pop(imports_key)will attempt list.pop()with a string index, raisingTypeError.- Even when
"_imports_"is not present, the membership check is slightly odd on non‑mapping roots.Given Config already allows non‑dict roots in some tests (e.g.,
Config("not a dict")), a small guard would make this more robust and keep_imports_strictly a mapping‑root feature.Suggested tweak:
def _process_imports_key(self) -> None: @@ - imports_key = "_imports_" - if imports_key not in self._data: - return + imports_key = "_imports_" + # Only process _imports_ when the root is a mapping + if not isinstance(self._data, dict): + return + if imports_key not in self._data: + returnThe rest of the logic (dict-type check on
imports_config, dotted-path handling withoptional_import, and support for non-string/module objects) looks solid and aligns with the new tests.
🧹 Nitpick comments (2)
tests/test_config.py (1)
150-257:_imports_behavior is well covered; consider one alias‑collision test (optional)The new
TestConfigImportscases thoroughly exercise:
- basic module imports,
- dotted module/class paths,
- interaction with the
importsconstructor parameter,- invalid
_imports_values,- and non‑string/imported objects.
Optionally, you could add a test where the same alias is provided both via
imports={...}and via_imports_to lock in the precedence semantics (constructor vs YAML). Current implementation lets the YAML_imports_override the existing entry, which seems reasonable but isn’t asserted anywhere.src/sparkwheel/config.py (1)
842-877: YAML‑basedparse_overridesbehavior matches docs and tests; import location optional nitThe move to
yaml.safe_loadfor value parsing is consistent with the updated docstring and the tests (YAML booleans, nulls, lists, dicts, and invalid YAML fallbacks). Operator handling (~key,=key=value,key=value) still behaves as expected.Minor optional nit: you re-import
yamlinsideparse_overrides; since this may be called in a loop, consider a module‑level import to avoid repeated local imports, though in practice Python’s import caching already keeps overhead small.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (5)
docs/user-guide/advanced.md(2 hunks)docs/user-guide/basics.md(1 hunks)docs/user-guide/instantiation.md(0 hunks)src/sparkwheel/config.py(8 hunks)tests/test_config.py(1 hunks)
💤 Files with no reviewable changes (1)
- docs/user-guide/instantiation.md
🚧 Files skipped from review as they are similar to previous changes (2)
- docs/user-guide/basics.md
- docs/user-guide/advanced.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
⚙️ CodeRabbit configuration file
Review the Python code for quality and correctness. Ensure variable names adhere to PEP8 style guides, are sensible and informative in regards to their function, though permitting simple names for loop and comprehension variables. Ensure routine names are meaningful in regards to their function and use verbs, adjectives, and nouns in a semantically appropriate way. Docstrings should be present for all definition which describe each variable, return value, and raised exception in the appropriate section of the Google-style of docstrings. Examine code for logical error or inconsistencies, and suggest what may be changed to addressed these. Suggest any enhancements for code improving efficiency, maintainability, comprehensibility, and correctness. Ensure new or modified definitions will be covered by existing or new unit tests.
Files:
tests/test_config.pysrc/sparkwheel/config.py
🧬 Code graph analysis (1)
src/sparkwheel/config.py (3)
src/sparkwheel/utils/module.py (1)
optional_import(149-200)src/sparkwheel/preprocessor.py (1)
Preprocessor(21-353)src/sparkwheel/parser.py (2)
Parser(12-100)parse(59-71)
🔇 Additional comments (3)
tests/test_config.py (1)
137-148: Init tests forimportsparameter are appropriate and low-couplingUsing
"pandas"only to check population ofparser._imports(without asserting import success) keeps tests independent of optional heavy dependencies, and the callable case verifies identity correctly. No changes needed.src/sparkwheel/config.py (2)
150-207:importsinitialization and wiring into Preprocessor look correctThe new
importskwarg is plumbed cleanly:
self._importsis always a dict, and onlydictinputs are processed, so bad types don’t leak in.- String values go through
optional_import, non‑strings are taken as-is (modules/callables), which matches the tests’ expectations.- Passing
self._importsintoPreprocessorkeeps the API aligned with the existingglobalsnotion and is forward‑compatible even though it’s unused today.No obvious correctness issues here.
700-701: Passing_importsintoParsercorrectly exposes YAML/imports to expressionsSwitching
Parser(globals=self._imports, ...)ensures both constructor‑levelimportsand YAML_imports_end up in the expression evaluation context. Given the comprehensive tests around json/os/pathlib/Counter imports, this wiring looks correct.
Summary
_imports_key support in YAML configs to declare imports available to all expressionsglobalstoimports_requires_key that was never implementedUsage
YAML-based imports:
Python parameter:
config = Config(imports={"torch": "torch", "np": "numpy"})
Breaking Changes