Fix ClassDecoratorSetting and get_class_settings to correctly handle __databind_settings__ on subclasses#77
Merged
NiklasRosenstein merged 8 commits intodevelopfrom Mar 25, 2026
Conversation
…sses Co-authored-by: NiklasRosenstein <1318438+NiklasRosenstein@users.noreply.github.com> Agent-Logs-Url: https://github.com/NiklasRosenstein/python-databind/sessions/beeda587-62ab-4243-ad49-d1a0c7b05759
Copilot
AI
changed the title
[WIP] Fix ExtraKeys decorator to create own __databind_settings__ in subclasses
Fix ClassDecoratorSetting to create own __databind_settings__ on subclasses
Mar 23, 2026
…ettings Co-authored-by: NiklasRosenstein <1318438+NiklasRosenstein@users.noreply.github.com> Agent-Logs-Url: https://github.com/NiklasRosenstein/python-databind/sessions/f66fb149-678a-494c-8bd0-69cbec04fc7f
Copilot
AI
changed the title
Fix ClassDecoratorSetting to create own __databind_settings__ on subclasses
Fix ClassDecoratorSetting and get_class_settings to correctly handle __databind_settings__ on subclasses
Mar 25, 2026
…ndle __databind_settings__ on subclasses
Ubuntu 20.04 runners have been removed, causing jobs to queue forever. Update to ubuntu-latest and bump checkout/setup-python to v4/v5. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Alias annotation on enum members is intentional for databind but violates mypy's enum typing spec. Add type: ignore to silence it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pkg_resources has no stubs and is only imported on Python < 3.10 at runtime, but mypy still checks the branch. Suppress import-not-found and the resulting no-any-return error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The pkg_resources type ignores are needed on 3.12+ but unused on 3.11 where stubs are available. Adding unused-ignore suppresses the warning on versions where the ignore isn't needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5 tasks
NiklasRosenstein
added a commit
that referenced
this pull request
Apr 2, 2026
## Summary - Fixes #80: `RecursionError` when serializing/deserializing dataclasses using the `Union` registry - Adds `inheritable` attribute to `ClassDecoratorSetting` (default `True`) and sets it to `False` on `Union`, preventing Union settings from being inherited by subclasses through MRO traversal - PR #77 introduced MRO traversal in `get_class_settings()` for `ExtraKeys` inheritance, but this inadvertently caused `Union` to also be inherited, leading to infinite recursion ## Test plan - [x] Regression test: Union base class with registered subclasses can serialize/deserialize without recursion - [x] Regression test: Union is not inherited through multi-level MRO chains (Base -> Middle -> Leaf) - [x] Regression test: Subclass with its own `@Union` decorator still works correctly - [x] Existing `ExtraKeys` inheritance tests still pass (PR #77 behavior preserved) - [x] Full test suite passes (81 tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.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.
ClassDecoratorSetting.__call__usedgetattr()to look up__databind_settings__, which resolves through MRO and returns the parent's list when the subclass has none. It then appends to that parent list in-place — butget_class_settings()originally usedvars(), which only checks the class's own__dict__, so the setting was never found on the subclass. Net effect:@ExtraKeys()on a subclass whose parent was already decorated was silently a no-op.Additionally,
get_class_settings()did not traverse the MRO, meaning subclasses could not inherit settings (such asExtraKeys()) from parent classes at all.Changes
settings.py—ClassDecoratorSetting.__call__: Replacegetattr(type_, "__databind_settings__", None)withvars(type_).get("__databind_settings__", None), ensuring a new list is always created on the target class rather than reusing an inherited one.settings.py—get_class_settings: Updated to traversetype_.__mro__so that subclasses inheritClassDecoratorSettingsettings (e.g.ExtraKeys()) from parent classes. The child class's own settings are yielded first, so a child can override a parent's setting by decorating itself explicitly (e.g.@ExtraKeys(allow=False)).converters_test.py: Add three regression tests covering the scenario:@ExtraKeys()each get independent__databind_settings__lists, and the parent's list is not polluted.ExtraKeys()from its parent (extra keys allowed), while a child explicitly decorated with@ExtraKeys(allow=False)overrides that and rejects extra keys.Original prompt
📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.