Pydantic: Different `pydantic.constr()` validation behavior in different environments

Created on 3 Dec 2019  路  6Comments  路  Source: samuelcolvin/pydantic

Bug

The main bug here is a _difference of validation behavior_ on different environments.

observations

Linux behavior (docker container)

  • OS - docker run -it --rm python:3.6.8 /bin/sh:
# uname -a
Linux 20bcd240af44 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64 GNU/Linux
  • Python version
>>> import sys; print(sys.version)
3.6.8 (default, Jun 11 2019, 01:16:11) 
[GCC 6.3.0 20170516]
  • Pydantic version
>>> import pydantic; print(pydantic.VERSION)
1.2

The following behavior is observed in the environment shown above:

import pydantic

mytype = pydantic.constr()
value = "value"
mytype_value = mytype(value)

class Model(pydantic.BaseModel):
    attr: mytype

# this works
Model(attr=value)

# this causes a validation error, shown below
Model(attr=mytype_value)

The error:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "pydantic/main.py", line 274, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Model
attr
  Argument 'value' has incorrect type (expected str, got ConstrainedStrValue) (type=type_error)

Darwin behavior (laptop)

  • OS
> uname -a
Darwin username 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64
  • Python version
>>> import sys; print(sys.version)
3.6.8 (v3.6.8:3c6b436a57, Dec 24 2018, 02:04:31) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
  • Pydantic version
>>> import pydantic; print(pydantic.VERSION)
1.2

The following behavior is observed on my laptop:

import pydantic

mytype = pydantic.constr()
value = "value"
mytype_value = mytype(value)

class Model(pydantic.BaseModel):
    attr: mytype

# this works
Model(attr=value)

# this also works in this environment, unlike Linux / container environment
Model(attr=mytype_value)

discussion

The behavior on Darwin seems more expected because pydantic.constr() creates a new type (I confirmed that isinstance(mytype, type) == True in both environments) and, the same type is also used as the annotation, so I would expect to be able to use an instance of my type for the input argument.

bug duplicate

All 6 comments

This will be because pydantic is not compiled on macos, but is on linux.

Might related to #1060 and related issues.

sorry, misread, this is definitely the same as #1060.

@samuelcolvin
It seems a kind of this bug still remains on pydantic 1.3.

from pydantic import BaseModel, EmailStr

class Address(BaseModel):
    email: EmailStr

addr = Address(email=EmailStr('[email protected]'))

The code above works fine on MacOS, but this raises the ValidationError on Linux.

ValidationError: 1 validation error for Address
email
  Argument 'value' has incorrect type (expected str, got EmailStr) (type=type_error)
$ cd /usr/local/lib/python3.7/site-packages/pydantic
$ sudo mv networks.cpython-37m-x86_64-linux-gnu.so networks.cpython-37m-x86_64-linux-gnu.so.bak

On Linux, I removed the shared object, then the test code worked without raising ValidationError.
I don't know about the cython compilation...

You just need to switch to use a union as in the pr.

Was this page helpful?
0 / 5 - 0 ratings