Pydantic: Automatic conversion from float to int?

Created on 18 Jan 2019  路  10Comments  路  Source: samuelcolvin/pydantic


Bug

For bugs/questions:

  • OS: Any
  • Python version import sys; print(sys.version): 3.7
  • Pydantic version import pydantic; print(pydantic.VERSION): 0.18.1

You got a misfeature there, buddy. Automatic conversion (by default!) from float to int is a terrible idea:

from pydantic import PositiveInt, BaseModel

class MySchema(BaseModel): 
    int_only: PositiveInt

MySchema(int_only=3.1415)
# <MySchema int_only=3>

I am working with 2 separate codebases that communicate with each other. One of these apps could have the wrong idea about the type of a variable, it would be great if the validation framework caught this. I wanted to use Pydantic to validate the data. How can I circumvent this misfeature? (Please add the answer to the documentation.)

strictness

Most helpful comment

You got a misfeature there, buddy. Automatic conversion (by default!) from float to int is a terrible idea

Wow, what a great way of not getting help.

I try really hard to understand peoples problems and always give constructive answers, but here I'm really tempted to just click close.

Do you always start conversations with volunteers where you would like help by calling them "buddy", then telling them they have "terrible idea"s? Great idea buddy.

This is by considered design, but you can change the behaviour using validators with pre=True.

Or you can use another library. Not a problem with me.

All 10 comments

You got a misfeature there, buddy. Automatic conversion (by default!) from float to int is a terrible idea

Wow, what a great way of not getting help.

I try really hard to understand peoples problems and always give constructive answers, but here I'm really tempted to just click close.

Do you always start conversations with volunteers where you would like help by calling them "buddy", then telling them they have "terrible idea"s? Great idea buddy.

This is by considered design, but you can change the behaviour using validators with pre=True.

Or you can use another library. Not a problem with me.

Ref. #284

Dear Samuel,

I apologize. You are absolutely right that I was arrogant. It's nothing personal. I repeat this mistake nearly every week and then I resolve to watch it and then suddenly it happens again. I seem unable to shake it, but I must not give up. I am not being sarcastic, I have struggled with this all my life. Therapy had no power to shadow my dad's example. If it means anything, no offense was intended, but I spoke as if I already knew you, trying to be a little funny, and that's the way it always happens.

Again, I am sorry and I hope you can forgive me. I did not really mean to talk down to you, although it totally appears that way. I truly admire your work in this library (one that I couldn't have written), I think it is awesome, and this is why I am going to insist.

I still think that the default should be changed -- we should not build a validation library that declines to validate types by default. (Python is a strongly typed, if dynamically typed, language.) In the case I brought to you, 3.14 is being converted to 3 by default, which is information loss, happening exactly when we wanted to prevent information loss.

At a minimum, a configuration option should be added to control this behavior.

I guess that's the best case I can make for it.

Best regards, Nando.

Please read #284.

Also python is not a strictly typed language, it's duck typed by default. Look at bool behaviour, it's as unstrict as imaginable.

We can simplify this discussion. I do not mean to discuss Python or its booleans. I am just arguing that allowing 3.14 to become 3 is data loss. I am saying that information loss is a bad default, and that we should do something about this. We can restrict the discussion to the float to int case.

I'm not interested in Changing the behaviour even to make it configurable, as explained in #284 that would be a massive amount of work and would likely cause large amounts of partially duplicated code, or performance degradation, or both.

You can however achieve this behaviour with custom validators with pre=True.

I'll add a section to the docs explaining that pydantic is a parsing library not a validation library and therefore makes promises about the form of output models, not the input data. I'll also remove references to validation which could be argued to be inaccurate.

But

I apologize...

Thanks a lot for this, admitting ones mistakes is never easy and your humility is much appreciated.

This still open bug makes this entire library not usable IMO. Defaulting to crazy magic type corrosion is a terrible idea. @samuelcolvin

Coercion in some places such as JSON types to Python sets, tuples, etc makes a lot of sense and greatly eases quite a bit of programming. Not coercing standard python allowed types would make things quite a bit more complex. As mentioned, this is quite easy to do yourself:

from pydantic import BaseModel

class StrictInt(int):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if isinstance(v, float):
            raise TypeError("Will not coerce float to int")
        return v

class Model(BaseModel):
    v: StrictInt

print(Model(v=5))
print(Model(v=5.0))

The validator can be extended to allow 5.0 but not 5.1 for example based on tolerances. As a base library this is the functionality that you want.

@four43, thanks for your feedback. Perhaps this is "crazy magic", but it's pythonic crazy magic:

>>> int('123')
123

Please could you give a practical example of where this approach "makes this entire library not usable (sic)"?

I'd also really like to understand why you've given thumbs down to my "thanks" comment above seems fairly innocuous to me...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mgresko picture mgresko  路  3Comments

ashpreetbedi picture ashpreetbedi  路  3Comments

sommd picture sommd  路  3Comments

drpoggi picture drpoggi  路  3Comments

sbv-trueenergy picture sbv-trueenergy  路  3Comments