Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeAdapter defer_build not working as expected #8716

Closed
1 task done
commonism opened this issue Feb 2, 2024 · 7 comments
Closed
1 task done

TypeAdapter defer_build not working as expected #8716

commonism opened this issue Feb 2, 2024 · 7 comments
Labels
awaiting author response awaiting response from issue opener bug V2 Bug related to Pydantic V2

Comments

@commonism
Copy link
Contributor

commonism commented Feb 2, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

I'm with the client side of OpenAPI, create models dynamically using create_model after parsing a OpenAPI description document.
Creating models dynamically requires delayed initialization, which works fine for BaseModel/RootModel.

Using TypeAdapter delayed initialization does not work.
I was hoping to skip a RootModels .root reference (for nullable objects) when using the TypeAdapter instead.

Example Code

import logging
from typing import ForwardRef, Optional, List

from pydantic import BaseModel, RootModel, TypeAdapter, ConfigDict, create_model

PYC = ConfigDict(defer_build=True, arbitrary_types_allowed=True)

class A_(BaseModel):
    model_config = PYC
    a: str

class B_(BaseModel):
    model_config = PYC
    la: List[ForwardRef('__types["A"]')]

types = {"__types":{"A":A_, "B":B_}}
A_.model_rebuild(_types_namespace=types)
B_.model_rebuild(_types_namespace=types)

E = create_model("E", __base__=(RootModel[Optional[ForwardRef("__types['A']")]],), __module__="debugging")
E.model_rebuild(_types_namespace=types)

# edit - this is what I want to do with the TypeAdapter instead
# assert E.model_validate(None).root is None

# we fail here
try:
  D = TypeAdapter(Optional[ForwardRef("__types['A']")], config=PYC)
except Exception as e:
    logging.exception(e)

Python, Pydantic & OS Version

pydantic version: 2.6.0
        pydantic-core version: 2.16.1
          pydantic-core build: profile=release pgo=true
                 install path: ~/venv/lib/python3.10/site-packages/pydantic
               python version: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
                     platform: Linux-6.5.0-14-generic-x86_64-with-glibc2.35
             related packages: mypy-1.5.1
@commonism commonism added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Feb 2, 2024
commonism added a commit to commonism/aiopenapi3 that referenced this issue Feb 3, 2024
TypeAdapter can not be used in nested schemas and does not work with
delayed initialization/defer_build
pydantic/pydantic#8716
commonism added a commit to commonism/aiopenapi3 that referenced this issue Feb 3, 2024
TypeAdapter can not be used in nested schemas and does not work with
delayed initialization/defer_build
pydantic/pydantic#8716
@sydney-runkle
Copy link
Member

@commonism,

Thanks for reporting this. Indeed, this looks like a bug. I suspect that a fix for this issue might look like that which I've implemented here for a similar issue: #7736.

Any interest in opening a PR with a fix?

@sydney-runkle sydney-runkle removed the pending Awaiting a response / confirmation label Feb 6, 2024
@sydney-runkle
Copy link
Member

@commonism,

Hmm. After thinking about this more - TypeAdapters don't have a model_rebuild method or close equivalent, so I'm curious what you expected to happen here. I think this can more accurately be categorized as a feature request...

@sydney-runkle sydney-runkle added the awaiting author response awaiting response from issue opener label Feb 6, 2024
@commonism
Copy link
Contributor Author

I think we both initially expected this to work.
Not being able to embed TypeAdapters in Models limit my interest in this feature anyway.
Therefore I'm fine with not taking care of this, but would be great if TypeAdapter could raise something when getting ConfigDict parameters not supported.
Breaking the expectation early.

@adriangb
Copy link
Member

adriangb commented Feb 6, 2024

TypeAdapter was never meant to be a field of a model. You’re supposed to just use the model, or a generic, for that.

I’m also confused by the __types thing. In particular I feel like there shouldn’t be a __types key. Like your forward ref should just be ”A” and namespace should be {“A”: A_}

@adriangb
Copy link
Member

adriangb commented Feb 6, 2024

Also, we could add a types_namespace argument to TypeAdapter pretty easily, does that solve it?

@commonism
Copy link
Contributor Author

I'd need TypeAdapter to behave "as models" basically as container for generics, which is not intended use.
I think I'm not a customer for TypeAdapter due to the limitations wrt. use as Field / missing "model_build" equivalent for deferred build and will be better of not trying to force it to be something it is/was not intended to be and use models/generics instead.

Using __types prevents name lookup collisions/confusion during construction.

@sydney-runkle
Copy link
Member

@commonism,

Given that, I think we can mark this issue as not planned, given that the features you're requesting are supported for BaseModel types.

Thanks for your feedback. Happy coding!

@sydney-runkle sydney-runkle closed this as not planned Won't fix, can't repro, duplicate, stale Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting author response awaiting response from issue opener bug V2 Bug related to Pydantic V2
Projects
None yet
Development

No branches or pull requests

3 participants