Skip to content

Commit e6ff6ca

Browse files
committed
enable the usage of newtypes in annotations
1 parent 6f4c2ee commit e6ff6ca

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

sqlmodel/_compat.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,17 @@ def is_field_noneable(field: "FieldInfo") -> bool:
171171
return False
172172

173173

174+
def unwrap_newtype(tp: Any) -> Any:
175+
# returns wrapped type of newtype recursivly
176+
while hasattr(tp, "__supertype__"):
177+
tp = tp.__supertype__
178+
return tp
179+
174180
def get_sa_type_from_type_annotation(annotation: Any) -> Any:
175181
# Resolve Optional fields
176182
if annotation is None:
177183
raise ValueError("Missing field type")
184+
annotation = unwrap_newtype(annotation)
178185
origin = get_origin(annotation)
179186
if origin is None:
180187
return annotation

tests/test_field_newtype.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from typing import Annotated, NewType
2+
from uuid import UUID, uuid4
3+
4+
from sqlmodel import Field, SQLModel
5+
6+
7+
def test_field_is_newtype() -> None:
8+
NewId = NewType("NewId", UUID)
9+
10+
class Item(SQLModel, table=True):
11+
id: NewId = Field(default_factory=uuid4, primary_key=True)
12+
13+
item = Item()
14+
assert isinstance(item.id, UUID)
15+
16+
17+
def test_field_is_recursive_newtype() -> None:
18+
NewId1 = NewType("NewId1", int)
19+
NewId2 = NewType("NewId2", NewId1)
20+
NewId3 = NewType("NewId3", NewId2)
21+
22+
class Item(SQLModel, table=True):
23+
id: NewId3 = Field(primary_key=True)
24+
25+
item = Item(id=NewId3(NewId2(NewId1(3))))
26+
assert isinstance(item.id, int)
27+
assert item.id == 3, item.id
28+
29+
30+
def test_field_is_newtype_and_annotated() -> None:
31+
NewId = NewType("NewId", UUID)
32+
33+
class Item(SQLModel, table=True):
34+
id: Annotated[NewId, Field(primary_key=True)] = NewId(uuid4())
35+
36+
item = Item()
37+
assert isinstance(item.id, UUID)

0 commit comments

Comments
 (0)