Skip to content

Commit 5d73592

Browse files
Merge pull request #32 from piercefreeman/bug/fix-pydantic-setter-crash
Use settable __pydantic_fields__
2 parents 768f29a + 41ab4c0 commit 5d73592

File tree

3 files changed

+125
-102
lines changed

3 files changed

+125
-102
lines changed

iceaxe/base.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def __new__(
3434
mcs._cached_args[cls] = raw_kwargs
3535

3636
# If we have already set the class's fields, we should wrap them
37-
if hasattr(cls, "model_fields"):
38-
cls.model_fields = {
37+
if hasattr(cls, "__pydantic_fields__"):
38+
cls.__pydantic_fields__ = {
3939
field: info
4040
if isinstance(info, DBFieldInfo)
4141
else DBFieldInfo.extend_field(
@@ -98,6 +98,14 @@ def _extract_kwarg(cls, kwargs: dict[str, Any], key: str, default: Any = None):
9898

9999
return default
100100

101+
@property
102+
def model_fields(self) -> dict[str, DBFieldInfo]: # type: ignore
103+
# model_fields must be reimplemented in our custom metaclass, otherwise
104+
# clients will get the super typehinting signature when they try
105+
# to access Model.model_fields. This overrides the ClassVar typehint
106+
# that's placed in the TableBase itself.
107+
return super().model_fields # type: ignore
108+
101109

102110
class UniqueConstraint(BaseModel):
103111
columns: list[str]

iceaxe/field.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
P = ParamSpec("P")
2727

28+
_Unset: Any = PydanticUndefined
29+
2830

2931
class DBFieldInputs(_FieldInfoInputs, total=False):
3032
primary_key: bool
@@ -116,11 +118,16 @@ def func(
116118
index: bool = False,
117119
check_expression: str | None = None,
118120
is_json: bool = False,
119-
default: Any = PydanticUndefined,
121+
default: Any = _Unset,
122+
default_factory: (
123+
Callable[[], Any] | Callable[[dict[str, Any]], Any] | None
124+
) = _Unset,
120125
*args: P.args,
121126
**kwargs: P.kwargs,
122127
):
123-
raw_field = PydanticField(default=default, **kwargs) # type: ignore
128+
raw_field = PydanticField(
129+
default=default, default_factory=default_factory, **kwargs
130+
) # type: ignore
124131

125132
# The Any request is required for us to be able to assign fields to any
126133
# arbitrary type, like `value: str = Field()`

0 commit comments

Comments
 (0)