The main bug here is a _difference of validation behavior_ on different environments.
Linux behavior (docker container)
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
>>> import sys; print(sys.version)
3.6.8 (default, Jun 11 2019, 01:16:11)
[GCC 6.3.0 20170516]
>>> 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)
> 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
>>> 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)]
>>> 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)
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.
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)
looks like this was not changed on EmailStr:
https://github.com/samuelcolvin/pydantic/blob/e65d11240a6febcd569ad44a61e2374eb00b9ba6/pydantic/networks.py#L280-L282
PR welcome.
$ 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.