protobuf/python/google/protobuf/internal/extension_dict.py
Go to the documentation of this file.
1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved.
3 # https://developers.google.com/protocol-buffers/
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 """Contains _ExtensionDict class to represent extensions.
32 """
33 
34 from google.protobuf.internal import type_checkers
35 from google.protobuf.descriptor import FieldDescriptor
36 
37 
38 def _VerifyExtensionHandle(message, extension_handle):
39  """Verify that the given extension handle is valid."""
40 
41  if not isinstance(extension_handle, FieldDescriptor):
42  raise KeyError('HasExtension() expects an extension handle, got: %s' %
43  extension_handle)
44 
45  if not extension_handle.is_extension:
46  raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
47 
48  if not extension_handle.containing_type:
49  raise KeyError('"%s" is missing a containing_type.'
50  % extension_handle.full_name)
51 
52  if extension_handle.containing_type is not message.DESCRIPTOR:
53  raise KeyError('Extension "%s" extends message type "%s", but this '
54  'message is of type "%s".' %
55  (extension_handle.full_name,
56  extension_handle.containing_type.full_name,
57  message.DESCRIPTOR.full_name))
58 
59 
60 # TODO(robinson): Unify error handling of "unknown extension" crap.
61 # TODO(robinson): Support iteritems()-style iteration over all
62 # extensions with the "has" bits turned on?
63 class _ExtensionDict(object):
64 
65  """Dict-like container for Extension fields on proto instances.
66 
67  Note that in all cases we expect extension handles to be
68  FieldDescriptors.
69  """
70 
71  def __init__(self, extended_message):
72  """
73  Args:
74  extended_message: Message instance for which we are the Extensions dict.
75  """
76  self._extended_message = extended_message
77 
78  def __getitem__(self, extension_handle):
79  """Returns the current value of the given extension handle."""
80 
81  _VerifyExtensionHandle(self._extended_message, extension_handle)
82 
83  result = self._extended_message._fields.get(extension_handle)
84  if result is not None:
85  return result
86 
87  if extension_handle.label == FieldDescriptor.LABEL_REPEATED:
88  result = extension_handle._default_constructor(self._extended_message)
89  elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
90  message_type = extension_handle.message_type
91  if not hasattr(message_type, '_concrete_class'):
92  # pylint: disable=protected-access
93  self._extended_message._FACTORY.GetPrototype(message_type)
94  assert getattr(extension_handle.message_type, '_concrete_class', None), (
95  'Uninitialized concrete class found for field %r (message type %r)'
96  % (extension_handle.full_name,
97  extension_handle.message_type.full_name))
98  result = extension_handle.message_type._concrete_class()
99  try:
100  result._SetListener(self._extended_message._listener_for_children)
101  except ReferenceError:
102  pass
103  else:
104  # Singular scalar -- just return the default without inserting into the
105  # dict.
106  return extension_handle.default_value
107 
108  # Atomically check if another thread has preempted us and, if not, swap
109  # in the new object we just created. If someone has preempted us, we
110  # take that object and discard ours.
111  # WARNING: We are relying on setdefault() being atomic. This is true
112  # in CPython but we haven't investigated others. This warning appears
113  # in several other locations in this file.
114  result = self._extended_message._fields.setdefault(
115  extension_handle, result)
116 
117  return result
118 
119  def __eq__(self, other):
120  if not isinstance(other, self.__class__):
121  return False
122 
123  my_fields = self._extended_message.ListFields()
124  other_fields = other._extended_message.ListFields()
125 
126  # Get rid of non-extension fields.
127  my_fields = [field for field in my_fields if field.is_extension]
128  other_fields = [field for field in other_fields if field.is_extension]
129 
130  return my_fields == other_fields
131 
132  def __ne__(self, other):
133  return not self == other
134 
135  def __len__(self):
136  fields = self._extended_message.ListFields()
137  # Get rid of non-extension fields.
138  extension_fields = [field for field in fields if field[0].is_extension]
139  return len(extension_fields)
140 
141  def __hash__(self):
142  raise TypeError('unhashable object')
143 
144  # Note that this is only meaningful for non-repeated, scalar extension
145  # fields. Note also that we may have to call _Modified() when we do
146  # successfully set a field this way, to set any necessary "has" bits in the
147  # ancestors of the extended message.
148  def __setitem__(self, extension_handle, value):
149  """If extension_handle specifies a non-repeated, scalar extension
150  field, sets the value of that field.
151  """
152 
153  _VerifyExtensionHandle(self._extended_message, extension_handle)
154 
155  if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or
156  extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE):
157  raise TypeError(
158  'Cannot assign to extension "%s" because it is a repeated or '
159  'composite type.' % extension_handle.full_name)
160 
161  # It's slightly wasteful to lookup the type checker each time,
162  # but we expect this to be a vanishingly uncommon case anyway.
163  type_checker = type_checkers.GetTypeChecker(extension_handle)
164  # pylint: disable=protected-access
165  self._extended_message._fields[extension_handle] = (
166  type_checker.CheckValue(value))
168 
169  def __delitem__(self, extension_handle):
170  self._extended_message.ClearExtension(extension_handle)
171 
172  def _FindExtensionByName(self, name):
173  """Tries to find a known extension with the specified name.
174 
175  Args:
176  name: Extension full name.
177 
178  Returns:
179  Extension field descriptor.
180  """
181  return self._extended_message._extensions_by_name.get(name, None)
182 
183  def _FindExtensionByNumber(self, number):
184  """Tries to find a known extension with the field number.
185 
186  Args:
187  number: Extension field number.
188 
189  Returns:
190  Extension field descriptor.
191  """
192  return self._extended_message._extensions_by_number.get(number, None)
193 
194  def __iter__(self):
195  # Return a generator over the populated extension fields
196  return (f[0] for f in self._extended_message.ListFields()
197  if f[0].is_extension)
198 
199  def __contains__(self, extension_handle):
200  _VerifyExtensionHandle(self._extended_message, extension_handle)
201 
202  if extension_handle not in self._extended_message._fields:
203  return False
204 
205  if extension_handle.label == FieldDescriptor.LABEL_REPEATED:
206  return bool(self._extended_message._fields.get(extension_handle))
207 
208  if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
209  value = self._extended_message._fields.get(extension_handle)
210  # pylint: disable=protected-access
211  return value is not None and value._is_present_in_parent
212 
213  return True
google::protobuf.internal.python_message._ExtensionDict
_ExtensionDict
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:78
google::protobuf.internal.extension_dict._ExtensionDict.__init__
def __init__(self, extended_message)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:71
google::protobuf.descriptor
Definition: bloaty/third_party/protobuf/python/google/protobuf/descriptor.py:1
google::protobuf.internal.extension_dict._ExtensionDict._FindExtensionByNumber
def _FindExtensionByNumber(self, number)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:179
google::protobuf.internal.extension_dict._ExtensionDict._FindExtensionByName
def _FindExtensionByName(self, name)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:168
google::protobuf.internal.extension_dict._ExtensionDict.__getitem__
def __getitem__(self, extension_handle)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:78
google::protobuf.internal.extension_dict._ExtensionDict._extended_message
_extended_message
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:76
google::protobuf.internal.extension_dict._ExtensionDict.__eq__
def __eq__(self, other)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:115
google::protobuf.internal.extension_dict._ExtensionDict.__setitem__
def __setitem__(self, extension_handle, value)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:144
google::protobuf.internal.extension_dict._ExtensionDict.__delitem__
def __delitem__(self, extension_handle)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:165
google::protobuf.internal
Definition: third_party/bloaty/third_party/protobuf/python/google/protobuf/internal/__init__.py:1
google::protobuf.internal.python_message.ClearExtension
ClearExtension
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:914
google::protobuf.internal.extension_dict._ExtensionDict.__ne__
def __ne__(self, other)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:128
google::protobuf.internal.python_message._Modified
_Modified
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:1465
google::protobuf.internal.extension_dict._ExtensionDict.__len__
def __len__(self)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:131
google::protobuf.internal.extension_dict._VerifyExtensionHandle
def _VerifyExtensionHandle(message, extension_handle)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:38
google::protobuf.internal.python_message.ListFields
ListFields
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:819
google::protobuf.internal.extension_dict._ExtensionDict.__contains__
def __contains__(self, extension_handle)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:195
google::protobuf.internal.extension_dict._ExtensionDict.__iter__
def __iter__(self)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:190
google::protobuf.internal.extension_dict._ExtensionDict.__hash__
def __hash__(self)
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/extension_dict.py:137
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:20