Skip to content

Preserve nested mutable mappings in recursive merges - #453

Merged
dgilland merged 2 commits into
dgilland:developfrom
Rajatendu1:fix-nested-mapping-merge
Nov 15, 2026
Merged

dgilland merged 2 commits into
dgilland:developfrom
Rajatendu1:fix-nested-mapping-merge

Conversation

@Rajatendu1

Copy link
Copy Markdown
Contributor

Problem

A nested UserDict or ChainMap is treated differently from a nested dict during recursive merges. A small override replaces the entire mapping and loses unrelated settings. With defaults_deep, the existing mapping stays but missing defaults are not added. Customizers also never reach the nested entries.

For example, merging {"settings": UserDict({"host": "localhost", "timeout": 30})} with {"settings": {"timeout": 60}} currently drops host.

Change

Recognize any Mapping source paired with a MutableMapping destination as a recursive mapping merge. Keep the destination mapping object, the existing literal-key lookup, source deep-copying, list behavior and scalar replacement rules. Add regression coverage for mixed dict/UserDict/ChainMap pairs, deep defaults, customizers, mappings nested in lists, ChainMap parent layers and source isolation. No dependencies or public signatures change.

Validation

Base: develop at b6bd031de47134b8e3c3977fbe65bf13cc51a205.

  • Added 34 cases: 29 fail on the unchanged source and 5 compatibility controls already pass. All 34 pass with the change.
  • Full configured unit/doctest suite on Linux CPython 3.10.12, 3.11.17, 3.12.15, 3.13.17 and 3.14.9: baseline 3,324 passed, patched 3,358 passed, 100% library statement coverage in every run.
  • Full inv ci before and after on Python 3.10: source/wheel builds, Sphinx with warnings as errors, Ruff format/lint, mypy, generated chaining-stub freshness and the configured tests pass.
  • git diff --check passes.

The documented test command excludes tests/pytest_mypy_testing; source mypy and generated-stub checks are included. An initial broader exploratory collection included that optional directory and failed 334 assertions; those are not claimed as passing. Windows, macOS and hosted CI have not been run locally.

Patch prepared and tests executed by Instinct, an AI assistant, at my request.

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 100.0%. remained the same — Rajatendu1:fix-nested-mapping-merge into dgilland:develop

@dgilland
dgilland merged commit 195d3db into dgilland:develop Nov 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants