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

Optional fields do not generate correct defaults in Pydantic #22

Closed
calclavia opened this issue Sep 25, 2023 · 4 comments · Fixed by #23
Closed

Optional fields do not generate correct defaults in Pydantic #22

calclavia opened this issue Sep 25, 2023 · 4 comments · Fixed by #23

Comments

@calclavia
Copy link

calclavia commented Sep 25, 2023

Describe the bug
A clear and concise description of what the bug is.
Using proto v3

Marking a field as optional in Proto doesn't seem to change anything in the generated Pydantic model.

To Reproduce
.proto

syntax = "proto3";

message A {
    string a = 1;
}
message B {
    optional A a = 1;
}

Output:

class A(BaseModel):
    a: str = Field(default="")

class B(BaseModel):
    a: typing.Optional[A] = Field()

Expected behavior
This is the expected output:

class A(BaseModel):
    a: str = Field(default="")


class B(BaseModel):
    a: typing.Optional[A] = Field(default=None)

Note that without setting default = None in Pydantic, it's impossible to construct B() with no args. You have to construct it via B(a=None).

@calclavia calclavia changed the title Optional field does not work. Optional fields do not generate correct defaults in Pydantic Sep 25, 2023
@so1n
Copy link
Owner

so1n commented Sep 26, 2023

Thanks for the feedback, I will fix this in version 0.2.0.1.

so1n added a commit that referenced this issue Sep 26, 2023
@so1n so1n linked a pull request Sep 26, 2023 that will close this issue
@so1n so1n closed this as completed in #23 Sep 26, 2023
so1n added a commit that referenced this issue Sep 26, 2023
…orrect-defaults-in-pydantic

Modify, Fix, fix #22
@calclavia
Copy link
Author

calclavia commented Sep 26, 2023

@so1n There's another bug created that's caused by the fix.

For fields such as:

repeated string a = 1;

It now generates this:

a: typing.Optional[typing.List[str]] = Field(default_factory=list, default=None)

which is not allowed in Pydantic. You cannot have default_factory and a default.

@so1n
Copy link
Owner

so1n commented Sep 27, 2023

@so1n There's another bug created that's caused by the fix.

For fields such as:

repeated string a = 1;

It now generates this:

a: typing.Optional[typing.List[str]] = Field(default_factory=list, default=None)

which is not allowed in Pydantic. You cannot have default_factory and a default.

Please provide the Protobuf file or Message, I can't reproduce the problem at the moment

@calclavia
Copy link
Author

calclavia commented Oct 1, 2023

@so1n Here it is:

syntax = "proto3";

message A {
    optional string a = 2;
    repeated string b = 3;
}

Output:

# This is an automatically generated file, please do not change
# gen by protobuf_to_pydantic[v0.2.0.1](https://github.com/so1n/protobuf_to_pydantic)
# Protobuf Version: 4.24.3
# Pydantic Version: 1.10.12
from google.protobuf.message import Message  # type: ignore
from pydantic import BaseModel
from pydantic import Field
import typing


class A(BaseModel):
    a: typing.Optional[str] = Field(default="")
    b: typing.Optional[typing.List[str]] = Field(default_factory=list, default=None)

It doesn't happen if you only have a single repeated field b.

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

Successfully merging a pull request may close this issue.

2 participants