Skip to content

Conversation

@wingding12
Copy link

Summary

When Constant field is initialized with None as the constant value, loading a payload containing null would incorrectly raise:

ValidationError: {'sentinel': ['Field may not be null.']}

Root Cause

The issue was in the initialization order:

  1. Constant.__init__ calls super().__init__(**kwargs)
  2. Field.__init__ computes allow_none based on load_default (line 213)
  3. At this point, load_default is still missing_ (not passed in kwargs)
  4. So allow_none is computed as False
  5. Only afterwards does Constant.__init__ set self.load_default = constant
  6. But allow_none has already been incorrectly set

Fix

Pass load_default and dump_default to the parent constructor via kwargs.setdefault() so that allow_none is computed correctly when the constant is None.

Test Plan

Added test test_constant_none_allows_null_input that verifies:

  • Loading {"sentinel": None} works without raising ValidationError
  • Loading {"sentinel": "anything"} also works (constant always wins)
  • Dumping also works correctly

Fixes #2868

When Constant field is initialized with None as the constant value,
loading a payload containing null would incorrectly raise:
  ValidationError: {'sentinel': ['Field may not be null.']}

The issue was that Field.__init__ computes allow_none based on
load_default before Constant.__init__ sets load_default to the
constant value. By the time load_default is set to None, allow_none
has already been computed as False.

The fix passes load_default and dump_default to the parent constructor
via kwargs.setdefault() so that allow_none is computed correctly.

Fixes marshmallow-code#2868
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.

fields.Constant rejects None constant values during load

1 participant