Skip to content

Add new validator: AnyDictValidator#148

Merged
binaryDiv merged 1 commit into
mainfrom
any-dict-validator
May 6, 2026
Merged

Add new validator: AnyDictValidator#148
binaryDiv merged 1 commit into
mainfrom
any-dict-validator

Conversation

@binaryDiv
Copy link
Copy Markdown
Contributor

This PR adds a new validator, the AnyDictValidator. This validator accepts any dictionary without validating its values, as long as the keys are strings (just like in a DictValidator).

It's essentially a shorthand for DictValidator(default_validator=AnythingValidator()).

Please note that this validator differs from an AnythingValidator(allowed_types=[dict]), because the latter does no validation on the dictionary at all and therefore allows non-string keys.

Since JSON objects cannot have non-string keys, this doesn't seem to make any difference in practice. However, the AnyDictValidator allows for better typing, because it always returns an object of type dict[str, object], while the AnythingValidator returns dict[Any, Any].

@binaryDiv binaryDiv self-assigned this Apr 29, 2026
@binaryDiv binaryDiv added the new validator Implementation of a new validator class label Apr 29, 2026
]


class AnyDictValidator(DictValidator[object]):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity what is the advantage of object of Any here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used it in this case because I noticed that it improves the type checking. But it's actually a good question in general, so I looked up again what the exact difference is, and... I think we should generally use object instead of Any more often. 😅 (Like, not everywhere, but in a lot of places object might be better.)

Basically, Any doesn't just mean "any possible type", it actually is more a kind of pseudotype to locally disable type checking for a given variable. So I guess it's less "any type" and more "unknown type" in a way. Setting Any as a type is essentially the same as having no type annotation at all, with the only difference being that someone explicitly declared the variable as "this is untyped, but on purpose".

object on the other hand is a static type that can stand for any possible type (because every type in Python inherits from object, so it's the base type). The difference is that with object you have statically typed code, meaning mypy will do strict type checking on it.

What this means in practice: Any allows (almost?) any operation on the variable (including assignments!), although for concrete types the operation might not actually be valid. If you type a variable as object, mypy will only allow operations on the variable that are supported by object, i.e. only operations that are valid for every type in Python.

For example, if you have this code:

var.some_method_that_might_not_exist()
var[i]
var + 5
explicitly_typed_Var: str = var

If var is typed as Any, mypy will accept that code. But if var is typed as object, mypy should report errors for every line: Not every type has a method with that specific name, not every type is indexable, not every type supports + with an integer, and the last line is invalid because you're can't assign object to an str variable.

The last one is also the reason I used object for the AnyDictValidator. Because if you use Any, defining a validataclass field like foo: dict[str, str] = AnyDictValidator() would be allowed by mypy (because it's valid to assign Any to str). But that would be wrong here, because the AnyDictValidator accepts user input that could very well be a dict[str, int] or some other dict.

For more info, see also the mypy docs: https://mypy.readthedocs.io/en/stable/dynamic_typing.html

@binaryDiv binaryDiv merged commit 6fa5682 into main May 6, 2026
6 checks passed
@binaryDiv binaryDiv deleted the any-dict-validator branch May 6, 2026 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new validator Implementation of a new validator class

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants