Pydantic: Data conversion feature

Created on 18 Mar 2020  路  1Comment  路  Source: samuelcolvin/pydantic

Question

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.4
            pydantic compiled: False
                 install path: D:\Python3\Lib\site-packages\pydantic
               python version: 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)]
                     platform: Windows-10-10.0.18362-SP0
     optional deps. installed: ['typing-extensions']

Is there a correct way to use data conversion feature, now I use it like this, but not very smart. I have tried reading the source code and doc but have no conclusion.

import pydantic

NotSet = type('NotSet', (object,), {})


def convert(value, value_type, default=NotSet):

    class Temp(pydantic.BaseModel):
        value: value_type

    try:
        return Temp(value=value).value
    except Exception as err:
        if default is NotSet:
            raise err
        else:
            return default


print(repr(convert('1', int, None)))
# 1
print(repr(convert('a', int, None)))
# None
print(convert('a', int))
# raise validation_error

question

Most helpful comment

Almost there, that would work, but this is cleaner and will be slightly more performant since parse_obj_as caches the models it creates:

from datetime import datetime
from typing import List, Union
import pydantic

NotSet = object()

def convert(value_type, value, default=NotSet):
    try:
        return pydantic.parse_obj_as(value_type, value)
    except Exception:
        if default is NotSet:
            raise
        else:
            return default

print(convert(int, '123', None))
#> 123
print(convert(int, 'xxx', None))
#> None
print(convert(List[Union[float, datetime]], ['2020-03-01T12:12:12', 321]))
#> [datetime.datetime(2020, 3, 1, 12, 12, 12), 321.0]

>All comments

Almost there, that would work, but this is cleaner and will be slightly more performant since parse_obj_as caches the models it creates:

from datetime import datetime
from typing import List, Union
import pydantic

NotSet = object()

def convert(value_type, value, default=NotSet):
    try:
        return pydantic.parse_obj_as(value_type, value)
    except Exception:
        if default is NotSet:
            raise
        else:
            return default

print(convert(int, '123', None))
#> 123
print(convert(int, 'xxx', None))
#> None
print(convert(List[Union[float, datetime]], ['2020-03-01T12:12:12', 321]))
#> [datetime.datetime(2020, 3, 1, 12, 12, 12), 321.0]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sommd picture sommd  路  3Comments

gangefors picture gangefors  路  3Comments

iwoloschin picture iwoloschin  路  3Comments

krzysieqq picture krzysieqq  路  3Comments

mgresko picture mgresko  路  3Comments