3

According to examples, this is the correct way to create a validation Schema:

import voluptuous as vol
PORT1 = vol.Schema(vol.All(int, vol.Range(min=0, max=65535)))

However, I noticed, that the Schema call is missing in some of my validators, e.g.:

PORT2 = vol.All(int, vol.Range(min=0, max=65535))

I checked that PORT1 and PORT2 are not of the same type. The catch is that PORT2 works fine for me and gives the same results as the correct PORT1.

I don't know if I made a mistake. Could somebode please clearly state if it is an error to omit the Schema(...)? Why it works so well without the Schema(...) that I did not notice any problems?

VPfB
  • 14,927
  • 6
  • 41
  • 75

1 Answers1

2

Every validator has a __call__ defined for in the validators. You can see the source code below

https://github.com/alecthomas/voluptuous/blob/master/voluptuous/validators.py#L279

So even if you have

PORT3 = vol.Range(min=0, max=65535)
PORT3(100)

This will also work. As you said, PORT1 and PORT2 are different objects but the __call__ method is defined on all validators as well ones derived from _WithSubValidators

https://github.com/alecthomas/voluptuous/blob/2e557f71db6260e3ab40a6848a6bf4705d434f2d/voluptuous/validators.py#L184

The Schema object is wrapper around these validators to check an object as such.

In your case since you are only validating individual fields or combining them together with other validators, they will work perfectly fine

Working

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • Thank you for your explanation. Could you also answer the first question? `Schema()` is obviously needed when building a validator based on basic data types (`dict`, `list` etc.). But why the examples from voluptuous README.md file show e.g. `s=Schema(All(..))` when `s=All(..)` does the job, because `All` is a validator? – VPfB Jul 11 '19 at 07:14
  • Because you want to test a Schema and not just a particular value. It is the implementation which allows you to do it without the `Schema` also. Was it an intentional behavior by the author or it is just a side effect of how things have been implemented, I can't say. But one thing I would recommend is to use `Schema` always so that you are compatible with the future upgrades also – Tarun Lalwani Jul 11 '19 at 07:21
  • I wish voluptuous authors/maintainers were listening here and giving authoritative answers for this tag. I'm still confused. Using `Schema` is a safe bet of course, but my intution says a mandatory `Schema` would imply nonsense like this: `Schema(Any(Schema(All(Schema(a1), Schema(a2)), Schema(b))))` – VPfB Jul 17 '19 at 14:33
  • Any and All doesn't necessary needs to have a Schema wrapper. Consider this like Lego blocks, you can join multiple ones and use the way you like – Tarun Lalwani Jul 17 '19 at 14:45