Skip to content

Commit f63ed55

Browse files
anandoleecopybara-github
authored andcommitted
Fix python proto_api to work with messages that required fields are not set.
Fix python proto_api to work with large messages for cpp extension (upb and pure python can not work with large messages which are larger than 2GB) PiperOrigin-RevId: 754120424
1 parent 84c5b63 commit f63ed55

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

python/google/protobuf/proto_api.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <Python.h>
44

5+
#include <climits>
56
#include <memory>
67
#include <string>
78

@@ -38,7 +39,7 @@ PythonMessageMutator::~PythonMessageMutator() {
3839
// check.
3940
if (!PyErr_Occurred() && owned_msg_ != nullptr) {
4041
std::string wire;
41-
message_->SerializeToString(&wire);
42+
message_->SerializePartialToString(&wire);
4243
PyObject* py_wire = PyBytes_FromStringAndSize(
4344
wire.data(), static_cast<Py_ssize_t>(wire.size()));
4445
PyObject* parse =
@@ -81,8 +82,14 @@ bool PythonConstMessagePointer::NotChanged() {
8182
return false;
8283
}
8384

85+
// Skip the check if too large. Parse won't work
86+
// for messages larger than 2 GB.
87+
if (message_->ByteSizeLong() > INT_MAX) {
88+
return true;
89+
}
90+
8491
PyObject* py_serialized_pb(
85-
PyObject_CallMethod(py_msg_, "SerializeToString", nullptr));
92+
PyObject_CallMethod(py_msg_, "SerializePartialToString", nullptr));
8693
if (py_serialized_pb == nullptr) {
8794
PyErr_Format(PyExc_ValueError, "Fail to serialize py_msg");
8895
return false;
@@ -99,19 +106,19 @@ bool PythonConstMessagePointer::NotChanged() {
99106
// serialize result may still diff between languages. So parse to
100107
// another c++ message for compare.
101108
std::unique_ptr<google::protobuf::Message> parsed_msg(owned_msg_->New());
102-
parsed_msg->ParseFromArray(data, static_cast<int>(len));
109+
parsed_msg->ParsePartialFromArray(data, static_cast<int>(len));
103110
std::string wire_other;
104111
google::protobuf::io::StringOutputStream stream_other(&wire_other);
105112
google::protobuf::io::CodedOutputStream output_other(&stream_other);
106113
output_other.SetSerializationDeterministic(true);
107-
parsed_msg->SerializeToCodedStream(&output_other);
114+
parsed_msg->SerializePartialToCodedStream(&output_other);
108115
output_other.Trim();
109116

110117
std::string wire;
111118
google::protobuf::io::StringOutputStream stream(&wire);
112119
google::protobuf::io::CodedOutputStream output(&stream);
113120
output.SetSerializationDeterministic(true);
114-
owned_msg_->SerializeToCodedStream(&output);
121+
owned_msg_->SerializePartialToCodedStream(&output);
115122
output.Trim();
116123

117124
if (wire == wire_other) {

python/google/protobuf/pyext/message_module.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase {
8585
return false;
8686
}
8787

88-
bool ok = output->ParseFromArray(
88+
bool ok = output->ParsePartialFromArray(
8989
reinterpret_cast<uint8_t*>(PyBytes_AS_STRING(pyfile_serialized)),
9090
PyBytes_GET_SIZE(pyfile_serialized));
9191
if (!ok) {
@@ -207,8 +207,8 @@ absl::StatusOr<google::protobuf::Message*> CreateNewMessage(PyObject* py_msg) {
207207
bool CopyToOwnedMsg(google::protobuf::Message** copy, const google::protobuf::Message& message) {
208208
*copy = message.New();
209209
std::string wire;
210-
message.SerializeToString(&wire);
211-
(*copy)->ParseFromArray(wire.data(), wire.size());
210+
message.SerializePartialToString(&wire);
211+
(*copy)->ParsePartialFromArray(wire.data(), wire.size());
212212
return true;
213213
}
214214

@@ -245,7 +245,7 @@ struct ApiImplementation : google::protobuf::python::PyProto_API {
245245
auto msg = CreateNewMessage(py_msg);
246246
RETURN_IF_ERROR(msg.status());
247247
PyObject* serialized_pb(
248-
PyObject_CallMethod(py_msg, "SerializeToString", nullptr));
248+
PyObject_CallMethod(py_msg, "SerializePartialToString", nullptr));
249249
if (serialized_pb == nullptr) {
250250
return absl::InternalError("Fail to serialize py_msg");
251251
}
@@ -256,7 +256,7 @@ struct ApiImplementation : google::protobuf::python::PyProto_API {
256256
return absl::InternalError(
257257
"Fail to get bytes from py_msg serialized data");
258258
}
259-
if (!(*msg)->ParseFromArray(data, len)) {
259+
if (!(*msg)->ParsePartialFromArray(data, len)) {
260260
Py_DECREF(serialized_pb);
261261
return absl::InternalError(
262262
"Couldn't parse py_message to google::protobuf::Message*!");

0 commit comments

Comments
 (0)