|
| 1 | +import sys |
1 | 2 | import types |
2 | 3 | from contextlib import contextmanager |
3 | 4 | from contextvars import ContextVar |
@@ -123,7 +124,20 @@ def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None: |
123 | 124 | object.__setattr__(new_object, "__pydantic_private__", None) |
124 | 125 |
|
125 | 126 | def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]: |
126 | | - return class_dict.get("__annotations__", {}) |
| 127 | + raw_annotations: Dict[str, Any] = class_dict.get("__annotations__", {}) |
| 128 | + if sys.version_info >= (3, 14) and "__annotations__" not in class_dict: |
| 129 | + # See https://github.com/pydantic/pydantic/pull/11991 |
| 130 | + from annotationlib import ( |
| 131 | + Format, |
| 132 | + call_annotate_function, |
| 133 | + get_annotate_from_class_namespace, |
| 134 | + ) |
| 135 | + |
| 136 | + if annotate := get_annotate_from_class_namespace(class_dict): |
| 137 | + raw_annotations = call_annotate_function( |
| 138 | + annotate, format=Format.FORWARDREF |
| 139 | + ) |
| 140 | + return raw_annotations |
127 | 141 |
|
128 | 142 | def is_table_model_class(cls: Type[Any]) -> bool: |
129 | 143 | config = getattr(cls, "model_config", {}) |
@@ -180,7 +194,7 @@ def is_field_noneable(field: "FieldInfo") -> bool: |
180 | 194 | if not field.is_required(): |
181 | 195 | if field.default is Undefined: |
182 | 196 | return False |
183 | | - if field.annotation is None or field.annotation is NoneType: # type: ignore[comparison-overlap] |
| 197 | + if field.annotation is None or field.annotation is NoneType: |
184 | 198 | return True |
185 | 199 | return False |
186 | 200 | return False |
@@ -509,7 +523,7 @@ def _calculate_keys( |
509 | 523 | keys -= update.keys() |
510 | 524 |
|
511 | 525 | if exclude: |
512 | | - keys -= {k for k, v in exclude.items() if ValueItems.is_true(v)} |
| 526 | + keys -= {str(k) for k, v in exclude.items() if ValueItems.is_true(v)} |
513 | 527 |
|
514 | 528 | return keys |
515 | 529 |
|
|
0 commit comments