|
31 | 31 | PYDANTIC_MINOR_VERSION = tuple(int(i) for i in P_VERSION.split(".")[:2]) |
32 | 32 | IS_PYDANTIC_V2 = PYDANTIC_MINOR_VERSION[0] == 2 |
33 | 33 |
|
34 | | - |
35 | 34 | if TYPE_CHECKING: |
36 | 35 | from .main import RelationshipInfo, SQLModel |
37 | 36 |
|
@@ -201,29 +200,43 @@ def is_field_noneable(field: "FieldInfo") -> bool: |
201 | 200 | return False |
202 | 201 | return False |
203 | 202 |
|
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 | | - |
| 203 | + def _is_typing_type_instance(annotation: Any, type_name: str) -> bool: |
209 | 204 | check_type = [] |
210 | | - if in_typing: |
211 | | - check_type.append(typing.TypeAliasType) |
212 | | - if in_typing_extensions: |
213 | | - check_type.append(typing_extensions.TypeAliasType) |
| 205 | + if hasattr(typing, type_name): |
| 206 | + check_type.append(getattr(typing, type_name)) |
| 207 | + if hasattr(typing_extensions, type_name): |
| 208 | + check_type.append(getattr(typing_extensions, type_name)) |
| 209 | + |
| 210 | + return check_type and isinstance(annotation, tuple(check_type)) |
| 211 | + |
| 212 | + def _is_new_type_instance(annotation: Any) -> bool: |
| 213 | + return _is_typing_type_instance(annotation, "NewType") |
214 | 214 |
|
| 215 | + def _is_type_var_instance(annotation: Any) -> bool: |
| 216 | + return _is_typing_type_instance(annotation, "TypeVar") |
| 217 | + |
| 218 | + def _is_type_alias_type_instance(annotation: Any) -> bool: |
215 | 219 | if sys.version_info[:2] == (3, 10): |
216 | 220 | if type(annotation) is types.GenericAlias: |
217 | | - # In Python 3.10, TypeAliasType instances are of type GenericAlias |
| 221 | + # In Python 3.10, GenericAlias instances are of type TypeAliasType |
218 | 222 | return False |
219 | 223 |
|
220 | | - return check_type and isinstance(annotation, tuple(check_type)) |
| 224 | + return _is_typing_type_instance(annotation, "TypeAliasType") |
221 | 225 |
|
222 | 226 | def get_sa_type_from_type_annotation(annotation: Any) -> Any: |
223 | 227 | # Resolve Optional fields |
224 | 228 | if annotation is None: |
225 | 229 | raise ValueError("Missing field type") |
226 | | - if _is_type_alias_type_instance(annotation): |
| 230 | + if _is_type_var_instance(annotation): |
| 231 | + annotation = annotation.__bound__ |
| 232 | + if not annotation: |
| 233 | + raise ValueError( |
| 234 | + "TypeVars without a bound type cannot be converted to SQLAlchemy types" |
| 235 | + ) |
| 236 | + # annotations.__constraints__ could be used and defined Union[*constraints], but ORM does not support it |
| 237 | + elif _is_new_type_instance(annotation): |
| 238 | + annotation = annotation.__supertype__ |
| 239 | + elif _is_type_alias_type_instance(annotation): |
227 | 240 | annotation = annotation.__value__ |
228 | 241 | origin = get_origin(annotation) |
229 | 242 | if origin is None: |
|
0 commit comments