Skip to content

Commit 8ab1b59

Browse files
committed
fix error on deal with UUID pgproto (asyncpg UUID)
1 parent 6b630bc commit 8ab1b59

File tree

6 files changed

+28
-6
lines changed

6 files changed

+28
-6
lines changed

datamodel/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ def _process_field_(
191191
field_category = self.__field_types__.get(name, 'complex')
192192
try:
193193
if field_category == 'primitive':
194+
print('AQUI > ', _type, value, type(value))
194195
# if value is not None:
195196
new_val = parse_basic(_type, value, _encoder)
196197
return self._validation_(name, new_val, f, _type)

datamodel/converters.pyx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ from cpython cimport datetime
1313
import pendulum
1414
from pendulum.parsing.exceptions import ParserError
1515
from uuid import UUID
16+
import asyncpg.pgproto.pgproto as pgproto
1617
from cpython.ref cimport PyObject
1718
from .functions import is_dataclass, is_iterable, is_primitive
1819

@@ -38,6 +39,9 @@ cdef str to_string(object obj):
3839
cdef object to_uuid(object obj):
3940
"""Returns a UUID version of a str column.
4041
"""
42+
if isinstance(obj, pgproto.UUID):
43+
# If it's asyncpg's UUID, convert by casting to string first
44+
return UUID(str(obj))
4145
if isinstance(obj, UUID):
4246
# already an uuid
4347
return obj
@@ -333,6 +337,7 @@ cpdef object register_converter(object _type, object converter_func):
333337
cdef dict encoders = {
334338
str: to_string,
335339
UUID: to_uuid,
340+
pgproto.UUID: to_uuid,
336341
bool: to_boolean,
337342
int: to_integer,
338343
float: to_float,
@@ -568,11 +573,12 @@ cpdef object parse_basic(object T, object data, object encoder = None):
568573
Parse a value to primitive types as str or int.
569574
--- (int, float, str, bool, bytes)
570575
"""
576+
if T == UUID or T == pgproto.UUID:
577+
return to_uuid(data)
571578
if T == str:
572579
return str(data)
573-
elif T == bytes:
580+
if T == bytes:
574581
return bytes(data)
575-
576582
# Using the encoders for basic types:
577583
try:
578584
return encoders[T](data)

datamodel/functions.pyx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ from typing import get_args, get_origin, Union, Optional
55
from collections.abc import Iterable
66
from libcpp cimport bool as bool_t
77
from uuid import UUID
8+
import asyncpg.pgproto.pgproto as pgproto
89
from decimal import Decimal
910
import datetime
1011
import types
@@ -26,6 +27,7 @@ cpdef bool_t is_primitive(object value):
2627
float,
2728
str,
2829
UUID,
30+
pgproto.UUID,
2931
Decimal,
3032
bool,
3133
bytes,

datamodel/validation.pyx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ from libcpp cimport bool as bool_t
88
from enum import Enum
99
import pendulum
1010
import datetime
11+
import asyncpg.pgproto.pgproto as pgproto
1112
from .types import uint64_min, uint64_max, Text
1213
from .abstract import ModelMeta
14+
from uuid import UUID
1315
from .fields import Field
1416
from .functions import (
1517
is_iterable,
@@ -122,6 +124,11 @@ cpdef list _validation(object F, str name, object value, object annotated_type,
122124
errors.append(
123125
_create_error(name, value, error_msg, val_type, annotated_type)
124126
)
127+
elif annotated_type is UUID:
128+
if not isinstance(value, (UUID, pgproto.UUID)):
129+
errors.append(
130+
_create_error(name, value, f'invalid type for {annotated_type}.{name}, expected {annotated_type}', val_type, annotated_type)
131+
)
125132
elif val_type != annotated_type:
126133
instance = is_instanceof(value, annotated_type)
127134
if not instance:

datamodel/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
__title__ = 'python-datamodel'
55
__description__ = ('simple library based on python +3.8 to use Dataclass-syntax'
66
'for interacting with Data')
7-
__version__ = '0.8.1'
7+
__version__ = '0.8.2'
88
__author__ = 'Jesus Lara'
99
__author_email__ = '[email protected]'
1010
__license__ = 'BSD'

examples/basic.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import uuid
22
from typing import Union, List, Optional
33
from dataclasses import dataclass, fields, is_dataclass, field
4+
import asyncpg.pgproto.pgproto as pgproto
45
import orjson
56
from datamodel import Field, BaseModel, Column
7+
from datamodel.exceptions import ValidationError
68

79

810
def auto_uid():
@@ -68,7 +70,7 @@ def valid_zipcode(field, value):
6870
return value == 45510
6971

7072
class Address(BaseModel):
71-
id: uuid.UUID = field(default_factory=auto_uid)
73+
id: uuid.UUID = Field(default_factory=auto_uid)
7274
street: str = Field(required=True)
7375
number: str = Field(factory=default_number)
7476
zipcode: int = Field(required=False, default=1010, validator=valid_zipcode)
@@ -132,6 +134,7 @@ def __str__(self) -> str:
132134

133135

134136
user = {
137+
"userid": pgproto.UUID('f47ac10b-58cc-4372-a567-0e02b2c3d479'),
135138
"name": "Jesus Lara",
136139
"account": [
137140
{
@@ -148,5 +151,8 @@ def __str__(self) -> str:
148151
}
149152
]
150153
}
151-
user = Actor(**user)
152-
print(user)
154+
try:
155+
user = Actor(**user)
156+
print(user)
157+
except ValidationError as e:
158+
print(e.payload)

0 commit comments

Comments
 (0)