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

Forward-compatible usage of Pydantic v1 #1950

Open
aaronsteers opened this issue May 7, 2024 · 0 comments
Open

Forward-compatible usage of Pydantic v1 #1950

aaronsteers opened this issue May 7, 2024 · 0 comments

Comments

@aaronsteers
Copy link

aaronsteers commented May 7, 2024

Is your feature request related to a problem? Please describe.

I love that this codegen tool exists! We currently rely on models generated with this library, but we need to support compatibility with both Pydantic v1 and v2. I'm struggling with how to do this.

Describe the solution you'd like

I'd like datamodel-code-generator to be able to generate "v1" Pydantic models, but in a way that also forwards-compatible with Pydantic 2.

This can be implemented with the following:

# We use Pydantic 1.x for backwards compatibility. We import it in a
# way that is also forwards compatible with Pydantic 2.x.
try:
    import pydantic.v1 as pydantic_v1
    # If this succeeds we are using Pydantic 2.x, and we import the backwards-compatible
    # version of BaseModel.
except ImportError:
    # In this case, we are using Pydantic 1.x and we import as usual.
    import pydantic as pydantic_v1

...

from pydantic_v1 import BaseModel, ...

...

Describe alternatives you've considered

I tried using a modified version of the above and then specifying an override base class of ..BaseModel_v1:

# We use Pydantic 1.x for backwards compatibility. We import it in a
# way that is also forwards compatible with Pydantic 2.x.
try:
    import pydantic.v1 import BaseModel as BaseModel_v1
    # If this succeeds we are using Pydantic 2.x, but we import the backwards-compatible
    # version of BaseModel.
except ImportError:
    # In this case, we are using Pydantic 1.x and we import as usual.
    import pydantic import BaseModel as BaseModel_v1

Any way I try implement the base class override, however, I still end up with an extra (and incorrect) import statement of BaseModel_v1. I tried the base class of BaseModel_v1, .BaseModel_v1, and ..BaseModel_v1.

Ideally, for this workaround to work, an override base class without a . in it would be expected to have already been imported, since its impossible to import a class without a module reference and so rather than import BaseModel_v1 being generated if I set base class of BaseModel_v1, that scenario would just skip an attempt to import.

The closest I could get was this invocation, using the above code in the header file:

  datamodel-codegen \
    --input "$ROOT_DIR/$YAML_DIR/$filename_wo_ext.yaml" \
    --output "$ROOT_DIR/$OUTPUT_DIR/$filename_wo_ext.py" \
    --use-title-as-name \
    --disable-timestamp \
    --input-file-type jsonschema \
    --output-model-type pydantic.BaseModel \
    --base-class "..BaseModel_v1" \
    --custom-file-header-path "protocol-models/python/generation-file-header.py" \
    --target-python-version 3.7

Additional context

WIP PR in downstream library here:

@aaronsteers aaronsteers changed the title Forwards-compatible usage of Python v1 Forward-compatible usage of Python v1 May 7, 2024
@aaronsteers aaronsteers changed the title Forward-compatible usage of Python v1 Forward-compatible usage of Pydantic v1 May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant