Skip to content

Commit 69a2b21

Browse files
committed
📝 Enhance type alias handling in compatibility module and tests for Python 3.12
1 parent 5954463 commit 69a2b21

File tree

2 files changed

+98
-31
lines changed

2 files changed

+98
-31
lines changed

‎sqlmodel/_compat.py‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import types
3+
import typing
34
from contextlib import contextmanager
45
from contextvars import ContextVar
56
from dataclasses import dataclass
@@ -19,6 +20,7 @@
1920
Union,
2021
)
2122

23+
import typing_extensions
2224
from pydantic import VERSION as P_VERSION
2325
from pydantic import BaseModel
2426
from pydantic.fields import FieldInfo
@@ -74,9 +76,6 @@ def partial_init() -> Generator[None, None, None]:
7476

7577

7678
if IS_PYDANTIC_V2:
77-
if sys.version_info >= (3, 12):
78-
from typing import TypeAliasType
79-
8079
from annotated_types import MaxLen
8180
from pydantic import ConfigDict as BaseConfig
8281
from pydantic._internal._fields import PydanticMetadata
@@ -202,11 +201,24 @@ def is_field_noneable(field: "FieldInfo") -> bool:
202201
return False
203202
return False
204203

204+
def _is_type_alias_type_instance(annotation: Any) -> bool:
205+
type_to_check = "TypeAliasType"
206+
in_typing = hasattr(typing, type_to_check)
207+
in_typing_extensions = hasattr(typing_extensions, type_to_check)
208+
209+
check_type = []
210+
if in_typing:
211+
check_type.append(typing.TypeAliasType)
212+
if in_typing_extensions:
213+
check_type.append(typing_extensions.TypeAliasType)
214+
215+
return check_type and isinstance(annotation, tuple(check_type))
216+
205217
def get_sa_type_from_type_annotation(annotation: Any) -> Any:
206218
# Resolve Optional fields
207219
if annotation is None:
208220
raise ValueError("Missing field type")
209-
if sys.version_info >= (3, 12) and isinstance(annotation, TypeAliasType):
221+
if _is_type_alias_type_instance(annotation):
210222
annotation = annotation.__value__
211223
origin = get_origin(annotation)
212224
if origin is None:
Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,118 @@
1-
import sys
2-
from typing import Annotated, TypeAlias
1+
import typing as t
32

3+
import typing_extensions as te
44
from sqlmodel import Field, SQLModel
55

66
from tests.conftest import needs_py312
77

88

99
@needs_py312
10-
def test_sa_type_1() -> None:
11-
Type1 = str
10+
def test_sa_type_typing_1() -> None:
11+
Type1_t = str
1212

1313
class Hero1(SQLModel, table=True):
1414
pk: int = Field(primary_key=True)
15-
weapon: Type1 = "sword"
15+
weapon: Type1_t = "sword"
1616

1717

1818
@needs_py312
19-
def test_sa_type_2() -> None:
20-
Type2 = Annotated[str, "Just a comment"]
19+
def test_sa_type_typing_2() -> None:
20+
Type2_t = t.Annotated[str, "Just a comment"]
2121

2222
class Hero(SQLModel, table=True):
2323
pk: int = Field(primary_key=True)
24-
weapon: Type2 = "sword"
24+
weapon: Type2_t = "sword"
2525

2626

27-
Type3: TypeAlias = str
27+
Type3_t: t.TypeAlias = str
2828

2929

3030
@needs_py312
31-
def test_sa_type_3() -> None:
31+
def test_sa_type_typing_3() -> None:
3232
class Hero(SQLModel, table=True):
3333
pk: int = Field(primary_key=True)
34-
weapon: Type3 = "sword"
34+
weapon: Type3_t = "sword"
3535

3636

37-
Type4: TypeAlias = Annotated[str, "Just a comment"]
37+
Type4_t: t.TypeAlias = t.Annotated[str, "Just a comment"]
3838

3939

4040
@needs_py312
41-
def test_sa_type_4() -> None:
41+
def test_sa_type_typing_4() -> None:
4242
class Hero(SQLModel, table=True):
4343
pk: int = Field(primary_key=True)
44-
weapon: Type4 = "sword"
44+
weapon: Type4_t = "sword"
4545

4646

47-
if sys.version_info >= (3, 12):
47+
@needs_py312
48+
def test_sa_type_typing_5() -> None:
49+
type Type5_t = str
50+
51+
class Hero(SQLModel, table=True):
52+
pk: int = Field(primary_key=True)
53+
weapon: Type5_t = "sword"
54+
55+
56+
@needs_py312
57+
def test_sa_type_typing_6() -> None:
58+
type Type6_t = t.Annotated[str, "Just a comment"]
59+
60+
class Hero(SQLModel, table=True):
61+
pk: int = Field(primary_key=True)
62+
weapon: Type6_t = "sword"
63+
64+
65+
@needs_py312
66+
def test_sa_type_typing_extensions_1() -> None:
67+
Type1_te = str
68+
69+
class Hero1(SQLModel, table=True):
70+
pk: int = Field(primary_key=True)
71+
weapon: Type1_te = "sword"
72+
73+
74+
@needs_py312
75+
def test_sa_type_typing_extensions_2() -> None:
76+
Type2_te = te.Annotated[str, "Just a comment"]
77+
78+
class Hero(SQLModel, table=True):
79+
pk: int = Field(primary_key=True)
80+
weapon: Type2_te = "sword"
4881

49-
@needs_py312
50-
def test_sa_type_5() -> None:
51-
type Type5 = str
5282

53-
class Hero(SQLModel, table=True):
54-
pk: int = Field(primary_key=True)
55-
weapon: Type5 = "sword"
83+
Type3_te: te.TypeAlias = str
5684

57-
@needs_py312
58-
def test_sa_type_6() -> None:
59-
type Type6 = Annotated[str, "Just a comment"]
6085

61-
class Hero(SQLModel, table=True):
62-
pk: int = Field(primary_key=True)
63-
weapon: Type6 = "sword"
86+
@needs_py312
87+
def test_sa_type_typing_extensions_3() -> None:
88+
class Hero(SQLModel, table=True):
89+
pk: int = Field(primary_key=True)
90+
weapon: Type3_te = "sword"
91+
92+
93+
Type4_te: te.TypeAlias = te.Annotated[str, "Just a comment"]
94+
95+
96+
@needs_py312
97+
def test_sa_type_typing_extensions_4() -> None:
98+
class Hero(SQLModel, table=True):
99+
pk: int = Field(primary_key=True)
100+
weapon: Type4_te = "sword"
101+
102+
103+
@needs_py312
104+
def test_sa_type_typing_extensions_5() -> None:
105+
type Type5_te = str
106+
107+
class Hero(SQLModel, table=True):
108+
pk: int = Field(primary_key=True)
109+
weapon: Type5_te = "sword"
110+
111+
112+
@needs_py312
113+
def test_sa_type_typing_extensions_6() -> None:
114+
type Type6_te = te.Annotated[str, "Just a comment"]
115+
116+
class Hero(SQLModel, table=True):
117+
pk: int = Field(primary_key=True)
118+
weapon: Type6_te = "sword"

0 commit comments

Comments
 (0)