|
55 | 55 |
|
56 | 56 | import google.protobuf.wrappers_pb2 |
57 | 57 | import proto |
| 58 | +from google.protobuf import message |
58 | 59 |
|
59 | 60 | from apache_beam.coders import coder_impl |
60 | 61 | from apache_beam.coders.avro_record import AvroRecord |
|
65 | 66 | from apache_beam.utils import proto_utils |
66 | 67 |
|
67 | 68 | if TYPE_CHECKING: |
68 | | - from google.protobuf import message # pylint: disable=ungrouped-imports |
69 | 69 | from apache_beam.coders.typecoders import CoderRegistry |
70 | 70 | from apache_beam.runners.pipeline_context import PipelineContext |
71 | 71 |
|
@@ -1039,11 +1039,18 @@ def __hash__(self): |
1039 | 1039 |
|
1040 | 1040 | @classmethod |
1041 | 1041 | def from_type_hint(cls, typehint, unused_registry): |
1042 | | - if issubclass(typehint, proto_utils.message_types): |
| 1042 | + # The typehint must be a strict subclass of google.protobuf.message.Message. |
| 1043 | + # ProtoCoder cannot work with message.Message itself, as deserialization of |
| 1044 | + # a serialized proto requires knowledge of the desired concrete proto |
| 1045 | + # subclass which is not stored in the encoded bytes themselves. If this |
| 1046 | + # occurs, an error is raised and the system defaults to other fallback |
| 1047 | + # coders. |
| 1048 | + if (issubclass(typehint, proto_utils.message_types) and |
| 1049 | + typehint != message.Message): |
1043 | 1050 | return cls(typehint) |
1044 | 1051 | else: |
1045 | 1052 | raise ValueError(( |
1046 | | - 'Expected a subclass of google.protobuf.message.Message' |
| 1053 | + 'Expected a strict subclass of google.protobuf.message.Message' |
1047 | 1054 | ', but got a %s' % typehint)) |
1048 | 1055 |
|
1049 | 1056 | def to_type_hint(self): |
|
0 commit comments