Status: New
Owner: ken...@google.com
Labels: Type-Defect Priority-Medium

New issue 207 by kleptog: python: MergeFrom copies fields not actually present
http://code.google.com/p/protobuf/issues/detail?id=207

What steps will reproduce the problem?

1. Create the following protocol in test.proto

--- cut ---
message CompositeType {
    required int32 stamp = 1;
}

message Record {
    optional CompositeType type = 1;
}

message RecordSet {
    repeated Record set = 1;
}
--- cut ---

2. Compile using protoc to test_pb2.py

3. Execute the following python code (interactively if possible):

In [1]: from test_pb2 import *

In [2]: r1=Record()

In [3]: r2=Record()

In [4]: r1.type == r2.type
Out[4]: True

# Note how we can access the type field even though it's not present. It has been added to the _fields dict.

In [5]: r1._fields
Out[5]: {<google.protobuf.descriptor.FieldDescriptor object at 0x2d87350>: <test_pb2.CompositeType object at 0x2d7abb0>}

# But when you serialise the object, it doesn't appear, it's not really there.

In [6]: r1.SerializeToString()
Out[6]: ''

# But when you do a MergeFrom, it breaks on serialisation

In [7]: RecordSet(set=[r1,r2]).SerializeToString()
---------------------------------------------------------------------------
EncodeError                               Traceback (most recent call last)

/tmp/<ipython console> in <module>()

/home/kleptog/python/eggs/protobuf-2.3.0-py2.5.egg/google/protobuf/reflection.pyc in SerializeToString(self)
    794       raise message_mod.EncodeError(
    795           'Message is missing required fields: ' +
--> 796           ','.join(self.FindInitializationErrors()))
    797     return self.SerializePartialToString()
    798   cls.SerializeToString = SerializeToString

EncodeError: Message is missing required fields: set[0].type.stamp,set[1].type.stamp

# Note the empty structures after merging

In [8]: print RecordSet(set=[r1,r2])
set {
  type {
  }
}
set {
  type {
  }
}

# ListFields gives the right answer
In [9]: r1.ListFields()
Out[9]: []


What is the expected output? What do you see instead?

I expected to have the Record objects merged into the RecordSet with no content.

What version of the product are you using? On what operating system?

protobuf-2.3.0 on Python 2.5 on Debian 5.0

Please provide any additional information below.

I believe the problem to be the ListFields and __str__use _IsPresent method in reflection.py, whereas MergeFrom uses _fields directly.

The simple solution is: in _AddMergeFromMethod.MergeFunc replace the line:

    for field, value in msg._fields.iteritems():

with

    for field, value in msg.ListFields():



--
You received this message because you are subscribed to the Google Groups "Protocol 
Buffers" group.
To post to this group, send email to proto...@googlegroups.com.
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to