cerberus icon indicating copy to clipboard operation
cerberus copied to clipboard

Add None as constraint to allowed when nullable and allowed are defined on a field

Open radix opened this issue 8 years ago • 13 comments

Example schema:

>>> v = cerberus.Validator({
...     'x': {
...         'nullable': True,
...         'oneof': [{'type': 'string'}, {'type': 'number'}]}})

# As expected:
>>> v.validate({'x': 'foo'})
True
>>> v.validate({'x': 52})
True
>>> v.validate({'x': object()})
False

# Unexpected:
>>> v.validate({'x': None})
False

Used Cerberus version / latest commit: b8b26f927c9cdd093254439e0841e551dce51abf

  • I consulted these documentations:

    • [x] http://docs.python-cerberus.org/en/stable/
    • [x] http://docs.python-cerberus.org/en/latest/
  • I consulted these sections of the docs (add more lines as necessary):

    • Validation Rules
  • [x] I found nothing relevant to my problem in the docs.

  • [x] I found the documentation not helpful to my problem.

  • [ ] I have the capacity to improve the docs when my problem is solved.

  • [ ] I have the capacity to submit a patch when a bug is identified.

radix avatar Apr 03 '18 01:04 radix

everything works as expected. but indeed, it raises the point that there is no None type which would make this schema much simpler.

mind that type can take multiple constraints.

funkyfuture avatar Apr 05 '18 20:04 funkyfuture

@funkyfuture thanks. yeah, a None type would also solve my problem.

As for type taking multiple constraints, this is just a simplification of my real schema which has more complex schemas under the oneof.

The only way I could figure out to work around this was to implement a custom validator instead of using oneof, which made my schema considerably more complex (and made error reporting worse cause I couldn't immediately figure out how to chain the errors in a very elegant way, but I probably need to spend more time poking at that).

Is there any other workaround you can think of? I guess I could implement my own _validate_type_none...

radix avatar Apr 05 '18 20:04 radix

another thing: if nullable really can't be used with oneof, shouldn't constructing a Validator with such a schema raise an exception?

radix avatar Apr 05 '18 20:04 radix

of course nullable can be used with oneof, but your schema doesn't reflect your desired logic.

that's why {'x': {'type': ('string', 'number', 'none')}} would be preferable.

funkyfuture avatar Apr 11 '18 14:04 funkyfuture

if "nullable can be used with oneof", what behavior does it affect?

radix avatar Apr 11 '18 14:04 radix

your schema snippet says, the value can be None AND (must be a string OR a number).

funkyfuture avatar Apr 11 '18 14:04 funkyfuture

So... there's no effect?

radix avatar Apr 11 '18 16:04 radix

The same happens with allowed and nullable. You can add None at least in the allowed array, but this should be implied (ie, you need both None in the allowed array and 'nullable' to be set to True). Incredibly counter-intuitive

deanolium avatar May 21 '18 13:05 deanolium

Incredibly counter-intuitive

i'd argue that it'd be counter-intuitive when one rule with a certain constraint changes the semantics of another rule within a shared context.

funkyfuture avatar May 21 '18 17:05 funkyfuture

problem is: we're both right. also, i can't come up with something such schema alteration could mess up.

funkyfuture avatar Jun 01 '18 21:06 funkyfuture

@funkyfuture Cerberus's behavior is inconsistent with your analysis:

your schema snippet says, the value can be None AND (must be a string OR a number).

What does a schema that says {'type': 'string', 'nullable': True} mean?

Does it mean "the value can be None AND the value must have type string"? No, cerberus treats this as an OR. So why would it suddenly become an AND in the face of oneof?

radix avatar Jan 31 '19 23:01 radix

could you please check out whether 74caea64b3d3a13c27f3dede0d59e8d3c0fd11aa solved this issue?

funkyfuture avatar Feb 01 '19 10:02 funkyfuture

Even I get unallowed value None for the schema {'type': 'string', 'allowed': ('min', 'max'), 'nullable': True} for None value over the string. Is it expected?

prudhvee avatar Jul 22 '19 02:07 prudhvee

i assume that this issue is either solved with the previously mentioned commit or this one: 35d9f7b79f6afd165568db9671441a8f41cf34cf.

funkyfuture avatar Jul 23 '23 14:07 funkyfuture