-
Notifications
You must be signed in to change notification settings - Fork 14
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Summary
If you have a nested messages and pass ignore_unknown_fields=True, the recursive call to from_dict doesn't pass the ignore_unknown_fields flag.
Reproduction Steps
Given this proto file:
syntax = "proto3";
package betterproto.repro;
message Inner {
int32 val = 1;
}
message Outer {
Inner inner = 1;
}compiled with
uv run python -m grpc_tools.protoc --python_betterproto2_out generated/ -I. nested.protoThis code all works
from generated.betterproto.repro import Outer, Inner
# No unknown fields, works fine
print(Outer.from_dict({"inner": {"val": 42}}, ignore_unknown_fields=True))
# Unknown field in Outer class, ignore_unknown_fields is respected
print(Outer.from_dict({"inner": {"val": 42}, "foo": "bar"}, ignore_unknown_fields=True))
# Unknown field with Inner class, ignore_unknown_fields is respected
print(Inner.from_dict({"val": 42, "foo": "bar"}, ignore_unknown_fields=True))but this fails
# Unknown field in nested class, ignore_unknown_fields is ignored
print(Outer.from_dict({"inner": {"val": 42, "foo": "bar"}}, ignore_unknown_fields=True))
Expected Results
The code should print Outer(inner=Inner(val=42))
Actual Results
The code raises an exception with this traceback
Traceback (most recent call last):
File "/snip/nested_fail.py", line 13, in <module>
print(Outer.from_dict({"inner": {"val": 42, "foo": "bar"}}, ignore_unknown_fields=True))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/snip/.venv/lib/python3.12/site-packages/betterproto2/__init__.py", line 1197, in from_dict
return cls(**cls._from_dict_init(value, ignore_unknown_fields=ignore_unknown_fields)) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/snip/.venv/lib/python3.12/site-packages/betterproto2/__init__.py", line 1157, in _from_dict_init
value = _value_from_dict(value, meta, field_cls)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/snip/.venv/lib/python3.12/site-packages/betterproto2/__init__.py", line 613, in _value_from_dict
msg = msg_cls.from_dict(value)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/snip/.venv/lib/python3.12/site-packages/betterproto2/__init__.py", line 1197, in from_dict
return cls(**cls._from_dict_init(value, ignore_unknown_fields=ignore_unknown_fields)) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/snip/.venv/lib/python3.12/site-packages/betterproto2/__init__.py", line 1143, in _from_dict_init
raise KeyError(f"Unknown field '{field_name}' in message {cls.__name__}.") from None
KeyError: "Unknown field 'foo' in message Inner."You can see here
| msg = msg_cls.from_dict(value) |
that the recursive
msg_cls.from_dict(value) doesn't use the top-level arguments.
System Information
$ uv run python -m grpc_tools.protoc --version
libprotoc 31.1
$ uv run python --version
Python 3.12.11
$ uv pip show betterproto2
Name: betterproto2
Version: 0.9.0
Location: [snip]/.venv/lib/python3.12/site-packages
Requires: python-dateutil, typing-extensions
Required-by: betterproto2-compiler
$ uv pip show betterproto2_compiler
Name: betterproto2-compiler
Version: 0.9.0
Location: [snip]/.venv/lib/python3.12/site-packages
Requires: betterproto2, jinja2, ruff, typing-extensions
Required-by:
Checklist
- I have searched the issues for duplicates.
- I have shown the entire traceback, if possible.
- I have verified this issue occurs on the latest prelease of betterproto which can be installed using
pip install -U --pre betterproto, if possible.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working