Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit cae5672

Browse files
thomasjiangcylovelydinosaur
authored andcommitted
UUID field (#63)
* added UUID_REGEX and UUIDFormat class * added UUIDFormat to fields.py * added tests * lint
1 parent 0429579 commit cae5672

5 files changed

Lines changed: 47 additions & 1 deletion

File tree

tests/test_fields.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
import decimal
33
import re
4+
import uuid
45

56
from typesystem.base import Message, ValidationError
67
from typesystem.fields import (
@@ -713,6 +714,16 @@ def test_datetime():
713714
assert error == ValidationError(text="Must be a real datetime.", code="invalid")
714715

715716

717+
def test_uuid():
718+
validator = String(format="uuid")
719+
value, error = validator.validate_or_error("93e19019-c7a6-45fe-8936-f6f4d550f35f")
720+
assert value == uuid.UUID("93e19019-c7a6-45fe-8936-f6f4d550f35f")
721+
722+
validator = String(format="uuid")
723+
value, error = validator.validate_or_error("1245a678-1234-1234-1234-123412341234")
724+
assert error == ValidationError(text="Must be valid UUID format.", code="format")
725+
726+
716727
def test_union():
717728
validator = Union(any_of=[Integer(), String()])
718729
value, error = validator.validate_or_error("abc")

tests/test_schemas.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import decimal
3+
import uuid
34

45
import pytest
56

@@ -171,6 +172,17 @@ class InventoryItem(typesystem.Schema):
171172
assert item["price"] == 123.45
172173

173174

175+
def test_schema_uuid_serialization():
176+
class User(typesystem.Schema):
177+
id = typesystem.String(format="uuid")
178+
username = typesystem.String()
179+
180+
item = User(id="b769df4a-18ec-480f-89ef-8ea961a82269", username="tom")
181+
182+
assert item.id == uuid.UUID("b769df4a-18ec-480f-89ef-8ea961a82269")
183+
assert item["id"] == "b769df4a-18ec-480f-89ef-8ea961a82269"
184+
185+
174186
def test_schema_with_callable_default():
175187
class Example(typesystem.Schema):
176188
created = typesystem.Date(default=datetime.date.today)

typesystem/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typesystem.base import ParseError, ValidationError, Message, Position
1+
from typesystem.base import Message, ParseError, Position, ValidationError
22
from typesystem.fields import (
33
Any,
44
Array,

typesystem/fields.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"date": formats.DateFormat(),
1414
"time": formats.TimeFormat(),
1515
"datetime": formats.DateTimeFormat(),
16+
"uuid": formats.UUIDFormat(),
1617
}
1718

1819

typesystem/formats.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
import re
33
import typing
4+
import uuid
45

56
from typesystem.base import ValidationError
67

@@ -18,6 +19,10 @@
1819
r"(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$"
1920
)
2021

22+
UUID_REGEX = re.compile(
23+
r"[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"
24+
)
25+
2126

2227
class BaseFormat:
2328
errors: typing.Dict[str, str] = {}
@@ -130,3 +135,20 @@ def validate(self, value: typing.Any) -> datetime.datetime:
130135
# if value.endswith('+00:00'):
131136
# value = value[:-6] + 'Z'
132137
# return value
138+
139+
140+
class UUIDFormat(BaseFormat):
141+
errors = {"format": "Must be valid UUID format."}
142+
143+
def is_native_type(self, value: typing.Any) -> bool:
144+
return isinstance(value, uuid.UUID)
145+
146+
def validate(self, value: typing.Any) -> uuid.UUID:
147+
match = UUID_REGEX.match(value)
148+
if not match:
149+
raise self.validation_error("format")
150+
151+
return uuid.UUID(value)
152+
153+
def serialize(self, obj: typing.Any) -> str:
154+
return str(obj)

0 commit comments

Comments
 (0)