Repository navigation
Conversation
_WithSubValidators (Any, All, Union, SomeOf) stored the compiled sub-validators on the instance: __voluptuous_compile__ reset self._compiled to an empty list and then appended to it, and _run read self._compiled (and, with a discriminant, overwrote it) on every call. A validator instance is often shared, e.g. a module level Any() that is reused in schemas built per request. When one thread compiles a new schema around it while another thread runs an already compiled schema, the running thread sees an empty or partially filled list and fails valid data with "no valid value found", or reports an error from the wrong alternative (e.g. "extra keys not allowed"). Gnocchi's REST API hits this under a threaded uWSGI: valid resource searches and aggregates requests are intermittently rejected with HTTP 400. Keep the compiled sub-validators in the closure returned by __voluptuous_compile__ instead, so compiling a schema never changes what another schema runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Simon Zhou <jp.zdm2008@gmail.com>
fivetime
added a commit
to fivetime/openstack-helm-images
that referenced
this pull request
Oct 8, 2026
voluptuous up to 0.16.0 keeps the compiled sub-validators of Any()/All() on the shared instance. Gnocchi shares such validators at module and class level and compiles them into a new Schema on every request, so under the threaded uWSGI a concurrent request can see an empty or half-built list and reject a valid search with HTTP 400. Install the fork that keeps them per schema (alecthomas/voluptuous#556) in the 2026.2 cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Problem
_WithSubValidators(Any,All,Union,SomeOf) keeps the compiled sub-validators on the instance.__voluptuous_compile__resetsself._compiledto an empty list and then appends to it._runreadsself._compiledon every call, and overwrites it when adiscriminantis set.A validator instance is often shared. A common pattern is a module-level
Any(...)reused inside schemas that are built per request. Then two things can overlap:In that case the running thread sees an empty or half-filled list, and valid data fails:
no valid value found(anAnywith no alternatives left);extra keys not allowed @ data['search']when only the first alternative of anAnyhas been compiled yet.We hit this in production with Gnocchi's REST API under a threaded uWSGI. Gnocchi has a module-level
Any(str, float, int, bool, None)and a class-levelAnyrequest schema, and both are compiled into a newSchemaon every request. Valid resource searches and/v1/aggregatesrequests were rejected intermittently with HTTP 400:no valid value found for dictionary value @ data['and'][0]['or'][0]['=']['ended_at']extra keys not allowed @ data['search']Reproducer
Results for 320,000 validations with 8 threads:
The failures include
no valid value found,extra keys not allowed @ data['search']andexpected str for dictionary value @ data['=']['ended_at']. With one thread there are no errors before or after the change.Fix
The compiled sub-validators now live in the closure that
__voluptuous_compile__returns, not on the instance. Compiling one schema therefore never changes what another, already compiled, schema runs. Thediscriminantpath uses a local list too.The new test,
test_shared_any_unaffected_by_compiling_another_schema, is deterministic and single-threaded. It runs an already compiled schema while a second schema sharing the sameAnyis in the middle of compiling. It fails on master and passes with this change.The full test suite passes (183 tests on Python 3.9 and 3.14). flake8, black and mypy are clean.
🤖 Generated with Claude Code