Skip to content

Booleans are accepted for type integer #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mbalser opened this issue Sep 10, 2015 · 10 comments
Closed

Booleans are accepted for type integer #144

mbalser opened this issue Sep 10, 2015 · 10 comments

Comments

@mbalser
Copy link

mbalser commented Sep 10, 2015

Internally cerberus 0.10 does the following:

>>> isinstance(1, (int,))
True
>>> isinstance(True, (int,))
True
>>> isinstance(0, (int,))
True
>>> isinstance(False, (int,))
True

Of course I could map True and False to integers using Value Coercion, but this seems awkward and feels it is not the correct thing to do when using a type check for integers and not explicitly for booleans.

@funkyfuture
Copy link
Member

what you show is Python's intended design.

can you elaborate your use-case?

@funkyfuture
Copy link
Member

btw, gh's markdown renders code between three backticks (not very accessible on qwertz-layouts).

@mbalser
Copy link
Author

mbalser commented Sep 10, 2015

The usecase is a customer facing api where I use cerberus for input validation. I want to clearly distinguish between truth values (true/false) and integers (1....1024).

Of course you are right about the python design choice, but I would rather not like to expose python internal "way-of-doing-things" to a backend neutral api. So my suggestion is to keep the current way of handling bool/int for backwards compatibility and provide something like a "strict" parameter which enforces that int has to be a number and not a boolean.

@mbalser
Copy link
Author

mbalser commented Sep 10, 2015

I think boolean is already strict - I guess only integer would require a "stricter" version - something like "integer_strict" or such.

The change itself should be quite trivial:

def _validate_type_integer_strict(self, field, value):
    if not isinstance(value, _int_types) or isinstance(value, bool):
        self._error(field, errors.ERROR_BAD_TYPE.format("integer"))

@funkyfuture
Copy link
Member

would the more generic number be suitable?

@mbalser
Copy link
Author

mbalser commented Sep 11, 2015

Although "number" is very generic in regards to int/float, but I think it would be a good fit.

@funkyfuture
Copy link
Member

yep, it isn't bound to a builtin-type anyway.

and numbers are infinite while 'true' / 'false' are (questionable,) very finite / determined concepts. ;-)

funkyfuture added a commit to funkyfuture/cerberus that referenced this issue Jan 31, 2016
nicolaiarocci pushed a commit that referenced this issue Feb 1, 2016
@arnauorriols
Copy link

I apologize for commenting on an already closed issue.

@mbalser #144 (comment) depicts precisely my opinion on this, and for me "number" is not suitable. Can you elaborate on the justification to expose Python's implementation details to a high-level tool like is Cerberus?

(I sincerely hope 3 == 2 + True was not really the Python's intended design, but rather an implementation trade-off)

@funkyfuture
Copy link
Member

well, the types are not all high-level i think (e.g. binary, datetime).

meanwhile a release candidate has taken form; it would be possible to change that and break bw-compatibility. i think it's okay to be more strict as {'type': 'integer'} -> {'type': ('bool', 'integer')} is an easy change.

(I sincerely hope 3 == 2 + True was not really the Python's intended design, but rather an implementation trade-off)

if that is the case, it must be changed as other interpreters may implement it differently. someone must lookup the specs.

@cjauvin
Copy link

cjauvin commented Nov 4, 2020

I'm new to Cerberus and recently stumbled upon this aspect of its design. I am validating some data structure decoded from a JSON string (in the context of a web API), and was surprised to find that a JS boolean, which gets mapped to a Python boolean by the JSON decoding, validates against a Cerberus integer. I agree with the "why expose a Python internal implementation aspect?" argument mentioned by others in this thread, and moreover, I would argue that Cerberus being an abstraction layer describing the data above the level of the language being actually used (as is my case, where I go from JSON to Python), it makes even more sense to have a strict interpretation of what the types mean. If you already distinguish between an integer and a number, wouldn't it more coherent to also distinguish between an integer and a boolean?

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 a pull request may close this issue.

4 participants