Skip to content

Commit

Permalink
fixing issue with inhereted defaults (#673)
Browse files Browse the repository at this point in the history
* fixing issue with inhereted defaults
  • Loading branch information
slorello89 authored Jan 14, 2025
1 parent d0e3a68 commit 758d9c7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
strategy:
matrix:
os: [ ubuntu-latest ]
pyver: [ "3.8", "3.9", "3.10", "3.11", "3.12", "pypy-3.8", "pypy-3.9", "pypy-3.10" ]
pyver: [ "3.9", "3.10", "3.11", "3.12", "pypy-3.9", "pypy-3.10" ]
redisstack: [ "latest" ]
fail-fast: false
services:
Expand Down
17 changes: 16 additions & 1 deletion aredis_om/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,12 @@ def __new__(cls, name, bases, attrs, **kwargs): # noqa C901
meta = meta or getattr(new_class, "Meta", None)
base_meta = getattr(new_class, "_meta", None)

if len(bases) == 1:
for f_name in bases[0].model_fields:
field = bases[0].model_fields[f_name]
print(field)
new_class.model_fields[f_name] = field

if meta and meta != DefaultMeta and meta != base_meta:
new_class.Meta = meta
new_class._meta = meta
Expand Down Expand Up @@ -1455,7 +1461,16 @@ class Config:

def __init__(__pydantic_self__, **data: Any) -> None:
__pydantic_self__.validate_primary_key()
super().__init__(**data)
missing_fields = __pydantic_self__.model_fields.keys() - data.keys() - {"pk"}

kwargs = data.copy()

# This is a hack, we need to manually make sure we are setting up defaults correctly when we encounter them
# because inheritance apparently won't cover that in pydantic 2.0.
for field in missing_fields:
default_value = __pydantic_self__.model_fields.get(field).default # type: ignore
kwargs[field] = default_value
super().__init__(**kwargs)

def __lt__(self, other):
"""Default sort: compare primary key of models."""
Expand Down
25 changes: 25 additions & 0 deletions tests/test_hash_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,3 +951,28 @@ class TestLiterals(HashModel):
await item.save()
rematerialized = await TestLiterals.find(TestLiterals.flavor == "pumpkin").first()
assert rematerialized.pk == item.pk


@py_test_mark_asyncio
async def test_child_class_expression_proxy():
# https://github.com/redis/redis-om-python/issues/669 seeing weird issue with child classes initalizing all their undefined members as ExpressionProxies
class Model(HashModel):
first_name: str
last_name: str
age: int = Field(default=18)
bio: Optional[str] = Field(default=None)

class Child(Model):
other_name: str
# is_new: bool = Field(default=True)

await Migrator().run()
m = Child(first_name="Steve", last_name="Lorello", other_name="foo")
await m.save()
print(m.age)
assert m.age == 18

rematerialized = await Child.find(Child.pk == m.pk).first()

assert rematerialized.age == 18
assert rematerialized.bio is None
26 changes: 25 additions & 1 deletion tests/test_json_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import pytest
import pytest_asyncio
from more_itertools.more import first

from aredis_om import (
EmbeddedJsonModel,
Expand Down Expand Up @@ -1159,7 +1160,29 @@ class TestLiterals(JsonModel):
assert rematerialized.pk == item.pk


@py_test_mark_asyncio
async def test_child_class_expression_proxy():
# https://github.com/redis/redis-om-python/issues/669 seeing weird issue with child classes initalizing all their undefined members as ExpressionProxies
class Model(JsonModel):
first_name: str
last_name: str
age: int = Field(default=18)
bio: Optional[str] = Field(default=None)

class Child(Model):
is_new: bool = Field(default=True)

await Migrator().run()
m = Child(first_name="Steve", last_name="Lorello")
await m.save()
print(m.age)
assert m.age == 18

rematerialized = await Child.find(Child.pk == m.pk).first()

assert rematerialized.age == 18
assert rematerialized.age != 19
assert rematerialized.bio is None

async def test_merged_model_error():
class Player(EmbeddedJsonModel):
username: str = Field(index=True)
Expand All @@ -1173,3 +1196,4 @@ class Game(JsonModel):
)
print(q.query)
assert q.query == "(@player1_username:{username})| (@player2_username:{username})"

0 comments on commit 758d9c7

Please sign in to comment.