Address an issue with pydantic v2 models as Vars (#3396)

* Addresses an issue with pydantic v2 models as Vars

It looks like there's an issue with state vars
which are pydantic v2 models...  Here's a
reproducible test case:

```python
import reflex as rx
from pydantic import BaseModel
from reflex.utils.serializers import serializer

class User(BaseModel):
    has_image: bool = False

@serializer
def serialize_user(user: User) -> dict:
    return user.dict()

class State(rx.State):
    user: User = None

def index() -> rx.Component:
    return rx.container(
        rx.cond(State.user,
                rx.text(State.user.has_image),
                rx.text("No user"))
    )

app = rx.App()
app.add_page(index)
```

This app works only with pydantic <2 installed:

```bash
reflex-test $ reflex run
...
AttributeError: 'FieldInfo' object has no attribute 'outer_type_'
reflex-test $ pip install pydantic==1.10.15
─────────────────────────────────── Starting Reflex App ───────────────────────────────────
Compiling: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 13/13 0:00:00
─────────────────────────────────────── App Running ───────────────────────────────────────
App running at: http://localhost:3000
```

Looks like this is caused by `outer_type_` no
[longer existing][1] in pydantic v2.  I'm guessing
this was introduced back in [v0.4.6][2].

1: https://github.com/pydantic/pydantic/discussions/7217
2: 86526cba51

This change explicitly ignores pydantic v2 models in
`get_attribute_access_type`, rather than trying to treat
them as v1 models.

* ruff formatting

---------

Co-authored-by: Masen Furer <m_github@0x26.net>
This commit is contained in:
Elliot Kroo 2024-06-07 09:47:54 -07:00 committed by GitHub
parent 4e990d2716
commit 168501d58a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -215,7 +215,11 @@ def get_attribute_access_type(cls: GenericType, name: str) -> GenericType | None
attr = getattr(cls, name, None)
if hint := get_property_hint(attr):
return hint
if hasattr(cls, "__fields__") and name in cls.__fields__:
if (
hasattr(cls, "__fields__")
and name in cls.__fields__
and hasattr(cls.__fields__[name], "outer_type_")
):
# pydantic models
field = cls.__fields__[name]
type_ = field.outer_type_