Skip to content

Misclassification of message types as mappings when their name end with "Entry" #99

@SoptikHa2

Description

@SoptikHa2

Describe the bug
Current mapping detection seems to work by checking whether type name ends with "Entry". Whoever, an user could define a message with such name, which clashes.

// when used as a field, p2p thinks it is a mapping
message FooEntry {
  // ...
}

Note that it is fine in plugin mode (protoc --protobuf-to-pydantic_out), the problem only happens at runtime model generation (msg_to_pydantic_model).

I actually have a solution to the problem, and will submit a pull request shortly, if you would like to review it / merge it.

Dependencies

python version: sys.version_info(major=3, minor=11, micro=11, releaselevel='final', serial=0)
############# dependencies ############## 
   grpc:            Not Install
   pydantic:        2.10.4

########## Expand dependencies ########## 
    mypy-protobuf:   3.6.0
    toml:            0.10.2

########## Format dependencies ########## 
    autoflake:       Not Install
    black:           Not Install
    isort:           Not Install

Protobuf File Content

The following does not (in runtime) compile to pydantic succesfully, and crashes:

message FooEntry {
  string a = 1;
}

message Container {
  FooEntry foo = 1;
}
model = msg_to_pydantic_model(Container)
print(pydantic_model_to_py_code(model))

Expected output

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


class Container(BaseModel):
    foo: typing.List[FooEntry] = Field(default_factory=list)

Actual output

  File "/Users/.../Library/Caches/pypoetry/virtualenvs/...-py3.11/lib/python3.11/site-packages/protobuf_to_pydantic/gen_model.py", in _protobuf_field_type_is_type_message_handler
    field_dataclass.field_type = Dict[tuple(dict_type_param_list)]  # type: ignore
                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/.../.pyenv/versions/3.11.11/lib/python3.11/typing.py", line 379, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/.../.pyenv/versions/3.11.11/lib/python3.11/typing.py", line 1592, in __getitem__
    _check_generic(self, params, self._nparams)
  File "/Users/.../Library/Caches/pypoetry/virtualenvs/sf.../lib/python3.11/site-packages/typing_extensions.py", line 2947, in _check_generic
    raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments"
TypeError: Too few arguments for typing.Dict; actual 1, expected 2

(The error is different when the class has a few / many fields).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions