Skip to content

Accept Mapping inputs for dict schemas - #550

Open
deepakganesh78 wants to merge 1 commit into
alecthomas:masterfrom
deepakganesh78:fix/issue299-accept-mapping
Open

Accept Mapping inputs for dict schemas#550
deepakganesh78 wants to merge 1 commit into
alecthomas:masterfrom
deepakganesh78:fix/issue299-accept-mapping

Conversation

@deepakganesh78

Copy link
Copy Markdown

Fixes #299

Reproduction

A dictionary schema currently rejects collections.abc.Mapping implementations that are not dict subclasses:

from collections.abc import Mapping
from voluptuous import Schema

class QueryArgs(Mapping):
    def __init__(self, data):
        self._data = data
    def __getitem__(self, key):
        return self._data[key]
    def __iter__(self):
        return iter(self._data)
    def __len__(self):
        return len(self._data)

Schema({"page": int})(QueryArgs({"page": 1}))

On current master this raises MultipleInvalid: expected a dictionary.

Root cause

Schema._compile_dict() only accepted dict instances even though the schema type already treats collections.abc.Mapping as a valid dictionary-like schema and mappings expose the .items() / membership APIs used by validation.

Fix

Accept collections.abc.Mapping inputs in dictionary schemas. Existing dict and dict subclass output behavior is preserved; generic Mapping inputs produce a plain dict, avoiding assumptions that arbitrary mapping classes can be constructed empty and mutated.

Compatibility notes

The existing error message for non-mapping inputs remains expected a dictionary. This only broadens accepted inputs for objects implementing the standard Mapping protocol.

Validation

  • Minimal reproducer failed before the fix with MultipleInvalid: expected a dictionary and succeeds after the fix.
  • Regression check with fix reverted: python -m pytest voluptuous\tests\tests.py::test_schema_accepts_mapping -q fails with MultipleInvalid: expected a dictionary.
  • Targeted regression with fix: python -m pytest voluptuous\tests\tests.py::test_schema_accepts_mapping -q -> 1 passed.
  • Full suite: python -m pytest -> 183 passed.
  • Formatting/lint/type checks: black --check voluptuous\schema_builder.py voluptuous\tests\tests.py -> unchanged; isort --check voluptuous\schema_builder.py voluptuous\tests\tests.py -> passed; flake8 --doctests voluptuous\schema_builder.py voluptuous\tests\tests.py -> passed; mypy voluptuous -> success, no issues found in 10 source files (mypy 2.3.0 also notes the repo's configured python_version = 3.9 is below its supported range on Python 3.13).

Fix dictionary schemas rejecting collections.abc.Mapping implementations such as aiohttp query mappings. Preserve existing dict subclass output behavior while returning a plain dict for generic Mapping inputs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@alecthomas

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 7cd2ce0e2e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

Validating a Mapping that isn't a dict fails

2 participants