diff options
author | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 08:50:35 +0300 |
---|---|---|
committer | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 09:00:27 +0300 |
commit | 509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194 (patch) | |
tree | 4b8a6a44009906ac852e59efa0bc78bb12043a5b /contrib/python | |
parent | 7688f2313619a39a60ef3c2734d8efbc49a0a6db (diff) | |
download | ydb-509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194.tar.gz |
Update protobuf to 3.20.2 and pyprotobuf to 3.20.3
Если это pull-request что-то сломал, то:
- если это тест с канонизацией и еще нет pr с переканонизацией, то переканонизируйте пожалуйста сами
- проверьте, что тест не флапает
- приходите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/createTicket?queue=DEVTOOLSSUPPORT) - там вам обязательно помогут
987be5ed151f827f7f292f32420470b04b71a91d
Diffstat (limited to 'contrib/python')
41 files changed, 2667 insertions, 2291 deletions
diff --git a/contrib/python/protobuf/py3/.dist-info/METADATA b/contrib/python/protobuf/py3/.dist-info/METADATA index 79a3401f13..13ac7d644c 100644 --- a/contrib/python/protobuf/py3/.dist-info/METADATA +++ b/contrib/python/protobuf/py3/.dist-info/METADATA @@ -1,22 +1,20 @@ Metadata-Version: 2.1 Name: protobuf -Version: 3.19.0 +Version: 3.20.3 Summary: Protocol Buffers Home-page: https://developers.google.com/protocol-buffers/ Download-URL: https://github.com/protocolbuffers/protobuf/releases Maintainer: protobuf@googlegroups.com Maintainer-email: protobuf@googlegroups.com -License: 3-Clause BSD License +License: BSD-3-Clause Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 -Requires-Python: >=3.5 +Requires-Python: >=3.7 License-File: LICENSE Protocol Buffers are Google's data interchange format diff --git a/contrib/python/protobuf/py3/README.md b/contrib/python/protobuf/py3/README.md index f0c9ce4f44..27f22c82c0 100644 --- a/contrib/python/protobuf/py3/README.md +++ b/contrib/python/protobuf/py3/README.md @@ -26,7 +26,7 @@ use python c++ implementation. Installation ============ -1) Make sure you have Python 3.5 or newer. If in doubt, run: +1) Make sure you have Python 3.7 or newer. If in doubt, run: $ python -V diff --git a/contrib/python/protobuf/py3/google/protobuf/__init__.py b/contrib/python/protobuf/py3/google/protobuf/__init__.py index 68087e5501..3087605b2e 100644 --- a/contrib/python/protobuf/py3/google/protobuf/__init__.py +++ b/contrib/python/protobuf/py3/google/protobuf/__init__.py @@ -30,4 +30,4 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '3.19.0' +__version__ = '3.20.3' diff --git a/contrib/python/protobuf/py3/google/protobuf/descriptor.py b/contrib/python/protobuf/py3/google/protobuf/descriptor.py index 61c242f9df..ad70be9a11 100644 --- a/contrib/python/protobuf/py3/google/protobuf/descriptor.py +++ b/contrib/python/protobuf/py3/google/protobuf/descriptor.py @@ -617,6 +617,26 @@ class FieldDescriptor(DescriptorBase): self._camelcase_name = _ToCamelCase(self.name) return self._camelcase_name + @property + def has_presence(self): + """Whether the field distinguishes between unpopulated and default values. + + Raises: + RuntimeError: singular field that is not linked with message nor file. + """ + if self.label == FieldDescriptor.LABEL_REPEATED: + return False + if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or + self.containing_oneof): + return True + if hasattr(self.file, 'syntax'): + return self.file.syntax == 'proto2' + if hasattr(self.message_type, 'syntax'): + return self.message_type.syntax == 'proto2' + raise RuntimeError( + 'has_presence is not ready to use because field %s is not' + ' linked with message type nor file' % self.full_name) + @staticmethod def ProtoTypeToCppProtoType(proto_type): """Converts from a Python proto type to a C++ Proto Type. @@ -647,7 +667,7 @@ class EnumDescriptor(_NestedDescriptorBase): full_name (str): Full name of the type, including package name and any enclosing type(s). - values (list[EnumValueDescriptors]): List of the values + values (list[EnumValueDescriptor]): List of the values in this enum. values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but indexed by the "name" field of each EnumValueDescriptor. @@ -879,6 +899,8 @@ class MethodDescriptor(DescriptorBase): accepts. output_type (Descriptor): The descriptor of the message that this method returns. + client_streaming (bool): Whether this method uses client streaming. + server_streaming (bool): Whether this method uses server streaming. options (descriptor_pb2.MethodOptions or None): Method options message, or None to use default method options. """ @@ -886,14 +908,32 @@ class MethodDescriptor(DescriptorBase): if _USE_C_DESCRIPTORS: _C_DESCRIPTOR_CLASS = _message.MethodDescriptor - def __new__(cls, name, full_name, index, containing_service, - input_type, output_type, options=None, serialized_options=None, + def __new__(cls, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + options=None, + serialized_options=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access return _message.default_pool.FindMethodByName(full_name) - def __init__(self, name, full_name, index, containing_service, - input_type, output_type, options=None, serialized_options=None, + def __init__(self, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + options=None, + serialized_options=None, create_key=None): """The arguments are as described in the description of MethodDescriptor attributes above. @@ -911,6 +951,8 @@ class MethodDescriptor(DescriptorBase): self.containing_service = containing_service self.input_type = input_type self.output_type = output_type + self.client_streaming = client_streaming + self.server_streaming = server_streaming def CopyToProto(self, proto): """Copies this to a descriptor_pb2.MethodDescriptorProto. diff --git a/contrib/python/protobuf/py3/google/protobuf/descriptor_pool.py b/contrib/python/protobuf/py3/google/protobuf/descriptor_pool.py index a6955ce81e..911372a8b0 100644 --- a/contrib/python/protobuf/py3/google/protobuf/descriptor_pool.py +++ b/contrib/python/protobuf/py3/google/protobuf/descriptor_pool.py @@ -1213,6 +1213,8 @@ class DescriptorPool(object): containing_service=None, input_type=input_type, output_type=output_type, + client_streaming=method_proto.client_streaming, + server_streaming=method_proto.server_streaming, options=_OptionsOrNone(method_proto), # pylint: disable=protected-access create_key=descriptor._internal_create_key) @@ -1233,21 +1235,25 @@ class DescriptorPool(object): for enum in desc.enum_types: yield (_PrefixWithDot(enum.full_name), enum) - def _GetDeps(self, dependencies): + def _GetDeps(self, dependencies, visited=None): """Recursively finds dependencies for file protos. Args: dependencies: The names of the files being depended on. + visited: The names of files already found. Yields: Each direct and indirect dependency. """ + visited = visited or set() for dependency in dependencies: - dep_desc = self.FindFileByName(dependency) - yield dep_desc - for parent_dep in dep_desc.dependencies: - yield parent_dep + if dependency not in visited: + visited.add(dependency) + dep_desc = self.FindFileByName(dependency) + yield dep_desc + public_files = [d.name for d in dep_desc.public_dependencies] + yield from self._GetDeps(public_files, visited) def _GetTypeFromScope(self, package, type_name, scope): """Finds a given type name in the current scope. diff --git a/contrib/python/protobuf/py3/google/protobuf/internal/api_implementation.cc b/contrib/python/protobuf/py3/google/protobuf/internal/api_implementation.cc index 6532a81405..33f5b04f49 100644 --- a/contrib/python/protobuf/py3/google/protobuf/internal/api_implementation.cc +++ b/contrib/python/protobuf/py3/google/protobuf/internal/api_implementation.cc @@ -28,6 +28,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#define PY_SSIZE_T_CLEAN #include <Python.h> namespace google { @@ -81,24 +82,24 @@ static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, kModuleName, kModuleDocstring, -1, - NULL, - NULL, - NULL, - NULL, - NULL}; + nullptr, + nullptr, + nullptr, + nullptr, + nullptr}; extern "C" { PyMODINIT_FUNC PyInit__api_implementation() { PyObject* module = PyModule_Create(&_module); - if (module == NULL) { - return NULL; + if (module == nullptr) { + return nullptr; } // Adds the module variable "api_version". if (PyModule_AddIntConstant(module, const_cast<char*>(kImplVersionName), kImplVersion)) { Py_DECREF(module); - return NULL; + return nullptr; } return module; diff --git a/contrib/python/protobuf/py3/google/protobuf/internal/builder.py b/contrib/python/protobuf/py3/google/protobuf/internal/builder.py new file mode 100644 index 0000000000..64353ee4af --- /dev/null +++ b/contrib/python/protobuf/py3/google/protobuf/internal/builder.py @@ -0,0 +1,130 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Builds descriptors, message classes and services for generated _pb2.py. + +This file is only called in python generated _pb2.py files. It builds +descriptors, message classes and services that users can directly use +in generated code. +""" + +__author__ = 'jieluo@google.com (Jie Luo)' + +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + +_sym_db = _symbol_database.Default() + + +def BuildMessageAndEnumDescriptors(file_des, module): + """Builds message and enum descriptors. + + Args: + file_des: FileDescriptor of the .proto file + module: Generated _pb2 module + """ + + def BuildNestedDescriptors(msg_des, prefix): + for (name, nested_msg) in msg_des.nested_types_by_name.items(): + module_name = prefix + name.upper() + module[module_name] = nested_msg + BuildNestedDescriptors(nested_msg, module_name + '_') + for enum_des in msg_des.enum_types: + module[prefix + enum_des.name.upper()] = enum_des + + for (name, msg_des) in file_des.message_types_by_name.items(): + module_name = '_' + name.upper() + module[module_name] = msg_des + BuildNestedDescriptors(msg_des, module_name + '_') + + +def BuildTopDescriptorsAndMessages(file_des, module_name, module): + """Builds top level descriptors and message classes. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + + def BuildMessage(msg_des): + create_dict = {} + for (name, nested_msg) in msg_des.nested_types_by_name.items(): + create_dict[name] = BuildMessage(nested_msg) + create_dict['DESCRIPTOR'] = msg_des + create_dict['__module__'] = module_name + message_class = _reflection.GeneratedProtocolMessageType( + msg_des.name, (_message.Message,), create_dict) + _sym_db.RegisterMessage(message_class) + return message_class + + # top level enums + for (name, enum_des) in file_des.enum_types_by_name.items(): + module['_' + name.upper()] = enum_des + module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) + for enum_value in enum_des.values: + module[enum_value.name] = enum_value.number + + # top level extensions + for (name, extension_des) in file_des.extensions_by_name.items(): + module[name.upper() + '_FIELD_NUMBER'] = extension_des.number + module[name] = extension_des + + # services + for (name, service) in file_des.services_by_name.items(): + module['_' + name.upper()] = service + + # Build messages. + for (name, msg_des) in file_des.message_types_by_name.items(): + module[name] = BuildMessage(msg_des) + + +def BuildServices(file_des, module_name, module): + """Builds services classes and services stub class. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + # pylint: disable=g-import-not-at-top + from google.protobuf import service as _service + from google.protobuf import service_reflection + # pylint: enable=g-import-not-at-top + for (name, service) in file_des.services_by_name.items(): + module[name] = service_reflection.GeneratedServiceType( + name, (_service.Service,), + dict(DESCRIPTOR=service, __module__=module_name)) + stub_name = name + '_Stub' + module[stub_name] = service_reflection.GeneratedServiceStubType( + stub_name, (module[name],), + dict(DESCRIPTOR=service, __module__=module_name)) diff --git a/contrib/python/protobuf/py3/google/protobuf/internal/containers.py b/contrib/python/protobuf/py3/google/protobuf/internal/containers.py index f0c06df8dd..29fbb53d2f 100644 --- a/contrib/python/protobuf/py3/google/protobuf/internal/containers.py +++ b/contrib/python/protobuf/py3/google/protobuf/internal/containers.py @@ -40,19 +40,37 @@ are: includes groups and nested messages. """ -__author__ = 'petar@google.com (Petar Petrov)' - import collections.abc - - -class BaseContainer(object): - +import copy +import pickle +from typing import ( + Any, + Iterable, + Iterator, + List, + MutableMapping, + MutableSequence, + NoReturn, + Optional, + Sequence, + TypeVar, + Union, + overload, +) + + +_T = TypeVar('_T') +_K = TypeVar('_K') +_V = TypeVar('_V') + + +class BaseContainer(Sequence[_T]): """Base container class.""" # Minimizes memory usage and disallows assignment to other attributes. __slots__ = ['_message_listener', '_values'] - def __init__(self, message_listener): + def __init__(self, message_listener: Any) -> None: """ Args: message_listener: A MessageListener implementation. @@ -62,26 +80,33 @@ class BaseContainer(object): self._message_listener = message_listener self._values = [] + @overload + def __getitem__(self, key: int) -> _T: + ... + + @overload + def __getitem__(self, key: slice) -> List[_T]: + ... + def __getitem__(self, key): """Retrieves item by the specified key.""" return self._values[key] - def __len__(self): + def __len__(self) -> int: """Returns the number of elements in the container.""" return len(self._values) - def __ne__(self, other): + def __ne__(self, other: Any) -> bool: """Checks if another instance isn't equal to this one.""" # The concrete classes should define __eq__. return not self == other - def __hash__(self): - raise TypeError('unhashable object') + __hash__ = None - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def sort(self, *args, **kwargs): + def sort(self, *args, **kwargs) -> None: # Continue to support the old sort_function keyword argument. # This is expected to be a rare occurrence, so use LBYL to avoid # the overhead of actually catching KeyError. @@ -89,20 +114,26 @@ class BaseContainer(object): kwargs['cmp'] = kwargs.pop('sort_function') self._values.sort(*args, **kwargs) - def reverse(self): + def reverse(self) -> None: self._values.reverse() +# TODO(slebedev): Remove this. BaseContainer does *not* conform to +# MutableSequence, only its subclasses do. collections.abc.MutableSequence.register(BaseContainer) -class RepeatedScalarFieldContainer(BaseContainer): +class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): """Simple, type-checked, list-like container for holding repeated scalars.""" # Disallows assignment to other attributes. __slots__ = ['_type_checker'] - def __init__(self, message_listener, type_checker): + def __init__( + self, + message_listener: Any, + type_checker: Any, + ) -> None: """Args: message_listener: A MessageListener implementation. The @@ -111,24 +142,23 @@ class RepeatedScalarFieldContainer(BaseContainer): type_checker: A type_checkers.ValueChecker instance to run on elements inserted into this container. """ - super(RepeatedScalarFieldContainer, self).__init__(message_listener) + super().__init__(message_listener) self._type_checker = type_checker - def append(self, value): + def append(self, value: _T) -> None: """Appends an item to the list. Similar to list.append().""" self._values.append(self._type_checker.CheckValue(value)) if not self._message_listener.dirty: self._message_listener.Modified() - def insert(self, key, value): + def insert(self, key: int, value: _T) -> None: """Inserts the item at the specified position. Similar to list.insert().""" self._values.insert(key, self._type_checker.CheckValue(value)) if not self._message_listener.dirty: self._message_listener.Modified() - def extend(self, elem_seq): + def extend(self, elem_seq: Iterable[_T]) -> None: """Extends by appending the given iterable. Similar to list.extend().""" - if elem_seq is None: return try: @@ -145,57 +175,52 @@ class RepeatedScalarFieldContainer(BaseContainer): self._values.extend(new_values) self._message_listener.Modified() - def MergeFrom(self, other): + def MergeFrom( + self, + other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], + ) -> None: """Appends the contents of another repeated field of the same type to this one. We do not check the types of the individual fields. """ - self._values.extend(other._values) + self._values.extend(other) self._message_listener.Modified() - def remove(self, elem): + def remove(self, elem: _T): """Removes an item from the list. Similar to list.remove().""" self._values.remove(elem) self._message_listener.Modified() - def pop(self, key=-1): + def pop(self, key: Optional[int] = -1) -> _T: """Removes and returns an item at a given index. Similar to list.pop().""" value = self._values[key] self.__delitem__(key) return value - def __setitem__(self, key, value): + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value) -> None: """Sets the item on the specified position.""" - if isinstance(key, slice): # PY3 + if isinstance(key, slice): if key.step is not None: raise ValueError('Extended slices not supported') - self.__setslice__(key.start, key.stop, value) + self._values[key] = map(self._type_checker.CheckValue, value) + self._message_listener.Modified() else: self._values[key] = self._type_checker.CheckValue(value) self._message_listener.Modified() - def __getslice__(self, start, stop): - """Retrieves the subset of items from between the specified indices.""" - return self._values[start:stop] - - def __setslice__(self, start, stop, values): - """Sets the subset of items from between the specified indices.""" - new_values = [] - for value in values: - new_values.append(self._type_checker.CheckValue(value)) - self._values[start:stop] = new_values - self._message_listener.Modified() - - def __delitem__(self, key): + def __delitem__(self, key: Union[int, slice]) -> None: """Deletes the item at the specified position.""" del self._values[key] self._message_listener.Modified() - def __delslice__(self, start, stop): - """Deletes the subset of items from between the specified indices.""" - del self._values[start:stop] - self._message_listener.Modified() - - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: """Compares the current instance with another one.""" if self is other: return True @@ -205,15 +230,28 @@ class RepeatedScalarFieldContainer(BaseContainer): # We are presumably comparing against some other sequence type. return other == self._values + def __deepcopy__( + self, + unused_memo: Any = None, + ) -> 'RepeatedScalarFieldContainer[_T]': + clone = RepeatedScalarFieldContainer( + copy.deepcopy(self._message_listener), self._type_checker) + clone.MergeFrom(self) + return clone + + def __reduce__(self, **kwargs) -> NoReturn: + raise pickle.PickleError( + "Can't pickle repeated scalar fields, convert to list first") -class RepeatedCompositeFieldContainer(BaseContainer): +# TODO(slebedev): Constrain T to be a subtype of Message. +class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): """Simple, list-like container for holding repeated composite fields.""" # Disallows assignment to other attributes. __slots__ = ['_message_descriptor'] - def __init__(self, message_listener, message_descriptor): + def __init__(self, message_listener: Any, message_descriptor: Any) -> None: """ Note that we pass in a descriptor instead of the generated directly, since at the time we construct a _RepeatedCompositeFieldContainer we @@ -228,10 +266,10 @@ class RepeatedCompositeFieldContainer(BaseContainer): that should be present in this container. We'll use the _concrete_class field of this descriptor when the client calls add(). """ - super(RepeatedCompositeFieldContainer, self).__init__(message_listener) + super().__init__(message_listener) self._message_descriptor = message_descriptor - def add(self, **kwargs): + def add(self, **kwargs: Any) -> _T: """Adds a new element at the end of the list and returns it. Keyword arguments may be used to initialize the element. """ @@ -242,7 +280,7 @@ class RepeatedCompositeFieldContainer(BaseContainer): self._message_listener.Modified() return new_element - def append(self, value): + def append(self, value: _T) -> None: """Appends one element by copying the message.""" new_element = self._message_descriptor._concrete_class() new_element._SetListener(self._message_listener) @@ -251,7 +289,7 @@ class RepeatedCompositeFieldContainer(BaseContainer): if not self._message_listener.dirty: self._message_listener.Modified() - def insert(self, key, value): + def insert(self, key: int, value: _T) -> None: """Inserts the item at the specified position by copying.""" new_element = self._message_descriptor._concrete_class() new_element._SetListener(self._message_listener) @@ -260,7 +298,7 @@ class RepeatedCompositeFieldContainer(BaseContainer): if not self._message_listener.dirty: self._message_listener.Modified() - def extend(self, elem_seq): + def extend(self, elem_seq: Iterable[_T]) -> None: """Extends by appending the given sequence of elements of the same type as this one, copying each individual message. @@ -275,38 +313,47 @@ class RepeatedCompositeFieldContainer(BaseContainer): values.append(new_element) listener.Modified() - def MergeFrom(self, other): + def MergeFrom( + self, + other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], + ) -> None: """Appends the contents of another repeated field of the same type to this one, copying each individual message. """ - self.extend(other._values) + self.extend(other) - def remove(self, elem): + def remove(self, elem: _T) -> None: """Removes an item from the list. Similar to list.remove().""" self._values.remove(elem) self._message_listener.Modified() - def pop(self, key=-1): + def pop(self, key: Optional[int] = -1) -> _T: """Removes and returns an item at a given index. Similar to list.pop().""" value = self._values[key] self.__delitem__(key) return value - def __getslice__(self, start, stop): - """Retrieves the subset of items from between the specified indices.""" - return self._values[start:stop] + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value): + # This method is implemented to make RepeatedCompositeFieldContainer + # structurally compatible with typing.MutableSequence. It is + # otherwise unsupported and will always raise an error. + raise TypeError( + f'{self.__class__.__name__} object does not support item assignment') - def __delitem__(self, key): + def __delitem__(self, key: Union[int, slice]) -> None: """Deletes the item at the specified position.""" del self._values[key] self._message_listener.Modified() - def __delslice__(self, start, stop): - """Deletes the subset of items from between the specified indices.""" - del self._values[start:stop] - self._message_listener.Modified() - - def __eq__(self, other): + def __eq__(self, other: Any) -> bool: """Compares the current instance with another one.""" if self is other: return True @@ -316,16 +363,20 @@ class RepeatedCompositeFieldContainer(BaseContainer): return self._values == other._values -class ScalarMap(collections.abc.MutableMapping): - +class ScalarMap(MutableMapping[_K, _V]): """Simple, type-checked, dict-like container for holding repeated scalars.""" # Disallows assignment to other attributes. __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener', '_entry_descriptor'] - def __init__(self, message_listener, key_checker, value_checker, - entry_descriptor): + def __init__( + self, + message_listener: Any, + key_checker: Any, + value_checker: Any, + entry_descriptor: Any, + ) -> None: """ Args: message_listener: A MessageListener implementation. @@ -343,7 +394,7 @@ class ScalarMap(collections.abc.MutableMapping): self._entry_descriptor = entry_descriptor self._values = {} - def __getitem__(self, key): + def __getitem__(self, key: _K) -> _V: try: return self._values[key] except KeyError: @@ -352,12 +403,20 @@ class ScalarMap(collections.abc.MutableMapping): self._values[key] = val return val - def __contains__(self, item): + def __contains__(self, item: _K) -> bool: # We check the key's type to match the strong-typing flavor of the API. # Also this makes it easier to match the behavior of the C++ implementation. self._key_checker.CheckValue(item) return item in self._values + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + # We need to override this explicitly, because our defaultdict-like behavior # will make the default implementation (from our base class) always insert # the key. @@ -367,30 +426,30 @@ class ScalarMap(collections.abc.MutableMapping): else: return default - def __setitem__(self, key, value): + def __setitem__(self, key: _K, value: _V) -> _T: checked_key = self._key_checker.CheckValue(key) checked_value = self._value_checker.CheckValue(value) self._values[checked_key] = checked_value self._message_listener.Modified() - def __delitem__(self, key): + def __delitem__(self, key: _K) -> None: del self._values[key] self._message_listener.Modified() - def __len__(self): + def __len__(self) -> int: return len(self._values) - def __iter__(self): + def __iter__(self) -> Iterator[_K]: return iter(self._values) - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def MergeFrom(self, other): + def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: self._values.update(other._values) self._message_listener.Modified() - def InvalidateIterators(self): + def InvalidateIterators(self) -> None: # It appears that the only way to reliably invalidate iterators to # self._values is to ensure that its size changes. original = self._values @@ -398,24 +457,28 @@ class ScalarMap(collections.abc.MutableMapping): original[None] = None # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self): + def clear(self) -> None: self._values.clear() self._message_listener.Modified() - def GetEntryClass(self): + def GetEntryClass(self) -> Any: return self._entry_descriptor._concrete_class -class MessageMap(collections.abc.MutableMapping): - +class MessageMap(MutableMapping[_K, _V]): """Simple, type-checked, dict-like container for with submessage values.""" # Disallows assignment to other attributes. __slots__ = ['_key_checker', '_values', '_message_listener', '_message_descriptor', '_entry_descriptor'] - def __init__(self, message_listener, message_descriptor, key_checker, - entry_descriptor): + def __init__( + self, + message_listener: Any, + message_descriptor: Any, + key_checker: Any, + entry_descriptor: Any, + ) -> None: """ Args: message_listener: A MessageListener implementation. @@ -433,7 +496,7 @@ class MessageMap(collections.abc.MutableMapping): self._entry_descriptor = entry_descriptor self._values = {} - def __getitem__(self, key): + def __getitem__(self, key: _K) -> _V: key = self._key_checker.CheckValue(key) try: return self._values[key] @@ -442,10 +505,9 @@ class MessageMap(collections.abc.MutableMapping): new_element._SetListener(self._message_listener) self._values[key] = new_element self._message_listener.Modified() - return new_element - def get_or_create(self, key): + def get_or_create(self, key: _K) -> _V: """get_or_create() is an alias for getitem (ie. map[key]). Args: @@ -459,6 +521,14 @@ class MessageMap(collections.abc.MutableMapping): """ return self[key] + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + # We need to override this explicitly, because our defaultdict-like behavior # will make the default implementation (from our base class) always insert # the key. @@ -468,28 +538,28 @@ class MessageMap(collections.abc.MutableMapping): else: return default - def __contains__(self, item): + def __contains__(self, item: _K) -> bool: item = self._key_checker.CheckValue(item) return item in self._values - def __setitem__(self, key, value): + def __setitem__(self, key: _K, value: _V) -> NoReturn: raise ValueError('May not set values directly, call my_map[key].foo = 5') - def __delitem__(self, key): + def __delitem__(self, key: _K) -> None: key = self._key_checker.CheckValue(key) del self._values[key] self._message_listener.Modified() - def __len__(self): + def __len__(self) -> int: return len(self._values) - def __iter__(self): + def __iter__(self) -> Iterator[_K]: return iter(self._values) - def __repr__(self): + def __repr__(self) -> str: return repr(self._values) - def MergeFrom(self, other): + def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: # pylint: disable=protected-access for key in other._values: # According to documentation: "When parsing from the wire or when merging, @@ -500,7 +570,7 @@ class MessageMap(collections.abc.MutableMapping): # self._message_listener.Modified() not required here, because # mutations to submessages already propagate. - def InvalidateIterators(self): + def InvalidateIterators(self) -> None: # It appears that the only way to reliably invalidate iterators to # self._values is to ensure that its size changes. original = self._values @@ -508,16 +578,15 @@ class MessageMap(collections.abc.MutableMapping): original[None] = None # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self): + def clear(self) -> None: self._values.clear() self._message_listener.Modified() - def GetEntryClass(self): + def GetEntryClass(self) -> Any: return self._entry_descriptor._concrete_class -class _UnknownField(object): - +class _UnknownField: """A parsed unknown field.""" # Disallows assignment to other attributes. @@ -542,12 +611,11 @@ class _UnknownField(object): self._data == other._data) -class UnknownFieldRef(object): +class UnknownFieldRef: # pylint: disable=missing-class-docstring def __init__(self, parent, index): self._parent = parent self._index = index - return def _check_valid(self): if not self._parent: @@ -576,8 +644,7 @@ class UnknownFieldRef(object): return self._parent._internal_get(self._index)._data -class UnknownFieldSet(object): - +class UnknownFieldSet: """UnknownField container""" # Disallows assignment to other attributes. diff --git a/contrib/python/protobuf/py3/google/protobuf/internal/type_checkers.py b/contrib/python/protobuf/py3/google/protobuf/internal/type_checkers.py index 9b9b859e1e..a53e71fe8e 100644 --- a/contrib/python/protobuf/py3/google/protobuf/internal/type_checkers.py +++ b/contrib/python/protobuf/py3/google/protobuf/internal/type_checkers.py @@ -48,7 +48,6 @@ __author__ = 'robinson@google.com (Will Robinson)' import ctypes import numbers -from google.protobuf.internal import api_implementation from google.protobuf.internal import decoder from google.protobuf.internal import encoder from google.protobuf.internal import wire_format @@ -77,7 +76,8 @@ def ToShortestFloat(original): def SupportsOpenEnums(field_descriptor): - return field_descriptor.containing_type.syntax == "proto3" + return field_descriptor.containing_type.syntax == 'proto3' + def GetTypeChecker(field): """Returns a type checker for a message field of the specified types. @@ -105,7 +105,6 @@ def GetTypeChecker(field): # subclassing builtin types and doing weird things. We're not trying to # protect against malicious clients here, just people accidentally shooting # themselves in the foot in obvious ways. - class TypeChecker(object): """Type checker used to catch type errors as early as possible @@ -124,11 +123,6 @@ class TypeChecker(object): message = ('%.1024r has type %s, but expected one of: %s' % (proposed_value, type(proposed_value), self._acceptable_types)) raise TypeError(message) - # Some field types(float, double and bool) accept other types, must - # convert to the correct type in such cases. - if self._acceptable_types: - if self._acceptable_types[0] in (bool, float): - return self._acceptable_types[0](proposed_value) return proposed_value @@ -142,6 +136,22 @@ class TypeCheckerWithDefault(TypeChecker): return self._default_value +class BoolValueChecker(object): + """Type checker used for bool fields.""" + + def CheckValue(self, proposed_value): + if not hasattr(proposed_value, '__index__') or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): + message = ('%.1024r has type %s, but expected one of: %s' % + (proposed_value, type(proposed_value), (bool, int))) + raise TypeError(message) + return bool(proposed_value) + + def DefaultValue(self): + return False + + # IntValueChecker and its subclasses perform integer type-checks # and bounds-checks. class IntValueChecker(object): @@ -149,10 +159,13 @@ class IntValueChecker(object): """Checker used for integer fields. Performs type-check and range check.""" def CheckValue(self, proposed_value): - if not isinstance(proposed_value, numbers.Integral): + if not hasattr(proposed_value, '__index__') or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): message = ('%.1024r has type %s, but expected one of: %s' % (proposed_value, type(proposed_value), (int,))) raise TypeError(message) + if not self._MIN <= int(proposed_value) <= self._MAX: raise ValueError('Value out of range: %d' % proposed_value) # We force all values to int to make alternate implementations where the @@ -249,20 +262,38 @@ _INF = float('inf') _NEG_INF = float('-inf') -class FloatValueChecker(object): +class DoubleValueChecker(object): + """Checker used for double fields. - """Checker used for float fields. Performs type-check and range check. - - Values exceeding a 32-bit float will be converted to inf/-inf. + Performs type-check and range check. """ def CheckValue(self, proposed_value): """Check and convert proposed_value to float.""" - if not isinstance(proposed_value, numbers.Real): - message = ('%.1024r has type %s, but expected one of: numbers.Real' % + if (not hasattr(proposed_value, '__float__') and + not hasattr(proposed_value, '__index__')) or ( + type(proposed_value).__module__ == 'numpy' and + type(proposed_value).__name__ == 'ndarray'): + message = ('%.1024r has type %s, but expected one of: int, float' % (proposed_value, type(proposed_value))) raise TypeError(message) - converted_value = float(proposed_value) + return float(proposed_value) + + def DefaultValue(self): + return 0.0 + + +class FloatValueChecker(DoubleValueChecker): + """Checker used for float fields. + + Performs type-check and range check. + + Values exceeding a 32-bit float will be converted to inf/-inf. + """ + + def CheckValue(self, proposed_value): + """Check and convert proposed_value to float.""" + converted_value = super().CheckValue(proposed_value) # This inf rounding matches the C++ proto SafeDoubleToFloat logic. if converted_value > _FLOAT_MAX: return _INF @@ -271,23 +302,17 @@ class FloatValueChecker(object): return TruncateToFourByteFloat(converted_value) - def DefaultValue(self): - return 0.0 - - # Type-checkers for all scalar CPPTYPEs. _VALUE_CHECKERS = { _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), - _FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault( - 0.0, float, numbers.Real), + _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), - _FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault( - False, bool, numbers.Integral), + _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), - } +} # Map from field type to a function F, such that F(field_num, value) diff --git a/contrib/python/protobuf/py3/google/protobuf/internal/well_known_types.py b/contrib/python/protobuf/py3/google/protobuf/internal/well_known_types.py index e7c059fde1..3f1aa9f846 100644 --- a/contrib/python/protobuf/py3/google/protobuf/internal/well_known_types.py +++ b/contrib/python/protobuf/py3/google/protobuf/internal/well_known_types.py @@ -42,8 +42,7 @@ __author__ = 'jieluo@google.com (Jie Luo)' import calendar import collections.abc -from datetime import datetime -from datetime import timedelta +import datetime from google.protobuf.descriptor import FieldDescriptor @@ -89,7 +88,9 @@ class Any(object): return '/' in self.type_url and self.TypeName() == descriptor.full_name -_EPOCH_DATETIME = datetime(1970, 1, 1, tzinfo=None) +_EPOCH_DATETIME_NAIVE = datetime.datetime(1970, 1, 1, tzinfo=None) +_EPOCH_DATETIME_AWARE = datetime.datetime.fromtimestamp( + 0, tz=datetime.timezone.utc) class Timestamp(object): @@ -109,7 +110,7 @@ class Timestamp(object): total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND seconds = total_sec % _SECONDS_PER_DAY days = (total_sec - seconds) // _SECONDS_PER_DAY - dt = datetime(1970, 1, 1) + timedelta(days, seconds) + dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) result = dt.isoformat() if (nanos % 1e9) == 0: @@ -159,8 +160,8 @@ class Timestamp(object): raise ValueError( 'time data \'{0}\' does not match format \'%Y-%m-%dT%H:%M:%S\', ' 'lowercase \'t\' is not accepted'.format(second_value)) - date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT) - td = date_object - datetime(1970, 1, 1) + date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFOMAT) + td = date_object - datetime.datetime(1970, 1, 1) seconds = td.seconds + td.days * _SECONDS_PER_DAY if len(nano_value) > 9: raise ValueError( @@ -191,7 +192,7 @@ class Timestamp(object): def GetCurrentTime(self): """Get the current UTC into Timestamp.""" - self.FromDatetime(datetime.utcnow()) + self.FromDatetime(datetime.datetime.utcnow()) def ToNanoseconds(self): """Converts Timestamp to nanoseconds since epoch.""" @@ -231,14 +232,32 @@ class Timestamp(object): self.seconds = seconds self.nanos = 0 - def ToDatetime(self): - """Converts Timestamp to datetime.""" - return _EPOCH_DATETIME + timedelta( - seconds=self.seconds, microseconds=_RoundTowardZero( - self.nanos, _NANOS_PER_MICROSECOND)) + def ToDatetime(self, tzinfo=None): + """Converts Timestamp to a datetime. + + Args: + tzinfo: A datetime.tzinfo subclass; defaults to None. + + Returns: + If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone + information, i.e. not aware that it's UTC). + + Otherwise, returns a timezone-aware datetime in the input timezone. + """ + delta = datetime.timedelta( + seconds=self.seconds, + microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)) + if tzinfo is None: + return _EPOCH_DATETIME_NAIVE + delta + else: + return _EPOCH_DATETIME_AWARE.astimezone(tzinfo) + delta def FromDatetime(self, dt): - """Converts datetime to Timestamp.""" + """Converts datetime to Timestamp. + + Args: + dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. + """ # Using this guide: http://wiki.python.org/moin/WorkingWithTime # And this conversion guide: http://docs.python.org/library/time.html @@ -363,7 +382,7 @@ class Duration(object): def ToTimedelta(self): """Converts Duration to timedelta.""" - return timedelta( + return datetime.timedelta( seconds=self.seconds, microseconds=_RoundTowardZero( self.nanos, _NANOS_PER_MICROSECOND)) diff --git a/contrib/python/protobuf/py3/google/protobuf/json_format.py b/contrib/python/protobuf/py3/google/protobuf/json_format.py index e68d29df6a..5024ed89d7 100644 --- a/contrib/python/protobuf/py3/google/protobuf/json_format.py +++ b/contrib/python/protobuf/py3/google/protobuf/json_format.py @@ -95,7 +95,8 @@ def MessageToJson( sort_keys=False, use_integers_for_enums=False, descriptor_pool=None, - float_precision=None): + float_precision=None, + ensure_ascii=True): """Converts protobuf message to JSON format. Args: @@ -114,6 +115,8 @@ def MessageToJson( descriptor_pool: A Descriptor Pool for resolving types. If None use the default. float_precision: If set, use this to specify float field valid digits. + ensure_ascii: If True, strings with non-ASCII characters are escaped. + If False, Unicode strings are returned unchanged. Returns: A string containing the JSON formatted protocol buffer message. @@ -124,7 +127,7 @@ def MessageToJson( use_integers_for_enums, descriptor_pool, float_precision=float_precision) - return printer.ToJsonString(message, indent, sort_keys) + return printer.ToJsonString(message, indent, sort_keys, ensure_ascii) def MessageToDict( @@ -190,9 +193,10 @@ class _Printer(object): else: self.float_format = None - def ToJsonString(self, message, indent, sort_keys): + def ToJsonString(self, message, indent, sort_keys, ensure_ascii): js = self._MessageToJsonObject(message) - return json.dumps(js, indent=indent, sort_keys=sort_keys) + return json.dumps( + js, indent=indent, sort_keys=sort_keys, ensure_ascii=ensure_ascii) def _MessageToJsonObject(self, message): """Converts message to an object according to Proto3 JSON Specification.""" @@ -395,12 +399,16 @@ def _CreateMessageFromTypeUrl(type_url, descriptor_pool): message_descriptor = pool.FindMessageTypeByName(type_name) except KeyError: raise TypeError( - 'Can not find message descriptor by type_url: {0}.'.format(type_url)) + 'Can not find message descriptor by type_url: {0}'.format(type_url)) message_class = db.GetPrototype(message_descriptor) return message_class() -def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): +def Parse(text, + message, + ignore_unknown_fields=False, + descriptor_pool=None, + max_recursion_depth=100): """Parses a JSON representation of a protocol message into a message. Args: @@ -408,7 +416,10 @@ def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): message: A protocol buffer message to merge into. ignore_unknown_fields: If True, do not raise errors for unknown fields. descriptor_pool: A Descriptor Pool for resolving types. If None use the - default. + default. + max_recursion_depth: max recursion depth of JSON message to be + deserialized. JSON messages over this depth will fail to be + deserialized. Default value is 100. Returns: The same message passed as argument. @@ -422,13 +433,15 @@ def Parse(text, message, ignore_unknown_fields=False, descriptor_pool=None): js = json.loads(text, object_pairs_hook=_DuplicateChecker) except ValueError as e: raise ParseError('Failed to load JSON: {0}.'.format(str(e))) - return ParseDict(js, message, ignore_unknown_fields, descriptor_pool) + return ParseDict(js, message, ignore_unknown_fields, descriptor_pool, + max_recursion_depth) def ParseDict(js_dict, message, ignore_unknown_fields=False, - descriptor_pool=None): + descriptor_pool=None, + max_recursion_depth=100): """Parses a JSON dictionary representation into a message. Args: @@ -437,12 +450,15 @@ def ParseDict(js_dict, ignore_unknown_fields: If True, do not raise errors for unknown fields. descriptor_pool: A Descriptor Pool for resolving types. If None use the default. + max_recursion_depth: max recursion depth of JSON message to be + deserialized. JSON messages over this depth will fail to be + deserialized. Default value is 100. Returns: The same message passed as argument. """ - parser = _Parser(ignore_unknown_fields, descriptor_pool) - parser.ConvertMessage(js_dict, message) + parser = _Parser(ignore_unknown_fields, descriptor_pool, max_recursion_depth) + parser.ConvertMessage(js_dict, message, '') return message @@ -452,35 +468,47 @@ _INT_OR_FLOAT = (int, float) class _Parser(object): """JSON format parser for protocol message.""" - def __init__(self, ignore_unknown_fields, descriptor_pool): + def __init__(self, ignore_unknown_fields, descriptor_pool, + max_recursion_depth): self.ignore_unknown_fields = ignore_unknown_fields self.descriptor_pool = descriptor_pool + self.max_recursion_depth = max_recursion_depth + self.recursion_depth = 0 - def ConvertMessage(self, value, message): + def ConvertMessage(self, value, message, path): """Convert a JSON object into a message. Args: value: A JSON object. message: A WKT or regular protocol message to record the data. + path: parent path to log parse error info. Raises: ParseError: In case of convert problems. """ + self.recursion_depth += 1 + if self.recursion_depth > self.max_recursion_depth: + raise ParseError('Message too deep. Max recursion depth is {0}'.format( + self.max_recursion_depth)) message_descriptor = message.DESCRIPTOR full_name = message_descriptor.full_name + if not path: + path = message_descriptor.name if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value, message) + self._ConvertWrapperMessage(value, message, path) elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value, message)(self) + methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) else: - self._ConvertFieldValuePair(value, message) + self._ConvertFieldValuePair(value, message, path) + self.recursion_depth -= 1 - def _ConvertFieldValuePair(self, js, message): + def _ConvertFieldValuePair(self, js, message, path): """Convert field value pairs into regular message. Args: js: A JSON object to convert the field value pairs. message: A regular protocol message to record the data. + path: parent path to log parse error info. Raises: ParseError: In case of problems converting. @@ -496,8 +524,9 @@ class _Parser(object): field = message_descriptor.fields_by_name.get(name, None) if not field and _VALID_EXTENSION_NAME.match(name): if not message_descriptor.is_extendable: - raise ParseError('Message type {0} does not have extensions'.format( - message_descriptor.full_name)) + raise ParseError( + 'Message type {0} does not have extensions at {1}'.format( + message_descriptor.full_name, path)) identifier = name[1:-1] # strip [] brackets # pylint: disable=protected-access field = message.Extensions._FindExtensionByName(identifier) @@ -513,14 +542,14 @@ class _Parser(object): if self.ignore_unknown_fields: continue raise ParseError( - ('Message type "{0}" has no field named "{1}".\n' - ' Available Fields(except extensions): {2}').format( - message_descriptor.full_name, name, + ('Message type "{0}" has no field named "{1}" at "{2}".\n' + ' Available Fields(except extensions): "{3}"').format( + message_descriptor.full_name, name, path, [f.json_name for f in message_descriptor.fields])) if name in names: raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" fields.'.format( - message.DESCRIPTOR.full_name, name)) + '"{1}" fields at "{2}".'.format( + message.DESCRIPTOR.full_name, name, path)) names.append(name) value = js[name] # Check no other oneof field is parsed. @@ -528,8 +557,9 @@ class _Parser(object): oneof_name = field.containing_oneof.name if oneof_name in names: raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" oneof fields.'.format( - message.DESCRIPTOR.full_name, oneof_name)) + '"{1}" oneof fields at "{2}".'.format( + message.DESCRIPTOR.full_name, oneof_name, + path)) names.append(oneof_name) if value is None: @@ -547,42 +577,51 @@ class _Parser(object): # Parse field value. if _IsMapEntry(field): message.ClearField(field.name) - self._ConvertMapFieldValue(value, message, field) + self._ConvertMapFieldValue(value, message, field, + '{0}.{1}'.format(path, name)) elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: message.ClearField(field.name) if not isinstance(value, list): raise ParseError('repeated field {0} must be in [] which is ' - '{1}.'.format(name, value)) + '{1} at {2}'.format(name, value, path)) if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: # Repeated message field. - for item in value: + for index, item in enumerate(value): sub_message = getattr(message, field.name).add() # None is a null_value in Value. if (item is None and sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'): raise ParseError('null is not allowed to be used as an element' - ' in a repeated field.') - self.ConvertMessage(item, sub_message) + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index)) + self.ConvertMessage(item, sub_message, + '{0}.{1}[{2}]'.format(path, name, index)) else: # Repeated scalar field. - for item in value: + for index, item in enumerate(value): if item is None: raise ParseError('null is not allowed to be used as an element' - ' in a repeated field.') + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index)) getattr(message, field.name).append( - _ConvertScalarFieldValue(item, field)) + _ConvertScalarFieldValue( + item, field, '{0}.{1}[{2}]'.format(path, name, index))) elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: if field.is_extension: sub_message = message.Extensions[field] else: sub_message = getattr(message, field.name) sub_message.SetInParent() - self.ConvertMessage(value, sub_message) + self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) else: if field.is_extension: - message.Extensions[field] = _ConvertScalarFieldValue(value, field) + message.Extensions[field] = _ConvertScalarFieldValue( + value, field, '{0}.{1}'.format(path, name)) else: - setattr(message, field.name, _ConvertScalarFieldValue(value, field)) + setattr( + message, field.name, + _ConvertScalarFieldValue(value, field, + '{0}.{1}'.format(path, name))) except ParseError as e: if field and field.containing_oneof is None: raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) @@ -593,46 +632,52 @@ class _Parser(object): except TypeError as e: raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - def _ConvertAnyMessage(self, value, message): + def _ConvertAnyMessage(self, value, message, path): """Convert a JSON representation into Any message.""" if isinstance(value, dict) and not value: return try: type_url = value['@type'] except KeyError: - raise ParseError('@type is missing when parsing any message.') + raise ParseError( + '@type is missing when parsing any message at {0}'.format(path)) - sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) + try: + sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) + except TypeError as e: + raise ParseError('{0} at {1}'.format(e, path)) message_descriptor = sub_message.DESCRIPTOR full_name = message_descriptor.full_name if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value['value'], sub_message) + self._ConvertWrapperMessage(value['value'], sub_message, + '{0}.value'.format(path)) elif full_name in _WKTJSONMETHODS: - methodcaller( - _WKTJSONMETHODS[full_name][1], value['value'], sub_message)(self) + methodcaller(_WKTJSONMETHODS[full_name][1], value['value'], sub_message, + '{0}.value'.format(path))( + self) else: del value['@type'] - self._ConvertFieldValuePair(value, sub_message) + self._ConvertFieldValuePair(value, sub_message, path) value['@type'] = type_url # Sets Any message message.value = sub_message.SerializeToString() message.type_url = type_url - def _ConvertGenericMessage(self, value, message): + def _ConvertGenericMessage(self, value, message, path): """Convert a JSON representation into message with FromJsonString.""" # Duration, Timestamp, FieldMask have a FromJsonString method to do the # conversion. Users can also call the method directly. try: message.FromJsonString(value) except ValueError as e: - raise ParseError(e) + raise ParseError('{0} at {1}'.format(e, path)) - def _ConvertValueMessage(self, value, message): + def _ConvertValueMessage(self, value, message, path): """Convert a JSON representation into Value message.""" if isinstance(value, dict): - self._ConvertStructMessage(value, message.struct_value) + self._ConvertStructMessage(value, message.struct_value, path) elif isinstance(value, list): - self. _ConvertListValueMessage(value, message.list_value) + self._ConvertListValueMessage(value, message.list_value, path) elif value is None: message.null_value = 0 elif isinstance(value, bool): @@ -642,68 +687,76 @@ class _Parser(object): elif isinstance(value, _INT_OR_FLOAT): message.number_value = value else: - raise ParseError('Value {0} has unexpected type {1}.'.format( - value, type(value))) + raise ParseError('Value {0} has unexpected type {1} at {2}'.format( + value, type(value), path)) - def _ConvertListValueMessage(self, value, message): + def _ConvertListValueMessage(self, value, message, path): """Convert a JSON representation into ListValue message.""" if not isinstance(value, list): - raise ParseError( - 'ListValue must be in [] which is {0}.'.format(value)) + raise ParseError('ListValue must be in [] which is {0} at {1}'.format( + value, path)) message.ClearField('values') - for item in value: - self._ConvertValueMessage(item, message.values.add()) + for index, item in enumerate(value): + self._ConvertValueMessage(item, message.values.add(), + '{0}[{1}]'.format(path, index)) - def _ConvertStructMessage(self, value, message): + def _ConvertStructMessage(self, value, message, path): """Convert a JSON representation into Struct message.""" if not isinstance(value, dict): - raise ParseError( - 'Struct must be in a dict which is {0}.'.format(value)) + raise ParseError('Struct must be in a dict which is {0} at {1}'.format( + value, path)) # Clear will mark the struct as modified so it will be created even if # there are no values. message.Clear() for key in value: - self._ConvertValueMessage(value[key], message.fields[key]) + self._ConvertValueMessage(value[key], message.fields[key], + '{0}.{1}'.format(path, key)) return - def _ConvertWrapperMessage(self, value, message): + def _ConvertWrapperMessage(self, value, message, path): """Convert a JSON representation into Wrapper message.""" field = message.DESCRIPTOR.fields_by_name['value'] - setattr(message, 'value', _ConvertScalarFieldValue(value, field)) + setattr( + message, 'value', + _ConvertScalarFieldValue(value, field, path='{0}.value'.format(path))) - def _ConvertMapFieldValue(self, value, message, field): + def _ConvertMapFieldValue(self, value, message, field, path): """Convert map field value for a message map field. Args: value: A JSON object to convert the map field value. message: A protocol message to record the converted data. field: The descriptor of the map field to be converted. + path: parent path to log parse error info. Raises: ParseError: In case of convert problems. """ if not isinstance(value, dict): raise ParseError( - 'Map field {0} must be in a dict which is {1}.'.format( - field.name, value)) + 'Map field {0} must be in a dict which is {1} at {2}'.format( + field.name, value, path)) key_field = field.message_type.fields_by_name['key'] value_field = field.message_type.fields_by_name['value'] for key in value: - key_value = _ConvertScalarFieldValue(key, key_field, True) + key_value = _ConvertScalarFieldValue(key, key_field, + '{0}.key'.format(path), True) if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self.ConvertMessage(value[key], getattr( - message, field.name)[key_value]) + self.ConvertMessage(value[key], + getattr(message, field.name)[key_value], + '{0}[{1}]'.format(path, key_value)) else: getattr(message, field.name)[key_value] = _ConvertScalarFieldValue( - value[key], value_field) + value[key], value_field, path='{0}[{1}]'.format(path, key_value)) -def _ConvertScalarFieldValue(value, field, require_str=False, path=None): +def _ConvertScalarFieldValue(value, field, path, require_str=False): """Convert a single scalar field value. Args: value: A scalar value to convert the scalar field value. field: The descriptor of the field to convert. + path: parent path to log parse error info. require_str: If True, the field value must be a str. Returns: @@ -712,44 +765,47 @@ def _ConvertScalarFieldValue(value, field, require_str=False, path=None): Raises: ParseError: In case of convert problems. """ - if field.cpp_type in _INT_TYPES: - return _ConvertInteger(value) - elif field.cpp_type in _FLOAT_TYPES: - return _ConvertFloat(value, field) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - return _ConvertBool(value, require_str) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - if isinstance(value, str): - encoded = value.encode('utf-8') + try: + if field.cpp_type in _INT_TYPES: + return _ConvertInteger(value) + elif field.cpp_type in _FLOAT_TYPES: + return _ConvertFloat(value, field) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: + return _ConvertBool(value, require_str) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: + if field.type == descriptor.FieldDescriptor.TYPE_BYTES: + if isinstance(value, str): + encoded = value.encode('utf-8') + else: + encoded = value + # Add extra padding '=' + padded_value = encoded + b'=' * (4 - len(encoded) % 4) + return base64.urlsafe_b64decode(padded_value) else: - encoded = value - # Add extra padding '=' - padded_value = encoded + b'=' * (4 - len(encoded) % 4) - return base64.urlsafe_b64decode(padded_value) - else: - # Checking for unpaired surrogates appears to be unreliable, - # depending on the specific Python version, so we check manually. - if _UNPAIRED_SURROGATE_PATTERN.search(value): - raise ParseError('Unpaired surrogate') - return value - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - # Convert an enum value. - enum_value = field.enum_type.values_by_name.get(value, None) - if enum_value is None: - try: - number = int(value) - enum_value = field.enum_type.values_by_number.get(number, None) - except ValueError: - raise ParseError('Invalid enum value {0} for enum type {1}.'.format( - value, field.enum_type.full_name)) + # Checking for unpaired surrogates appears to be unreliable, + # depending on the specific Python version, so we check manually. + if _UNPAIRED_SURROGATE_PATTERN.search(value): + raise ParseError('Unpaired surrogate') + return value + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: + # Convert an enum value. + enum_value = field.enum_type.values_by_name.get(value, None) if enum_value is None: - if field.file.syntax == 'proto3': - # Proto3 accepts unknown enums. - return number - raise ParseError('Invalid enum value {0} for enum type {1}.'.format( - value, field.enum_type.full_name)) - return enum_value.number + try: + number = int(value) + enum_value = field.enum_type.values_by_number.get(number, None) + except ValueError: + raise ParseError('Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name)) + if enum_value is None: + if field.file.syntax == 'proto3': + # Proto3 accepts unknown enums. + return number + raise ParseError('Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name)) + return enum_value.number + except ParseError as e: + raise ParseError('{0} at {1}'.format(e, path)) def _ConvertInteger(value): @@ -765,14 +821,14 @@ def _ConvertInteger(value): ParseError: If an integer couldn't be consumed. """ if isinstance(value, float) and not value.is_integer(): - raise ParseError('Couldn\'t parse integer: {0}.'.format(value)) + raise ParseError('Couldn\'t parse integer: {0}'.format(value)) if isinstance(value, str) and value.find(' ') != -1: - raise ParseError('Couldn\'t parse integer: "{0}".'.format(value)) + raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) if isinstance(value, bool): raise ParseError('Bool value {0} is not acceptable for ' - 'integer field.'.format(value)) + 'integer field'.format(value)) return int(value) @@ -781,14 +837,14 @@ def _ConvertFloat(value, field): """Convert an floating point number.""" if isinstance(value, float): if math.isnan(value): - raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead.') + raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') if math.isinf(value): if value > 0: raise ParseError('Couldn\'t parse Infinity or value too large, ' - 'use quoted "Infinity" instead.') + 'use quoted "Infinity" instead') else: raise ParseError('Couldn\'t parse -Infinity or value too small, ' - 'use quoted "-Infinity" instead.') + 'use quoted "-Infinity" instead') if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: # pylint: disable=protected-access if value > type_checkers._FLOAT_MAX: @@ -797,7 +853,7 @@ def _ConvertFloat(value, field): if value < type_checkers._FLOAT_MIN: raise ParseError('Float value too small') if value == 'nan': - raise ParseError('Couldn\'t parse float "nan", use "NaN" instead.') + raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') try: # Assume Python compatible syntax. return float(value) @@ -810,7 +866,7 @@ def _ConvertFloat(value, field): elif value == _NAN: return float('nan') else: - raise ParseError('Couldn\'t parse float: {0}.'.format(value)) + raise ParseError('Couldn\'t parse float: {0}'.format(value)) def _ConvertBool(value, require_str): @@ -832,10 +888,10 @@ def _ConvertBool(value, require_str): elif value == 'false': return False else: - raise ParseError('Expected "true" or "false", not {0}.'.format(value)) + raise ParseError('Expected "true" or "false", not {0}'.format(value)) if not isinstance(value, bool): - raise ParseError('Expected true or false without quotes.') + raise ParseError('Expected true or false without quotes') return value _WKTJSONMETHODS = { diff --git a/contrib/python/protobuf/py3/google/protobuf/message.py b/contrib/python/protobuf/py3/google/protobuf/message.py index ee46d0e4c9..76c6802f70 100644 --- a/contrib/python/protobuf/py3/google/protobuf/message.py +++ b/contrib/python/protobuf/py3/google/protobuf/message.py @@ -194,6 +194,9 @@ class Message(object): """Parse serialized protocol buffer data into this message. Like :func:`MergeFromString()`, except we clear the object first. + + Raises: + message.DecodeError if the input cannot be parsed. """ self.Clear() return self.MergeFromString(serialized) diff --git a/contrib/python/protobuf/py3/google/protobuf/proto_api.h b/contrib/python/protobuf/py3/google/protobuf/proto_api.h index 2e2156a56e..9969a91f44 100644 --- a/contrib/python/protobuf/py3/google/protobuf/proto_api.h +++ b/contrib/python/protobuf/py3/google/protobuf/proto_api.h @@ -45,6 +45,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_PROTO_API_H__ #define GOOGLE_PROTOBUF_PYTHON_PROTO_API_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/descriptor_database.h> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.cc index 0712abc068..a5254ce97b 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.cc @@ -32,6 +32,7 @@ #include <google/protobuf/pyext/descriptor.h> +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <frameobject.h> @@ -49,12 +50,13 @@ #include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include <google/protobuf/stubs/hash.h> -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) @@ -130,7 +132,7 @@ bool _CalledFromGeneratedFile(int stacklevel) { PyObject* frame_locals = nullptr; bool result = false; - if (frame == NULL) { + if (frame == nullptr) { goto exit; } Py_INCREF(frame); @@ -138,7 +140,7 @@ bool _CalledFromGeneratedFile(int stacklevel) { PyFrameObject* next_frame = PyFrame_GetBack(frame); Py_DECREF(frame); frame = next_frame; - if (frame == NULL) { + if (frame == nullptr) { goto exit; } } @@ -284,23 +286,23 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { const Descriptor *message_type = options.GetDescriptor(); CMessageClass* message_class = message_factory::GetOrCreateMessageClass( message_factory, message_type); - if (message_class == NULL) { + if (message_class == nullptr) { PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s", message_type->full_name().c_str()); - return NULL; + return nullptr; } ScopedPyObjectPtr args(PyTuple_New(0)); ScopedPyObjectPtr value( - PyObject_Call(message_class->AsPyObject(), args.get(), NULL)); + PyObject_Call(message_class->AsPyObject(), args.get(), nullptr)); Py_DECREF(message_class); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(value.get(), CMessage_Type)) { PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", message_type->full_name().c_str(), Py_TYPE(value.get())->tp_name); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast<CMessage*>(value.get()); @@ -312,7 +314,7 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { // Reparse options string! XXX call cmessage::MergeFromString if (!Reparse(message_factory, options, cmsg->message)) { PyErr_Format(PyExc_ValueError, "Error reparsing Options message"); - return NULL; + return nullptr; } } @@ -336,7 +338,7 @@ static PyObject* CopyToPythonProto(const DescriptorClass *descriptor, message->message->GetDescriptor() != self_descriptor) { PyErr_Format(PyExc_TypeError, "Not a %s message", self_descriptor->full_name().c_str()); - return NULL; + return nullptr; } cmessage::AssureWritable(message); DescriptorProtoClass* descriptor_message = @@ -372,7 +374,7 @@ typedef struct PyBaseDescriptor { typedef struct PyFileDescriptor { PyBaseDescriptor base; - // The cached version of serialized pb. Either NULL, or a Bytes string. + // The cached version of serialized pb. Either null, or a Bytes string. // We own the reference. PyObject *serialized_pb; } PyFileDescriptor; @@ -393,9 +395,9 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, if (was_created) { *was_created = false; } - if (descriptor == NULL) { + if (descriptor == nullptr) { PyErr_BadInternalCall(); - return NULL; + return nullptr; } // See if the object is in the map of interned descriptors @@ -409,8 +411,8 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, // Create a new descriptor object PyBaseDescriptor* py_descriptor = PyObject_GC_New( PyBaseDescriptor, type); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } py_descriptor->descriptor = descriptor; @@ -421,10 +423,10 @@ PyObject* NewInternedDescriptor(PyTypeObject* type, // Ensures that the DescriptorPool stays alive. PyDescriptorPool* pool = GetDescriptorPool_FromPool( GetFileDescriptor(descriptor)->pool()); - if (pool == NULL) { + if (pool == nullptr) { // Don't DECREF, the object is not fully initialized. PyObject_Del(py_descriptor); - return NULL; + return nullptr; } Py_INCREF(pool); py_descriptor->pool = pool; @@ -461,39 +463,43 @@ static int GcClear(PyObject* pself) { } static PyGetSetDef Getters[] = { - {NULL} + {nullptr}, }; PyTypeObject PyBaseDescriptor_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".DescriptorBase", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - (destructor)Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + ".DescriptorBase", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + (destructor)Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags "Descriptors base class", // tp_doc GcTraverse, // tp_traverse GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members Getters, // tp_getset }; @@ -502,7 +508,7 @@ PyTypeObject PyBaseDescriptor_Type = { const void* PyDescriptor_AsVoidPtr(PyObject* obj) { if (!PyObject_TypeCheck(obj, &descriptor::PyBaseDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a BaseDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor; } @@ -664,19 +670,18 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) { const char *enum_name; int number; - if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) - return NULL; + if (!PyArg_ParseTuple(args, "si", &enum_name, &number)) return nullptr; const EnumDescriptor *enum_type = _GetDescriptor(self)->FindEnumTypeByName(enum_name); - if (enum_type == NULL) { + if (enum_type == nullptr) { PyErr_SetString(PyExc_KeyError, enum_name); - return NULL; + return nullptr; } const EnumValueDescriptor *enum_value = enum_type->FindValueByNumber(number); - if (enum_value == NULL) { + if (enum_value == nullptr) { PyErr_Format(PyExc_KeyError, "%d", number); - return NULL; + return nullptr; } return PyString_FromCppString(enum_value->name()); } @@ -687,94 +692,102 @@ static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Last name"}, - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "_concrete_class", (getter)GetConcreteClass, NULL, "concrete class"}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - - { "fields", (getter)GetFieldsSeq, NULL, "Fields sequence"}, - { "fields_by_name", (getter)GetFieldsByName, NULL, "Fields by name"}, - { "fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, NULL, - "Fields by camelCase name"}, - { "fields_by_number", (getter)GetFieldsByNumber, NULL, "Fields by number"}, - { "nested_types", (getter)GetNestedTypesSeq, NULL, "Nested types sequence"}, - { "nested_types_by_name", (getter)GetNestedTypesByName, NULL, - "Nested types by name"}, - { "extensions", (getter)GetExtensions, NULL, "Extensions Sequence"}, - { "extensions_by_name", (getter)GetExtensionsByName, NULL, - "Extensions by name"}, - { "extension_ranges", (getter)GetExtensionRanges, NULL, "Extension ranges"}, - { "enum_types", (getter)GetEnumsSeq, NULL, "Enum sequence"}, - { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, - "Enum types by name"}, - { "enum_values_by_name", (getter)GetEnumValuesByName, NULL, - "Enum values by name"}, - { "oneofs_by_name", (getter)GetOneofsByName, NULL, "Oneofs by name"}, - { "oneofs", (getter)GetOneofsSeq, NULL, "Oneofs by name"}, - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "is_extendable", (getter)IsExtendable, (setter)NULL}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, - {NULL} + {"name", (getter)GetName, nullptr, "Last name"}, + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"_concrete_class", (getter)GetConcreteClass, nullptr, "concrete class"}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + + {"fields", (getter)GetFieldsSeq, nullptr, "Fields sequence"}, + {"fields_by_name", (getter)GetFieldsByName, nullptr, "Fields by name"}, + {"fields_by_camelcase_name", (getter)GetFieldsByCamelcaseName, nullptr, + "Fields by camelCase name"}, + {"fields_by_number", (getter)GetFieldsByNumber, nullptr, + "Fields by number"}, + {"nested_types", (getter)GetNestedTypesSeq, nullptr, + "Nested types sequence"}, + {"nested_types_by_name", (getter)GetNestedTypesByName, nullptr, + "Nested types by name"}, + {"extensions", (getter)GetExtensions, nullptr, "Extensions Sequence"}, + {"extensions_by_name", (getter)GetExtensionsByName, nullptr, + "Extensions by name"}, + {"extension_ranges", (getter)GetExtensionRanges, nullptr, + "Extension ranges"}, + {"enum_types", (getter)GetEnumsSeq, nullptr, "Enum sequence"}, + {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr, + "Enum types by name"}, + {"enum_values_by_name", (getter)GetEnumValuesByName, nullptr, + "Enum values by name"}, + {"oneofs_by_name", (getter)GetOneofsByName, nullptr, "Oneofs by name"}, + {"oneofs", (getter)GetOneofsSeq, nullptr, "Oneofs by name"}, + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"is_extendable", (getter)IsExtendable, (setter) nullptr}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - { "EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {"EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS}, + {nullptr}, }; } // namespace message_descriptor PyTypeObject PyMessageDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MessageDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Message Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - message_descriptor::Methods, // tp_methods - 0, // tp_members - message_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".MessageDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Message Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + message_descriptor::Methods, // tp_methods + nullptr, // tp_members + message_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyMessageDescriptor_FromDescriptor( const Descriptor* message_descriptor) { - return descriptor::NewInternedDescriptor( - &PyMessageDescriptor_Type, message_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyMessageDescriptor_Type, + message_descriptor, nullptr); } const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyMessageDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a MessageDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<const Descriptor*>( reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); @@ -902,7 +915,7 @@ static PyObject* GetDefaultValue(PyBaseDescriptor *self, void *closure) { default: PyErr_Format(PyExc_NotImplementedError, "default value for %s", _GetDescriptor(self)->full_name().c_str()); - return NULL; + return nullptr; } return result; } @@ -993,6 +1006,14 @@ static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("has_options"); } +static PyObject* GetHasPresence(PyBaseDescriptor* self, void* closure) { + if (_GetDescriptor(self)->has_presence()) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -1008,89 +1029,95 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "name", (getter)GetName, NULL, "Unqualified name"}, - { "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"}, - { "json_name", (getter)GetJsonName, NULL, "Json name"}, - { "file", (getter)GetFile, NULL, "File Descriptor"}, - { "type", (getter)GetType, NULL, "C++ Type"}, - { "cpp_type", (getter)GetCppType, NULL, "C++ Type"}, - { "label", (getter)GetLabel, NULL, "Label"}, - { "number", (getter)GetNumber, NULL, "Number"}, - { "index", (getter)GetIndex, NULL, "Index"}, - { "default_value", (getter)GetDefaultValue, NULL, "Default Value"}, - { "has_default_value", (getter)HasDefaultValue}, - { "is_extension", (getter)IsExtension, NULL, "ID"}, - { "id", (getter)GetID, NULL, "ID"}, - { "_cdescriptor", (getter)GetCDescriptor, NULL, "HAACK REMOVE ME"}, - - { "message_type", (getter)GetMessageType, (setter)SetMessageType, - "Message type"}, - { "enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "extension_scope", (getter)GetExtensionScope, (setter)NULL, - "Extension scope"}, - { "containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, - "Containing oneof"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"name", (getter)GetName, nullptr, "Unqualified name"}, + {"camelcase_name", (getter)GetCamelcaseName, nullptr, "Camelcase name"}, + {"json_name", (getter)GetJsonName, nullptr, "Json name"}, + {"file", (getter)GetFile, nullptr, "File Descriptor"}, + {"type", (getter)GetType, nullptr, "C++ Type"}, + {"cpp_type", (getter)GetCppType, nullptr, "C++ Type"}, + {"label", (getter)GetLabel, nullptr, "Label"}, + {"number", (getter)GetNumber, nullptr, "Number"}, + {"index", (getter)GetIndex, nullptr, "Index"}, + {"default_value", (getter)GetDefaultValue, nullptr, "Default Value"}, + {"has_default_value", (getter)HasDefaultValue}, + {"is_extension", (getter)IsExtension, nullptr, "ID"}, + {"id", (getter)GetID, nullptr, "ID"}, + {"_cdescriptor", (getter)GetCDescriptor, nullptr, "HAACK REMOVE ME"}, + + {"message_type", (getter)GetMessageType, (setter)SetMessageType, + "Message type"}, + {"enum_type", (getter)GetEnumType, (setter)SetEnumType, "Enum type"}, + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"extension_scope", (getter)GetExtensionScope, (setter) nullptr, + "Extension scope"}, + {"containing_oneof", (getter)GetContainingOneof, (setter)SetContainingOneof, + "Containing oneof"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"has_presence", (getter)GetHasPresence, (setter) nullptr, "Has Presence"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace field_descriptor PyTypeObject PyFieldDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".FieldDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Field Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - field_descriptor::Methods, // tp_methods - 0, // tp_members - field_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".FieldDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Field Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + field_descriptor::Methods, // tp_methods + nullptr, // tp_members + field_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyFieldDescriptor_FromDescriptor( const FieldDescriptor* field_descriptor) { - return descriptor::NewInternedDescriptor( - &PyFieldDescriptor_Type, field_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyFieldDescriptor_Type, + field_descriptor, nullptr); } const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyFieldDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a FieldDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<const FieldDescriptor*>( reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); @@ -1176,76 +1203,81 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; static PyGetSetDef Getters[] = { - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "name", (getter)GetName, NULL, "last name"}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - { "values", (getter)GetEnumvaluesSeq, NULL, "values"}, - { "values_by_name", (getter)GetEnumvaluesByName, NULL, - "Enum values by name"}, - { "values_by_number", (getter)GetEnumvaluesByNumber, NULL, - "Enum values by number"}, - - { "containing_type", (getter)GetContainingType, (setter)SetContainingType, - "Containing type"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"name", (getter)GetName, nullptr, "last name"}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + {"values", (getter)GetEnumvaluesSeq, nullptr, "values"}, + {"values_by_name", (getter)GetEnumvaluesByName, nullptr, + "Enum values by name"}, + {"values_by_number", (getter)GetEnumvaluesByNumber, nullptr, + "Enum values by number"}, + + {"containing_type", (getter)GetContainingType, (setter)SetContainingType, + "Containing type"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; } // namespace enum_descriptor PyTypeObject PyEnumDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".EnumDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Enum Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - enum_descriptor::Methods, // tp_methods - 0, // tp_members - enum_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".EnumDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Enum Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + enum_descriptor::Methods, // tp_methods + nullptr, // tp_members + enum_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyEnumDescriptor_FromDescriptor( const EnumDescriptor* enum_descriptor) { - return descriptor::NewInternedDescriptor( - &PyEnumDescriptor_Type, enum_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyEnumDescriptor_Type, + enum_descriptor, nullptr); } const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyEnumDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not an EnumDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<const EnumDescriptor*>( reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); @@ -1303,63 +1335,68 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "name"}, - { "number", (getter)GetNumber, NULL, "number"}, - { "index", (getter)GetIndex, NULL, "index"}, - { "type", (getter)GetType, NULL, "index"}, - - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - {NULL} + {"name", (getter)GetName, nullptr, "name"}, + {"number", (getter)GetNumber, nullptr, "number"}, + {"index", (getter)GetIndex, nullptr, "index"}, + {"type", (getter)GetType, nullptr, "index"}, + + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace enumvalue_descriptor PyTypeObject PyEnumValueDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".EnumValueDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A EnumValue Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - enumvalue_descriptor::Methods, // tp_methods - 0, // tp_members - enumvalue_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".EnumValueDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A EnumValue Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + enumvalue_descriptor::Methods, // tp_methods + nullptr, // tp_members + enumvalue_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyEnumValueDescriptor_FromDescriptor( const EnumValueDescriptor* enumvalue_descriptor) { - return descriptor::NewInternedDescriptor( - &PyEnumValueDescriptor_Type, enumvalue_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyEnumValueDescriptor_Type, + enumvalue_descriptor, nullptr); } namespace file_descriptor { @@ -1391,7 +1428,7 @@ static PyObject* GetPackage(PyFileDescriptor *self, void *closure) { static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) { PyObject *serialized_pb = self->serialized_pb; - if (serialized_pb != NULL) { + if (serialized_pb != nullptr) { Py_INCREF(serialized_pb); return serialized_pb; } @@ -1401,8 +1438,8 @@ static PyObject* GetSerializedPb(PyFileDescriptor *self, void *closure) { file_proto.SerializePartialToString(&contents); self->serialized_pb = PyBytes_FromStringAndSize( contents.c_str(), contents.size()); - if (self->serialized_pb == NULL) { - return NULL; + if (self->serialized_pb == nullptr) { + return nullptr; } Py_INCREF(self->serialized_pb); return self->serialized_pb; @@ -1445,6 +1482,10 @@ static int SetHasOptions(PyFileDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("has_options"); } +static PyObject* GetDebugString(PyFileDescriptor* self) { + return PyString_FromCppString(_GetDescriptor(self)->DebugString()); +} + static PyObject* GetOptions(PyFileDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -1469,31 +1510,36 @@ static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "pool", (getter)GetPool, NULL, "pool"}, - { "name", (getter)GetName, NULL, "name"}, - { "package", (getter)GetPackage, NULL, "package"}, - { "serialized_pb", (getter)GetSerializedPb}, - { "message_types_by_name", (getter)GetMessageTypesByName, NULL, - "Messages by name"}, - { "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"}, - { "extensions_by_name", (getter)GetExtensionsByName, NULL, - "Extensions by name"}, - { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"}, - { "dependencies", (getter)GetDependencies, NULL, "Dependencies"}, - { "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"}, - - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "syntax", (getter)GetSyntax, (setter)NULL, "Syntax"}, - {NULL} + {"pool", (getter)GetPool, nullptr, "pool"}, + {"name", (getter)GetName, nullptr, "name"}, + {"package", (getter)GetPackage, nullptr, "package"}, + {"serialized_pb", (getter)GetSerializedPb}, + {"message_types_by_name", (getter)GetMessageTypesByName, nullptr, + "Messages by name"}, + {"enum_types_by_name", (getter)GetEnumTypesByName, nullptr, + "Enums by name"}, + {"extensions_by_name", (getter)GetExtensionsByName, nullptr, + "Extensions by name"}, + {"services_by_name", (getter)GetServicesByName, nullptr, + "Services by name"}, + {"dependencies", (getter)GetDependencies, nullptr, "Dependencies"}, + {"public_dependencies", (getter)GetPublicDependencies, nullptr, + "Dependencies"}, + + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetDebugString", (PyCFunction)GetDebugString, METH_NOARGS}, + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; } // namespace file_descriptor @@ -1504,46 +1550,50 @@ PyTypeObject PyFileDescriptor_Type = { sizeof(PyFileDescriptor), // tp_basicsize 0, // tp_itemsize (destructor)file_descriptor::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A File Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - file_descriptor::Methods, // tp_methods - 0, // tp_members - file_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new - PyObject_GC_Del, // tp_free +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A File Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + file_descriptor::Methods, // tp_methods + nullptr, // tp_members + file_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + PyObject_GC_Del, // tp_free }; PyObject* PyFileDescriptor_FromDescriptor( const FileDescriptor* file_descriptor) { return PyFileDescriptor_FromDescriptorWithSerializedPb(file_descriptor, - NULL); + nullptr); } PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( @@ -1551,8 +1601,8 @@ PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( bool was_created; PyObject* py_descriptor = descriptor::NewInternedDescriptor( &PyFileDescriptor_Type, file_descriptor, &was_created); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } if (was_created) { PyFileDescriptor* cfile_descriptor = @@ -1569,7 +1619,7 @@ PyObject* PyFileDescriptor_FromDescriptorWithSerializedPb( const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyFileDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a FileDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<const FileDescriptor*>( reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); @@ -1617,6 +1667,7 @@ static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) { Py_RETURN_FALSE; } } + static int SetHasOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("has_options"); @@ -1637,64 +1688,69 @@ static int SetSerializedOptions(PyBaseDescriptor *self, PyObject *value, } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name"}, - { "full_name", (getter)GetFullName, NULL, "Full name"}, - { "index", (getter)GetIndex, NULL, "Index"}, - - { "containing_type", (getter)GetContainingType, NULL, "Containing type"}, - { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"}, - { "_options", (getter)NULL, (setter)SetOptions, "Options"}, - { "_serialized_options", (getter)NULL, (setter)SetSerializedOptions, - "Serialized Options"}, - { "fields", (getter)GetFields, NULL, "Fields"}, - {NULL} + {"name", (getter)GetName, nullptr, "Name"}, + {"full_name", (getter)GetFullName, nullptr, "Full name"}, + {"index", (getter)GetIndex, nullptr, "Index"}, + + {"containing_type", (getter)GetContainingType, nullptr, "Containing type"}, + {"has_options", (getter)GetHasOptions, (setter)SetHasOptions, + "Has Options"}, + {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, + {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, + "Serialized Options"}, + {"fields", (getter)GetFields, nullptr, "Fields"}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {nullptr}, }; } // namespace oneof_descriptor PyTypeObject PyOneofDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".OneofDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Oneof Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - oneof_descriptor::Methods, // tp_methods - 0, // tp_members - oneof_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".OneofDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Oneof Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + oneof_descriptor::Methods, // tp_methods + nullptr, // tp_members + oneof_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyOneofDescriptor_FromDescriptor( const OneofDescriptor* oneof_descriptor) { - return descriptor::NewInternedDescriptor( - &PyOneofDescriptor_Type, oneof_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyOneofDescriptor_Type, + oneof_descriptor, nullptr); } namespace service_descriptor { @@ -1733,14 +1789,14 @@ static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const MethodDescriptor* method_descriptor = _GetDescriptor(self)->FindMethodByName(StringParam(name, name_size)); - if (method_descriptor == NULL) { + if (method_descriptor == nullptr) { PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name); - return NULL; + return nullptr; } return PyMethodDescriptor_FromDescriptor(method_descriptor); @@ -1756,69 +1812,73 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name", NULL}, - { "full_name", (getter)GetFullName, NULL, "Full name", NULL}, - { "file", (getter)GetFile, NULL, "File descriptor"}, - { "index", (getter)GetIndex, NULL, "Index", NULL}, - - { "methods", (getter)GetMethods, NULL, "Methods", NULL}, - { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL}, - {NULL} + {"name", (getter)GetName, nullptr, "Name", nullptr}, + {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr}, + {"file", (getter)GetFile, nullptr, "File descriptor"}, + {"index", (getter)GetIndex, nullptr, "Index", nullptr}, + {"methods", (getter)GetMethods, nullptr, "Methods", nullptr}, + {"methods_by_name", (getter)GetMethodsByName, nullptr, "Methods by name", + nullptr}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {"FindMethodByName", (PyCFunction)FindMethodByName, METH_O}, + {nullptr}, }; } // namespace service_descriptor PyTypeObject PyServiceDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".ServiceDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Service Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - service_descriptor::Methods, // tp_methods - 0, // tp_members - service_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".ServiceDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Service Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + service_descriptor::Methods, // tp_methods + nullptr, // tp_members + service_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyServiceDescriptor_FromDescriptor( const ServiceDescriptor* service_descriptor) { - return descriptor::NewInternedDescriptor( - &PyServiceDescriptor_Type, service_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyServiceDescriptor_Type, + service_descriptor, nullptr); } const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) { if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) { PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor"); - return NULL; + return nullptr; } return reinterpret_cast<const ServiceDescriptor*>( reinterpret_cast<PyBaseDescriptor*>(obj)->descriptor); @@ -1860,6 +1920,14 @@ static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) { return PyMessageDescriptor_FromDescriptor(output_type); } +static PyObject* GetClientStreaming(PyBaseDescriptor* self, void* closure) { + return PyBool_FromLong(_GetDescriptor(self)->client_streaming() ? 1 : 0); +} + +static PyObject* GetServerStreaming(PyBaseDescriptor* self, void* closure) { + return PyBool_FromLong(_GetDescriptor(self)->server_streaming() ? 1 : 0); +} + static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } @@ -1869,62 +1937,70 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { } static PyGetSetDef Getters[] = { - { "name", (getter)GetName, NULL, "Name", NULL}, - { "full_name", (getter)GetFullName, NULL, "Full name", NULL}, - { "index", (getter)GetIndex, NULL, "Index", NULL}, - { "containing_service", (getter)GetContainingService, NULL, - "Containing service", NULL}, - { "input_type", (getter)GetInputType, NULL, "Input type", NULL}, - { "output_type", (getter)GetOutputType, NULL, "Output type", NULL}, - {NULL} + {"name", (getter)GetName, nullptr, "Name", nullptr}, + {"full_name", (getter)GetFullName, nullptr, "Full name", nullptr}, + {"index", (getter)GetIndex, nullptr, "Index", nullptr}, + {"containing_service", (getter)GetContainingService, nullptr, + "Containing service", nullptr}, + {"input_type", (getter)GetInputType, nullptr, "Input type", nullptr}, + {"output_type", (getter)GetOutputType, nullptr, "Output type", nullptr}, + {"client_streaming", (getter)GetClientStreaming, nullptr, + "Client streaming", nullptr}, + {"server_streaming", (getter)GetServerStreaming, nullptr, + "Server streaming", nullptr}, + {nullptr}, }; static PyMethodDef Methods[] = { - { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, }, - { "CopyToProto", (PyCFunction)CopyToProto, METH_O, }, - {NULL} + {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, + {nullptr}, }; } // namespace method_descriptor PyTypeObject PyMethodDescriptor_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MethodDescriptor", // tp_name - sizeof(PyBaseDescriptor), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Method Descriptor", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - method_descriptor::Methods, // tp_methods - 0, // tp_members - method_descriptor::Getters, // tp_getset - &descriptor::PyBaseDescriptor_Type, // tp_base + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".MethodDescriptor", // tp_name + sizeof(PyBaseDescriptor), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Method Descriptor", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + method_descriptor::Methods, // tp_methods + nullptr, // tp_members + method_descriptor::Getters, // tp_getset + &descriptor::PyBaseDescriptor_Type, // tp_base }; PyObject* PyMethodDescriptor_FromDescriptor( const MethodDescriptor* method_descriptor) { - return descriptor::NewInternedDescriptor( - &PyMethodDescriptor_Type, method_descriptor, NULL); + return descriptor::NewInternedDescriptor(&PyMethodDescriptor_Type, + method_descriptor, nullptr); } // Add a enum values to a type dictionary. @@ -1933,7 +2009,7 @@ static bool AddEnumValues(PyTypeObject *type, for (int i = 0; i < enum_descriptor->value_count(); ++i) { const EnumValueDescriptor* value = enum_descriptor->value(i); ScopedPyObjectPtr obj(PyLong_FromLong(value->number())); - if (obj == NULL) { + if (obj == nullptr) { return false; } if (PyDict_SetItemString(type->tp_dict, value->name().c_str(), obj.get()) < diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.h b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.h index 47efbe35d7..a383a7927a 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor.h @@ -33,6 +33,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/descriptor.h> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.cc index fe85b2e351..b17d8348bf 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.cc @@ -49,6 +49,7 @@ // because the Python API is based on C, and does not play well with C++ // inheritance. +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/descriptor.h> @@ -57,12 +58,13 @@ #include <google/protobuf/pyext/descriptor.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -157,59 +159,56 @@ namespace descriptor { // Returns the C++ item descriptor for a given Python key. // When the descriptor is found, return true and set *item. -// When the descriptor is not found, return true, but set *item to NULL. +// When the descriptor is not found, return true, but set *item to null. // On error, returns false with an exception set. static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { switch (self->kind) { - case PyContainer::KIND_BYNAME: - { - char* name; - Py_ssize_t name_size; - if (PyString_AsStringAndSize(key, &name, &name_size) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a string, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + case PyContainer::KIND_BYNAME: { + char* name; + Py_ssize_t name_size; + if (PyString_AsStringAndSize(key, &name, &name_size) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a string, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_name_fn( - self, StringParam(name, name_size)); - return true; + return false; } - case PyContainer::KIND_BYCAMELCASENAME: - { - char* camelcase_name; - Py_ssize_t name_size; - if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a string, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + *item = self->container_def->get_by_name_fn(self, + StringParam(name, name_size)); + return true; + } + case PyContainer::KIND_BYCAMELCASENAME: { + char* camelcase_name; + Py_ssize_t name_size; + if (PyString_AsStringAndSize(key, &camelcase_name, &name_size) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a string, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_camelcase_name_fn( - self, StringParam(camelcase_name, name_size)); - return true; + return false; } - case PyContainer::KIND_BYNUMBER: - { - Py_ssize_t number = PyNumber_AsSsize_t(key, NULL); - if (number == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - // Not a number, cannot be in the container. - PyErr_Clear(); - *item = NULL; - return true; - } - return false; + *item = self->container_def->get_by_camelcase_name_fn( + self, StringParam(camelcase_name, name_size)); + return true; + } + case PyContainer::KIND_BYNUMBER: { + Py_ssize_t number = PyNumber_AsSsize_t(key, nullptr); + if (number == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + // Not a number, cannot be in the container. + PyErr_Clear(); + *item = nullptr; + return true; } - *item = self->container_def->get_by_number_fn(self, number); - return true; + return false; } + *item = self->container_def->get_by_number_fn(self, number); + return true; + } default: PyErr_SetNone(PyExc_NotImplementedError); return false; @@ -221,25 +220,22 @@ static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { static PyObject* _NewKey_ByIndex(PyContainer* self, Py_ssize_t index) { const void* item = self->container_def->get_by_index_fn(self, index); switch (self->kind) { - case PyContainer::KIND_BYNAME: - { + case PyContainer::KIND_BYNAME: { const TProtoStringType& name(self->container_def->get_item_name_fn(item)); return PyUnicode_FromStringAndSize(name.c_str(), name.size()); - } - case PyContainer::KIND_BYCAMELCASENAME: - { + } + case PyContainer::KIND_BYCAMELCASENAME: { const TProtoStringType& name( self->container_def->get_item_camelcase_name_fn(item)); return PyUnicode_FromStringAndSize(name.c_str(), name.size()); - } - case PyContainer::KIND_BYNUMBER: - { - int value = self->container_def->get_item_number_fn(item); - return PyLong_FromLong(value); - } + } + case PyContainer::KIND_BYNUMBER: { + int value = self->container_def->get_item_number_fn(item); + return PyLong_FromLong(value); + } default: PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } } @@ -257,13 +253,13 @@ static Py_ssize_t Length(PyContainer* self) { // The DescriptorMapping type. static PyObject* Subscript(PyContainer* self, PyObject* key) { - const void* item = NULL; + const void* item = nullptr; if (!_GetItemByKey(self, key, &item)) { - return NULL; + return nullptr; } if (!item) { PyErr_SetObject(PyExc_KeyError, key); - return NULL; + return nullptr; } return self->container_def->new_object_from_item_fn(item); } @@ -285,7 +281,7 @@ static PyMappingMethods MappingMappingMethods = { }; static int Contains(PyContainer* self, PyObject* key) { - const void* item = NULL; + const void* item = nullptr; if (!_GetItemByKey(self, key, &item)) { return -1; } @@ -344,11 +340,11 @@ static int DescriptorSequence_Equal(PyContainer* self, PyObject* other) { } for (int index = 0; index < size; index++) { ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index)); - if (value1 == NULL) { + if (value1 == nullptr) { return -1; } PyObject* value2 = PyList_GetItem(other, index); - if (value2 == NULL) { + if (value2 == nullptr) { return -1; } int cmp = PyObject_RichCompareBool(value1.get(), value2, Py_EQ); @@ -388,15 +384,15 @@ static int DescriptorMapping_Equal(PyContainer* self, PyObject* other) { } for (int index = 0; index < size; index++) { ScopedPyObjectPtr key(_NewKey_ByIndex(self, index)); - if (key == NULL) { + if (key == nullptr) { return -1; } ScopedPyObjectPtr value1(_NewObj_ByIndex(self, index)); - if (value1 == NULL) { + if (value1 == nullptr) { return -1; } PyObject* value2 = PyDict_GetItem(other, key.get()); - if (value2 == NULL) { + if (value2 == nullptr) { // Not found in the other dictionary return 0; } @@ -426,7 +422,7 @@ static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) { result = DescriptorMapping_Equal(self, other); } if (result < 0) { - return NULL; + return nullptr; } if (result ^ (opid == Py_NE)) { Py_RETURN_TRUE; @@ -436,28 +432,28 @@ static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) { } static PySequenceMethods MappingSequenceMethods = { - 0, // sq_length - 0, // sq_concat - 0, // sq_repeat - 0, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice - (objobjproc)Contains, // sq_contains + nullptr, // sq_length + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + (objobjproc)Contains, // sq_contains }; static PyObject* Get(PyContainer* self, PyObject* args) { PyObject* key; PyObject* default_value = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &default_value)) { - return NULL; + return nullptr; } const void* item; if (!_GetItemByKey(self, key, &item)) { - return NULL; + return nullptr; } - if (item == NULL) { + if (item == nullptr) { Py_INCREF(default_value); return default_value; } @@ -467,13 +463,13 @@ static PyObject* Get(PyContainer* self, PyObject* args) { static PyObject* Keys(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { PyObject* key = _NewKey_ByIndex(self, index); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } PyList_SET_ITEM(list.get(), index, key); } @@ -483,13 +479,13 @@ static PyObject* Keys(PyContainer* self, PyObject* args) { static PyObject* Values(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { PyObject* value = _NewObj_ByIndex(self, index); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } PyList_SET_ITEM(list.get(), index, value); } @@ -499,22 +495,22 @@ static PyObject* Values(PyContainer* self, PyObject* args) { static PyObject* Items(PyContainer* self, PyObject* args) { Py_ssize_t count = Length(self); ScopedPyObjectPtr list(PyList_New(count)); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } for (Py_ssize_t index = 0; index < count; ++index) { ScopedPyObjectPtr obj(PyTuple_New(2)); - if (obj == NULL) { - return NULL; + if (obj == nullptr) { + return nullptr; } PyObject* key = _NewKey_ByIndex(self, index); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } PyTuple_SET_ITEM(obj.get(), 0, key); PyObject* value = _NewObj_ByIndex(self, index); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } PyTuple_SET_ITEM(obj.get(), 1, value); PyList_SET_ITEM(list.get(), index, obj.release()); @@ -539,56 +535,59 @@ static PyObject* IterItems(PyContainer* self, PyObject* args) { } static PyMethodDef MappingMethods[] = { - { "get", (PyCFunction)Get, METH_VARARGS, }, - { "keys", (PyCFunction)Keys, METH_NOARGS, }, - { "values", (PyCFunction)Values, METH_NOARGS, }, - { "items", (PyCFunction)Items, METH_NOARGS, }, - { "iterkeys", (PyCFunction)IterKeys, METH_NOARGS, }, - { "itervalues", (PyCFunction)IterValues, METH_NOARGS, }, - { "iteritems", (PyCFunction)IterItems, METH_NOARGS, }, - {NULL} + {"get", (PyCFunction)Get, METH_VARARGS}, + {"keys", (PyCFunction)Keys, METH_NOARGS}, + {"values", (PyCFunction)Values, METH_NOARGS}, + {"items", (PyCFunction)Items, METH_NOARGS}, + {"iterkeys", (PyCFunction)IterKeys, METH_NOARGS}, + {"itervalues", (PyCFunction)IterValues, METH_NOARGS}, + {"iteritems", (PyCFunction)IterItems, METH_NOARGS}, + {nullptr}, }; PyTypeObject DescriptorMapping_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorMapping", // tp_name - sizeof(PyContainer), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)ContainerRepr, // tp_repr - 0, // tp_as_number - &MappingSequenceMethods, // tp_as_sequence - &MappingMappingMethods, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - (getiterfunc)Iter, // tp_iter - 0, // tp_iternext - MappingMethods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, 0) "DescriptorMapping", // tp_name + sizeof(PyContainer), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)ContainerRepr, // tp_repr + nullptr, // tp_as_number + &MappingSequenceMethods, // tp_as_sequence + &MappingMappingMethods, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + (getiterfunc)Iter, // tp_iter + nullptr, // tp_iternext + MappingMethods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; // The DescriptorSequence type. @@ -599,7 +598,7 @@ static PyObject* GetItem(PyContainer* self, Py_ssize_t index) { } if (index < 0 || index >= Length(self)) { PyErr_SetString(PyExc_IndexError, "index out of range"); - return NULL; + return nullptr; } return _NewObj_ByIndex(self, index); } @@ -609,15 +608,14 @@ SeqSubscript(PyContainer* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t index; index = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (index == -1 && PyErr_Occurred()) - return NULL; + if (index == -1 && PyErr_Occurred()) return nullptr; return GetItem(self, index); } // Materialize the list and delegate the operation to it. ScopedPyObjectPtr list(PyObject_CallFunctionObjArgs( - reinterpret_cast<PyObject*>(&PyList_Type), self, NULL)); - if (list == NULL) { - return NULL; + reinterpret_cast<PyObject*>(&PyList_Type), self, nullptr)); + if (list == nullptr) { + return nullptr; } return Py_TYPE(list.get())->tp_as_mapping->mp_subscript(list.get(), item); } @@ -632,7 +630,7 @@ int Find(PyContainer* self, PyObject* item) { // a specific item belongs to only one sequence, depending on its position in // the .proto file definition. const void* descriptor_ptr = PyDescriptor_AsVoidPtr(item); - if (descriptor_ptr == NULL) { + if (descriptor_ptr == nullptr) { PyErr_Clear(); // Not a descriptor, it cannot be in the list. return -1; @@ -668,7 +666,7 @@ static PyObject* Index(PyContainer* self, PyObject* item) { if (position < 0) { // Not found PyErr_SetNone(PyExc_ValueError); - return NULL; + return nullptr; } else { return PyLong_FromLong(position); } @@ -701,7 +699,7 @@ static PyObject* Append(PyContainer* self, PyObject* args) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not a mutable sequence", Py_TYPE(self)->tp_name); - return NULL; + return nullptr; } static PyObject* Reversed(PyContainer* self, PyObject* args) { @@ -710,77 +708,80 @@ static PyObject* Reversed(PyContainer* self, PyObject* args) { } static PyMethodDef SeqMethods[] = { - { "index", (PyCFunction)Index, METH_O, }, - { "count", (PyCFunction)Count, METH_O, }, - { "append", (PyCFunction)Append, METH_O, }, - { "__reversed__", (PyCFunction)Reversed, METH_NOARGS, }, - {NULL} + {"index", (PyCFunction)Index, METH_O}, + {"count", (PyCFunction)Count, METH_O}, + {"append", (PyCFunction)Append, METH_O}, + {"__reversed__", (PyCFunction)Reversed, METH_NOARGS}, + {nullptr}, }; static PySequenceMethods SeqSequenceMethods = { - (lenfunc)Length, // sq_length - 0, // sq_concat - 0, // sq_repeat - (ssizeargfunc)GetItem, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice - (objobjproc)SeqContains, // sq_contains + (lenfunc)Length, // sq_length + nullptr, // sq_concat + nullptr, // sq_repeat + (ssizeargfunc)GetItem, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + (objobjproc)SeqContains, // sq_contains }; static PyMappingMethods SeqMappingMethods = { - (lenfunc)Length, // mp_length - (binaryfunc)SeqSubscript, // mp_subscript - 0, // mp_ass_subscript + (lenfunc)Length, // mp_length + (binaryfunc)SeqSubscript, // mp_subscript + nullptr, // mp_ass_subscript }; PyTypeObject DescriptorSequence_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorSequence", // tp_name - sizeof(PyContainer), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)ContainerRepr, // tp_repr - 0, // tp_as_number - &SeqSequenceMethods, // tp_as_sequence - &SeqMappingMethods, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - SeqMethods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, 0) "DescriptorSequence", // tp_name + sizeof(PyContainer), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)ContainerRepr, // tp_repr + nullptr, // tp_as_number + &SeqSequenceMethods, // tp_as_sequence + &SeqMappingMethods, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + SeqMethods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; static PyObject* NewMappingByName( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -791,8 +792,8 @@ static PyObject* NewMappingByName( static PyObject* NewMappingByCamelcaseName( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -802,14 +803,14 @@ static PyObject* NewMappingByCamelcaseName( static PyObject* NewMappingByNumber( DescriptorContainerDef* container_def, const void* descriptor) { - if (container_def->get_by_number_fn == NULL || - container_def->get_item_number_fn == NULL) { + if (container_def->get_by_number_fn == nullptr || + container_def->get_item_number_fn == nullptr) { PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } PyContainer* self = PyObject_New(PyContainer, &DescriptorMapping_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -820,8 +821,8 @@ static PyObject* NewMappingByNumber( static PyObject* NewSequence( DescriptorContainerDef* container_def, const void* descriptor) { PyContainer* self = PyObject_New(PyContainer, &DescriptorSequence_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } self->descriptor = descriptor; self->container_def = container_def; @@ -839,8 +840,8 @@ static void Iterator_Dealloc(PyContainerIterator* self) { static PyObject* Iterator_Next(PyContainerIterator* self) { int count = self->container->container_def->count_fn(self->container); if (self->index >= count) { - // Return NULL with no exception to indicate the end. - return NULL; + // Return null with no exception to indicate the end. + return nullptr; } int index = self->index; self->index += 1; @@ -851,80 +852,83 @@ static PyObject* Iterator_Next(PyContainerIterator* self) { return _NewObj_ByIndex(self->container, index); case PyContainerIterator::KIND_ITERVALUE_REVERSED: return _NewObj_ByIndex(self->container, count - index - 1); - case PyContainerIterator::KIND_ITERITEM: - { - PyObject* obj = PyTuple_New(2); - if (obj == NULL) { - return NULL; - } - PyObject* key = _NewKey_ByIndex(self->container, index); - if (key == NULL) { - Py_DECREF(obj); - return NULL; - } - PyTuple_SET_ITEM(obj, 0, key); - PyObject* value = _NewObj_ByIndex(self->container, index); - if (value == NULL) { - Py_DECREF(obj); - return NULL; - } - PyTuple_SET_ITEM(obj, 1, value); - return obj; + case PyContainerIterator::KIND_ITERITEM: { + PyObject* obj = PyTuple_New(2); + if (obj == nullptr) { + return nullptr; + } + PyObject* key = _NewKey_ByIndex(self->container, index); + if (key == nullptr) { + Py_DECREF(obj); + return nullptr; } + PyTuple_SET_ITEM(obj, 0, key); + PyObject* value = _NewObj_ByIndex(self->container, index); + if (value == nullptr) { + Py_DECREF(obj); + return nullptr; + } + PyTuple_SET_ITEM(obj, 1, value); + return obj; + } default: PyErr_SetNone(PyExc_NotImplementedError); - return NULL; + return nullptr; } } static PyTypeObject ContainerIterator_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "DescriptorContainerIterator", // tp_name - sizeof(PyContainerIterator), // tp_basicsize - 0, // tp_itemsize - (destructor)Iterator_Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - 0, // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, // tp_iter - (iternextfunc)Iterator_Next, // tp_iternext - 0, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new - 0, // tp_free + PyVarObject_HEAD_INIT(&PyType_Type, + 0) "DescriptorContainerIterator", // tp_name + sizeof(PyContainerIterator), // tp_basicsize + 0, // tp_itemsize + (destructor)Iterator_Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, // tp_iter + (iternextfunc)Iterator_Next, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_free }; static PyObject* NewContainerIterator(PyContainer* container, PyContainerIterator::IterKind kind) { PyContainerIterator* self = PyObject_New(PyContainerIterator, &ContainerIterator_Type); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(container); self->container = container; @@ -992,17 +996,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageFields", - Count, - GetByIndex, - GetByName, - GetByCamelcaseName, - GetByNumber, - NewObjectFromItem, - GetItemName, - GetItemCamelcaseName, - GetItemNumber, - GetItemIndex, + "MessageFields", Count, GetByIndex, GetByName, + GetByCamelcaseName, GetByNumber, NewObjectFromItem, GetItemName, + GetItemCamelcaseName, GetItemNumber, GetItemIndex, }; } // namespace fields @@ -1053,17 +1049,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageNestedTypes", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageNestedTypes", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace nested_types @@ -1105,17 +1101,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageNestedEnums", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageNestedEnums", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace enums @@ -1154,7 +1150,7 @@ static const void* GetByName(PyContainer* self, ConstStringParam name) { static const void* GetByIndex(PyContainer* self, int index) { // This is not optimal, but the number of enums *types* in a given message // is small. This function is only used when iterating over the mapping. - const EnumDescriptor* enum_type = NULL; + const EnumDescriptor* enum_type = nullptr; int enum_type_count = GetDescriptor(self)->enum_type_count(); for (int i = 0; i < enum_type_count; ++i) { enum_type = GetDescriptor(self)->enum_type(i); @@ -1180,17 +1176,8 @@ static const TProtoStringType& GetItemName(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageEnumValues", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - NULL, + "MessageEnumValues", Count, GetByIndex, GetByName, nullptr, nullptr, + NewObjectFromItem, GetItemName, nullptr, nullptr, nullptr, }; } // namespace enumvalues @@ -1228,17 +1215,17 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageExtensions", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageExtensions", + Count, + GetByIndex, + GetByName, + nullptr, + nullptr, + NewObjectFromItem, + GetItemName, + nullptr, + nullptr, + GetItemIndex, }; } // namespace extensions @@ -1280,17 +1267,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "MessageOneofs", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "MessageOneofs", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace oneofs @@ -1351,17 +1330,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "EnumValues", - Count, - GetByIndex, - GetByName, - NULL, - GetByNumber, - NewObjectFromItem, - GetItemName, - NULL, - GetItemNumber, - GetItemIndex, + "EnumValues", Count, GetByIndex, GetByName, + nullptr, GetByNumber, NewObjectFromItem, GetItemName, + nullptr, GetItemNumber, GetItemIndex, }; } // namespace enumvalues @@ -1409,17 +1380,8 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "OneofFields", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - GetItemIndex, + "OneofFields", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, GetItemIndex, }; } // namespace fields @@ -1467,17 +1429,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "ServiceMethods", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "ServiceMethods", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace methods @@ -1529,17 +1483,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileMessages", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileMessages", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace messages @@ -1577,17 +1523,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileEnums", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileEnums", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace enums @@ -1625,17 +1563,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileExtensions", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileExtensions", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace extensions @@ -1673,17 +1603,9 @@ static int GetItemIndex(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileServices", - Count, - GetByIndex, - GetByName, - NULL, - NULL, - NewObjectFromItem, - GetItemName, - NULL, - NULL, - GetItemIndex, + "FileServices", Count, GetByIndex, GetByName, + nullptr, nullptr, NewObjectFromItem, GetItemName, + nullptr, nullptr, GetItemIndex, }; } // namespace services @@ -1709,17 +1631,8 @@ static PyObject* NewObjectFromItem(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FileDependencies", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - NULL, + "FileDependencies", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, nullptr, }; } // namespace dependencies @@ -1745,17 +1658,8 @@ static PyObject* NewObjectFromItem(const void* item) { } static DescriptorContainerDef ContainerDef = { - "FilePublicDependencies", - Count, - GetByIndex, - NULL, - NULL, - NULL, - NewObjectFromItem, - NULL, - NULL, - NULL, - NULL, + "FilePublicDependencies", Count, GetByIndex, nullptr, nullptr, nullptr, + NewObjectFromItem, nullptr, nullptr, nullptr, nullptr, }; } // namespace public_dependencies diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.h b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.h index 4e05c58e2b..cf2cf4ad0b 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_containers.h @@ -34,6 +34,7 @@ // Mappings and Sequences of descriptors. // They implement containers like fields_by_name, EnumDescriptor.values... // See descriptor_containers.cc for more description. +#define PY_SSIZE_T_CLEAN #include <Python.h> namespace google { diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.cc index be8089841c..14f5bf2230 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.cc @@ -56,7 +56,7 @@ PyDescriptorDatabase::~PyDescriptorDatabase() { Py_DECREF(py_database_); } // Handles all kinds of Python errors, which are simply logged. static bool GetFileDescriptorProto(PyObject* py_descriptor, FileDescriptorProto* output) { - if (py_descriptor == NULL) { + if (py_descriptor == nullptr) { if (PyErr_ExceptionMatches(PyExc_KeyError)) { // Expected error: item was simply not found. PyErr_Clear(); @@ -83,8 +83,8 @@ static bool GetFileDescriptorProto(PyObject* py_descriptor, // Slow path: serialize the message. This allows to use databases which // use a different implementation of FileDescriptorProto. ScopedPyObjectPtr serialized_pb( - PyObject_CallMethod(py_descriptor, "SerializeToString", NULL)); - if (serialized_pb == NULL) { + PyObject_CallMethod(py_descriptor, "SerializeToString", nullptr)); + if (serialized_pb == nullptr) { GOOGLE_LOG(ERROR) << "DescriptorDatabase method did not return a FileDescriptorProto"; PyErr_Print(); @@ -134,7 +134,7 @@ bool PyDescriptorDatabase::FindFileContainingExtension( FileDescriptorProto* output) { ScopedPyObjectPtr py_method( PyObject_GetAttrString(py_database_, "FindFileContainingExtension")); - if (py_method == NULL) { + if (py_method == nullptr) { // This method is not implemented, returns without error. PyErr_Clear(); return false; @@ -153,7 +153,7 @@ bool PyDescriptorDatabase::FindAllExtensionNumbers( const TProtoStringType& containing_type, std::vector<int>* output) { ScopedPyObjectPtr py_method( PyObject_GetAttrString(py_database_, "FindAllExtensionNumbers")); - if (py_method == NULL) { + if (py_method == nullptr) { // This method is not implemented, returns without error. PyErr_Clear(); return false; @@ -161,7 +161,7 @@ bool PyDescriptorDatabase::FindAllExtensionNumbers( ScopedPyObjectPtr py_list( PyObject_CallFunction(py_method.get(), "s#", containing_type.c_str(), containing_type.size())); - if (py_list == NULL) { + if (py_list == nullptr) { PyErr_Print(); return false; } diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.h b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.h index 59918a6d92..08318ff98f 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_database.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/descriptor_database.h> @@ -42,17 +43,18 @@ namespace python { class PyDescriptorDatabase : public DescriptorDatabase { public: explicit PyDescriptorDatabase(PyObject* py_database); - ~PyDescriptorDatabase(); + ~PyDescriptorDatabase() override; // Implement the abstract interface. All these functions fill the output // with a copy of FileDescriptorProto. // Find a file by file name. - bool FindFileByName(const TProtoStringType& filename, FileDescriptorProto* output); + bool FindFileByName(const TProtoStringType& filename, + FileDescriptorProto* output) override; // Find the file that declares the given fully-qualified symbol name. bool FindFileContainingSymbol(const TProtoStringType& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; // Find the file which defines an extension extending the given message type // with the given field number. @@ -60,14 +62,14 @@ class PyDescriptorDatabase : public DescriptorDatabase { // Python objects are not required to implement this method. bool FindFileContainingExtension(const TProtoStringType& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; // Finds the tag numbers used by all known extensions of // containing_type, and appends them to output in an undefined // order. // Python objects are not required to implement this method. bool FindAllExtensionNumbers(const TProtoStringType& containing_type, - std::vector<int>* output); + std::vector<int>* output) override; private: // The python object that implements the database. The reference is owned. diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.cc index 1ba01d55d8..2dd47bdb23 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.cc @@ -32,6 +32,7 @@ #include <unordered_map> +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/descriptor.pb.h> @@ -43,12 +44,13 @@ #include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include <google/protobuf/stubs/hash.h> -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -98,13 +100,13 @@ class BuildFileErrorCollector : public DescriptorPool::ErrorCollector { static PyDescriptorPool* _CreateDescriptorPool() { PyDescriptorPool* cpool = PyObject_GC_New( PyDescriptorPool, &PyDescriptorPool_Type); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } cpool->error_collector = nullptr; - cpool->underlay = NULL; - cpool->database = NULL; + cpool->underlay = nullptr; + cpool->database = nullptr; cpool->is_owned = false; cpool->is_mutable = false; @@ -112,9 +114,9 @@ static PyDescriptorPool* _CreateDescriptorPool() { cpool->py_message_factory = message_factory::NewMessageFactory( &PyMessageFactory_Type, cpool); - if (cpool->py_message_factory == NULL) { + if (cpool->py_message_factory == nullptr) { Py_DECREF(cpool); - return NULL; + return nullptr; } PyObject_GC_Track(cpool); @@ -130,8 +132,8 @@ static PyDescriptorPool* _CreateDescriptorPool() { static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( const DescriptorPool* underlay) { PyDescriptorPool* cpool = _CreateDescriptorPool(); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } cpool->pool = new DescriptorPool(underlay); cpool->is_owned = true; @@ -142,7 +144,7 @@ static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( std::make_pair(cpool->pool, cpool)).second) { // Should never happen -- would indicate an internal error / bug. PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered"); - return NULL; + return nullptr; } return cpool; @@ -151,10 +153,10 @@ static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay( static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( DescriptorDatabase* database) { PyDescriptorPool* cpool = _CreateDescriptorPool(); - if (cpool == NULL) { - return NULL; + if (cpool == nullptr) { + return nullptr; } - if (database != NULL) { + if (database != nullptr) { cpool->error_collector = new BuildFileErrorCollector(); cpool->pool = new DescriptorPool(database, cpool->error_collector); cpool->is_mutable = false; @@ -168,7 +170,7 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( if (!descriptor_pool_map->insert(std::make_pair(cpool->pool, cpool)).second) { // Should never happen -- would indicate an internal error / bug. PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered"); - return NULL; + return nullptr; } return cpool; @@ -177,13 +179,13 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase( // The public DescriptorPool constructor. static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"descriptor_db", 0}; - PyObject* py_database = NULL; + static const char* kwlist[] = {"descriptor_db", nullptr}; + PyObject* py_database = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast<char**>(kwlist), &py_database)) { - return NULL; + return nullptr; } - DescriptorDatabase* database = NULL; + DescriptorDatabase* database = nullptr; if (py_database && py_database != Py_None) { database = new PyDescriptorDatabase(py_database); } @@ -232,24 +234,24 @@ PyObject* SetErrorFromCollector(DescriptorPool::ErrorCollector* self, PyErr_Format(PyExc_KeyError, "Couldn't build file for %s %.200s\n%s", error_type, name, error_collector->error_message.c_str()); error_collector->Clear(); - return NULL; + return nullptr; } PyErr_Format(PyExc_KeyError, "Couldn't find %s %.200s", error_type, name); - return NULL; + return nullptr; } static PyObject* FindMessageByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const Descriptor* message_descriptor = reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName( StringParam(name, name_size)); - if (message_descriptor == NULL) { + if (message_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name, "message"); @@ -266,14 +268,14 @@ static PyObject* FindFileByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } PyDescriptorPool* py_pool = reinterpret_cast<PyDescriptorPool*>(self); const FileDescriptor* file_descriptor = py_pool->pool->FindFileByName(StringParam(name, name_size)); - if (file_descriptor == NULL) { + if (file_descriptor == nullptr) { return SetErrorFromCollector(py_pool->error_collector, name, "file"); } return PyFileDescriptor_FromDescriptor(file_descriptor); @@ -283,12 +285,12 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FieldDescriptor* field_descriptor = self->pool->FindFieldByName(StringParam(name, name_size)); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "field"); } @@ -304,12 +306,12 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FieldDescriptor* field_descriptor = self->pool->FindExtensionByName(StringParam(name, name_size)); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "extension field"); } @@ -326,12 +328,12 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const EnumDescriptor* enum_descriptor = self->pool->FindEnumTypeByName(StringParam(name, name_size)); - if (enum_descriptor == NULL) { + if (enum_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "enum"); } @@ -347,12 +349,12 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const OneofDescriptor* oneof_descriptor = self->pool->FindOneofByName(StringParam(name, name_size)); - if (oneof_descriptor == NULL) { + if (oneof_descriptor == nullptr) { return SetErrorFromCollector(self->error_collector, name, "oneof"); } @@ -368,13 +370,13 @@ static PyObject* FindServiceByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const ServiceDescriptor* service_descriptor = reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName( StringParam(name, name_size)); - if (service_descriptor == NULL) { + if (service_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name, "service"); @@ -388,13 +390,13 @@ static PyObject* FindMethodByName(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const MethodDescriptor* method_descriptor = reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName( StringParam(name, name_size)); - if (method_descriptor == NULL) { + if (method_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name, "method"); @@ -408,13 +410,13 @@ static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) { Py_ssize_t name_size; char* name; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } const FileDescriptor* file_descriptor = reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol( StringParam(name, name_size)); - if (file_descriptor == NULL) { + if (file_descriptor == nullptr) { return SetErrorFromCollector( reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name, "symbol"); @@ -428,18 +430,18 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { PyObject* message_descriptor; int number; if (!PyArg_ParseTuple(args, "Oi", &message_descriptor, &number)) { - return NULL; + return nullptr; } const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor( message_descriptor); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } const FieldDescriptor* extension_descriptor = reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber( descriptor, number); - if (extension_descriptor == NULL) { + if (extension_descriptor == nullptr) { BuildFileErrorCollector* error_collector = reinterpret_cast<BuildFileErrorCollector*>( reinterpret_cast<PyDescriptorPool*>(self)->error_collector); @@ -447,10 +449,10 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { PyErr_Format(PyExc_KeyError, "Couldn't build file for Extension %.d\n%s", number, error_collector->error_message.c_str()); error_collector->Clear(); - return NULL; + return nullptr; } PyErr_Format(PyExc_KeyError, "Couldn't find Extension %d", number); - return NULL; + return nullptr; } @@ -459,8 +461,8 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) { static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) { const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(arg); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } std::vector<const FieldDescriptor*> extensions; @@ -468,13 +470,13 @@ static PyObject* FindAllExtensions(PyObject* self, PyObject* arg) { descriptor, &extensions); ScopedPyObjectPtr result(PyList_New(extensions.size())); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } for (int i = 0; i < extensions.size(); i++) { PyObject* extension = PyFieldDescriptor_FromDescriptor(extensions[i]); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } PyList_SET_ITEM(result.get(), i, extension); // Steals the reference. } @@ -494,7 +496,7 @@ static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) { const FileDescriptor* file_descriptor = PyFileDescriptor_AsDescriptor(descriptor); if (!file_descriptor) { - return NULL; + return nullptr; } if (file_descriptor != reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName( @@ -502,7 +504,7 @@ static PyObject* AddFileDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The file descriptor %s does not belong to this pool", file_descriptor->name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -511,7 +513,7 @@ static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) { const Descriptor* message_descriptor = PyMessageDescriptor_AsDescriptor(descriptor); if (!message_descriptor) { - return NULL; + return nullptr; } if (message_descriptor != reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMessageTypeByName( @@ -519,7 +521,7 @@ static PyObject* AddDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The message descriptor %s does not belong to this pool", message_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -528,7 +530,7 @@ static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) { const EnumDescriptor* enum_descriptor = PyEnumDescriptor_AsDescriptor(descriptor); if (!enum_descriptor) { - return NULL; + return nullptr; } if (enum_descriptor != reinterpret_cast<PyDescriptorPool*>(self)->pool->FindEnumTypeByName( @@ -536,7 +538,7 @@ static PyObject* AddEnumDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The enum descriptor %s does not belong to this pool", enum_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -545,7 +547,7 @@ static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) { const FieldDescriptor* extension_descriptor = PyFieldDescriptor_AsDescriptor(descriptor); if (!extension_descriptor) { - return NULL; + return nullptr; } if (extension_descriptor != reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByName( @@ -553,7 +555,7 @@ static PyObject* AddExtensionDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The extension descriptor %s does not belong to this pool", extension_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -562,7 +564,7 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) { const ServiceDescriptor* service_descriptor = PyServiceDescriptor_AsDescriptor(descriptor); if (!service_descriptor) { - return NULL; + return nullptr; } if (service_descriptor != reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName( @@ -570,7 +572,7 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) { PyErr_Format(PyExc_ValueError, "The service descriptor %s does not belong to this pool", service_descriptor->full_name().c_str()); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -581,12 +583,12 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { char* message_type; Py_ssize_t message_len; - if (self->database != NULL) { + if (self->database != nullptr) { PyErr_SetString( PyExc_ValueError, "Cannot call Add on a DescriptorPool that uses a DescriptorDatabase. " "Add your file to the underlying database."); - return NULL; + return nullptr; } if (!self->is_mutable) { PyErr_SetString( @@ -596,22 +598,22 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { } if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) { - return NULL; + return nullptr; } FileDescriptorProto file_proto; if (!file_proto.ParseFromArray(message_type, message_len)) { PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); - return NULL; + return nullptr; } // If the file was already part of a C++ library, all its descriptors are in // the underlying pool. No need to do anything else. - const FileDescriptor* generated_file = NULL; + const FileDescriptor* generated_file = nullptr; if (self->underlay) { generated_file = self->underlay->FindFileByName(file_proto.name()); } - if (generated_file != NULL) { + if (generated_file != nullptr) { return PyFileDescriptor_FromDescriptorWithSerializedPb( generated_file, serialized_pb); } @@ -621,11 +623,11 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { // Pool is mutable, we can remove the "const". const_cast<DescriptorPool*>(self->pool) ->BuildFileCollectingErrors(file_proto, &error_collector); - if (descriptor == NULL) { + if (descriptor == nullptr) { PyErr_Format(PyExc_TypeError, "Couldn't build proto file into descriptor pool!\n%s", error_collector.error_message.c_str()); - return NULL; + return nullptr; } @@ -635,105 +637,109 @@ static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) { static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) { ScopedPyObjectPtr serialized_pb( - PyObject_CallMethod(file_descriptor_proto, "SerializeToString", NULL)); - if (serialized_pb == NULL) { - return NULL; + PyObject_CallMethod(file_descriptor_proto, "SerializeToString", nullptr)); + if (serialized_pb == nullptr) { + return nullptr; } return AddSerializedFile(self, serialized_pb.get()); } static PyMethodDef Methods[] = { - { "Add", Add, METH_O, - "Adds the FileDescriptorProto and its types to this pool." }, - { "AddSerializedFile", AddSerializedFile, METH_O, - "Adds a serialized FileDescriptorProto to this pool." }, - - // TODO(amauryfa): Understand why the Python implementation differs from - // this one, ask users to use another API and deprecate these functions. - { "AddFileDescriptor", AddFileDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddDescriptor", AddDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddEnumDescriptor", AddEnumDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddExtensionDescriptor", AddExtensionDescriptor, METH_O, - "No-op. Add() must have been called before." }, - { "AddServiceDescriptor", AddServiceDescriptor, METH_O, - "No-op. Add() must have been called before." }, - - { "FindFileByName", FindFileByName, METH_O, - "Searches for a file descriptor by its .proto name." }, - { "FindMessageTypeByName", FindMessageByName, METH_O, - "Searches for a message descriptor by full name." }, - { "FindFieldByName", FindFieldByNameMethod, METH_O, - "Searches for a field descriptor by full name." }, - { "FindExtensionByName", FindExtensionByNameMethod, METH_O, - "Searches for extension descriptor by full name." }, - { "FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O, - "Searches for enum type descriptor by full name." }, - { "FindOneofByName", FindOneofByNameMethod, METH_O, - "Searches for oneof descriptor by full name." }, - { "FindServiceByName", FindServiceByName, METH_O, - "Searches for service descriptor by full name." }, - { "FindMethodByName", FindMethodByName, METH_O, - "Searches for method descriptor by full name." }, - - { "FindFileContainingSymbol", FindFileContainingSymbol, METH_O, - "Gets the FileDescriptor containing the specified symbol." }, - { "FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS, - "Gets the extension descriptor for the given number." }, - { "FindAllExtensions", FindAllExtensions, METH_O, - "Gets all known extensions of the given message descriptor." }, - {NULL} + {"Add", Add, METH_O, + "Adds the FileDescriptorProto and its types to this pool."}, + {"AddSerializedFile", AddSerializedFile, METH_O, + "Adds a serialized FileDescriptorProto to this pool."}, + + // TODO(amauryfa): Understand why the Python implementation differs from + // this one, ask users to use another API and deprecate these functions. + {"AddFileDescriptor", AddFileDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddDescriptor", AddDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddEnumDescriptor", AddEnumDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddExtensionDescriptor", AddExtensionDescriptor, METH_O, + "No-op. Add() must have been called before."}, + {"AddServiceDescriptor", AddServiceDescriptor, METH_O, + "No-op. Add() must have been called before."}, + + {"FindFileByName", FindFileByName, METH_O, + "Searches for a file descriptor by its .proto name."}, + {"FindMessageTypeByName", FindMessageByName, METH_O, + "Searches for a message descriptor by full name."}, + {"FindFieldByName", FindFieldByNameMethod, METH_O, + "Searches for a field descriptor by full name."}, + {"FindExtensionByName", FindExtensionByNameMethod, METH_O, + "Searches for extension descriptor by full name."}, + {"FindEnumTypeByName", FindEnumTypeByNameMethod, METH_O, + "Searches for enum type descriptor by full name."}, + {"FindOneofByName", FindOneofByNameMethod, METH_O, + "Searches for oneof descriptor by full name."}, + {"FindServiceByName", FindServiceByName, METH_O, + "Searches for service descriptor by full name."}, + {"FindMethodByName", FindMethodByName, METH_O, + "Searches for method descriptor by full name."}, + + {"FindFileContainingSymbol", FindFileContainingSymbol, METH_O, + "Gets the FileDescriptor containing the specified symbol."}, + {"FindExtensionByNumber", FindExtensionByNumber, METH_VARARGS, + "Gets the extension descriptor for the given number."}, + {"FindAllExtensions", FindAllExtensions, METH_O, + "Gets all known extensions of the given message descriptor."}, + {nullptr}, }; } // namespace cdescriptor_pool PyTypeObject PyDescriptorPool_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".DescriptorPool", // tp_name - sizeof(PyDescriptorPool), // tp_basicsize - 0, // tp_itemsize - cdescriptor_pool::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + ".DescriptorPool", // tp_name + sizeof(PyDescriptorPool), // tp_basicsize + 0, // tp_itemsize + cdescriptor_pool::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags "A Descriptor Pool", // tp_doc cdescriptor_pool::GcTraverse, // tp_traverse cdescriptor_pool::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + nullptr, // tp_iter + nullptr, // tp_iternext cdescriptor_pool::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc cdescriptor_pool::New, // tp_new PyObject_GC_Del, // tp_free }; // This is the DescriptorPool which contains all the definitions from the // generated _pb2.py modules. -static PyDescriptorPool* python_generated_pool = NULL; +static PyDescriptorPool* python_generated_pool = nullptr; bool InitDescriptorPool() { if (PyType_Ready(&PyDescriptorPool_Type) < 0) @@ -746,7 +752,7 @@ bool InitDescriptorPool() { new std::unordered_map<const DescriptorPool*, PyDescriptorPool*>; python_generated_pool = cdescriptor_pool::PyDescriptorPool_NewWithUnderlay( DescriptorPool::generated_pool()); - if (python_generated_pool == NULL) { + if (python_generated_pool == nullptr) { delete descriptor_pool_map; return false; } @@ -777,7 +783,7 @@ PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool) { descriptor_pool_map->find(pool); if (it == descriptor_pool_map->end()) { PyErr_SetString(PyExc_KeyError, "Unknown descriptor pool"); - return NULL; + return nullptr; } return it->second; } diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.h b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.h index 48658d3e88..5d3c3a95cc 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/descriptor_pool.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <unordered_map> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.cc index b36c723266..692029f682 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.cc @@ -49,12 +49,13 @@ #include <google/protobuf/pyext/repeated_scalar_container.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -130,11 +131,11 @@ static void DeallocExtensionIterator(PyObject* _self) { PyObject* subscript(ExtensionDict* self, PyObject* key) { const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) { - return NULL; + return nullptr; } if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && @@ -154,8 +155,8 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) { // TODO(plabatut): consider building the class on the fly! ContainerBase* sub_message = cmessage::InternalGetSubMessage( self->parent, descriptor); - if (sub_message == NULL) { - return NULL; + if (sub_message == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = sub_message; return sub_message->AsPyObject(); @@ -178,33 +179,33 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) { descriptor->message_type()); ScopedPyObjectPtr message_class_handler( reinterpret_cast<PyObject*>(message_class)); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } ContainerBase* py_container = repeated_composite_container::NewContainer( self->parent, descriptor, message_class); - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = py_container; return py_container->AsPyObject(); } else { ContainerBase* py_container = repeated_scalar_container::NewContainer( self->parent, descriptor); - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } (*self->parent->composite_fields)[descriptor] = py_container; return py_container->AsPyObject(); } } PyErr_SetString(PyExc_ValueError, "control reached unexpected line"); - return NULL; + return nullptr; } int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) { const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); - if (descriptor == NULL) { + if (descriptor == nullptr) { return -1; } if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) { @@ -232,13 +233,13 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { char* name; Py_ssize_t name_size; if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { - return NULL; + return nullptr; } PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; const FieldDescriptor* message_extension = pool->pool->FindExtensionByName(StringParam(name, name_size)); - if (message_extension == NULL) { + if (message_extension == nullptr) { // Is is the name of a message set extension? const Descriptor* message_descriptor = pool->pool->FindMessageTypeByName(StringParam(name, name_size)); @@ -252,7 +253,7 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { } } } - if (message_extension == NULL) { + if (message_extension == nullptr) { Py_RETURN_NONE; } @@ -262,13 +263,13 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) { int64_t number = PyLong_AsLong(arg); if (number == -1 && PyErr_Occurred()) { - return NULL; + return nullptr; } PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber( self->parent->message->GetDescriptor(), number); - if (message_extension == NULL) { + if (message_extension == nullptr) { Py_RETURN_NONE; } @@ -307,8 +308,8 @@ static int Contains(PyObject* _self, PyObject* key) { ExtensionDict* NewExtensionDict(CMessage *parent) { ExtensionDict* self = reinterpret_cast<ExtensionDict*>( PyType_GenericAlloc(&ExtensionDict_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -340,12 +341,12 @@ static PyObject* RichCompare(ExtensionDict* self, PyObject* other, int opid) { } static PySequenceMethods SeqMethods = { (lenfunc)len, // sq_length - 0, // sq_concat - 0, // sq_repeat - 0, // sq_item - 0, // sq_slice - 0, // sq_ass_item - 0, // sq_ass_slice + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice (objobjproc)Contains, // sq_contains }; @@ -360,48 +361,52 @@ static PyMethodDef Methods[] = { EDMETHOD(_FindExtensionByName, METH_O, "Finds an extension by name."), EDMETHOD(_FindExtensionByNumber, METH_O, "Finds an extension by field number."), - {NULL, NULL}, + {nullptr, nullptr}, }; } // namespace extension_dict PyTypeObject ExtensionDict_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) // - FULL_MODULE_NAME ".ExtensionDict", // tp_name - sizeof(ExtensionDict), // tp_basicsize - 0, // tp_itemsize - (destructor)extension_dict::dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number + PyVarObject_HEAD_INIT(&PyType_Type, 0) // + FULL_MODULE_NAME ".ExtensionDict", // tp_name + sizeof(ExtensionDict), // tp_basicsize + 0, // tp_itemsize + (destructor)extension_dict::dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number &extension_dict::SeqMethods, // tp_as_sequence &extension_dict::MpMethods, // tp_as_mapping PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT, // tp_flags "An extension dict", // tp_doc - 0, // tp_traverse - 0, // tp_clear + nullptr, // tp_traverse + nullptr, // tp_clear (richcmpfunc)extension_dict::RichCompare, // tp_richcompare 0, // tp_weaklistoffset extension_dict::GetIter, // tp_iter - 0, // tp_iternext + nullptr, // tp_iternext extension_dict::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init + nullptr, // tp_init }; PyObject* IterNext(PyObject* _self) { @@ -438,37 +443,41 @@ PyTypeObject ExtensionIterator_Type = { sizeof(extension_dict::ExtensionIterator), // tp_basicsize 0, // tp_itemsize extension_dict::DeallocExtensionIterator, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A scalar map iterator", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, // tp_iter - IterNext, // tp_iternext - 0, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A scalar map iterator", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, // tp_iter + IterNext, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; } // namespace python } // namespace protobuf diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.h b/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.h index c9da443161..a0581941bd 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/extension_dict.h @@ -34,6 +34,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <memory> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/field.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/field.cc index 5eab3ef2bc..0d3b0b9607 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/field.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/field.cc @@ -47,7 +47,7 @@ static PyObject* Repr(PyMessageFieldProperty* self) { static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj, PyObject* type) { - if (obj == NULL) { + if (obj == nullptr) { Py_INCREF(self); return reinterpret_cast<PyObject*>(self); } @@ -57,7 +57,7 @@ static PyObject* DescrGet(PyMessageFieldProperty* self, PyObject* obj, static int DescrSet(PyMessageFieldProperty* self, PyObject* obj, PyObject* value) { - if (value == NULL) { + if (value == nullptr) { PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute"); return -1; } @@ -75,50 +75,55 @@ static PyObject* GetDoc(PyMessageFieldProperty* self, void* closure) { } static PyGetSetDef Getters[] = { - {"DESCRIPTOR", (getter)GetDescriptor, NULL, "Field descriptor"}, - {"__doc__", (getter)GetDoc, NULL, NULL}, - {NULL}}; + {"DESCRIPTOR", (getter)GetDescriptor, nullptr, "Field descriptor"}, + {"__doc__", (getter)GetDoc, nullptr, nullptr}, + {nullptr}, +}; } // namespace field static PyTypeObject _CFieldProperty_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) // head - FULL_MODULE_NAME ".FieldProperty", // tp_name - sizeof(PyMessageFieldProperty), // tp_basicsize - 0, // tp_itemsize - 0, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)field::Repr, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "Field property of a Message", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members - field::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - (descrgetfunc)field::DescrGet, // tp_descr_get - (descrsetfunc)field::DescrSet, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc - 0, // tp_new + PyVarObject_HEAD_INIT(&PyType_Type, 0) // head + FULL_MODULE_NAME ".FieldProperty", // tp_name + sizeof(PyMessageFieldProperty), // tp_basicsize + 0, // tp_itemsize + nullptr, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)field::Repr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "Field property of a Message", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + field::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + (descrgetfunc)field::DescrGet, // tp_descr_get + (descrsetfunc)field::DescrSet, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new }; PyTypeObject* CFieldProperty_Type = &_CFieldProperty_Type; @@ -126,8 +131,8 @@ PyObject* NewFieldProperty(const FieldDescriptor* field_descriptor) { // Create a new descriptor object PyMessageFieldProperty* property = PyObject_New(PyMessageFieldProperty, CFieldProperty_Type); - if (property == NULL) { - return NULL; + if (property == nullptr) { + return nullptr; } property->field_descriptor = field_descriptor; return reinterpret_cast<PyObject*>(property); diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/field.h b/contrib/python/protobuf/py3/google/protobuf/pyext/field.h index 7b4660cab5..f9f94c4983 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/field.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/field.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_FIELD_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_FIELD_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> namespace google { diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.cc index 94a5e2dad9..2c22e022d0 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.cc @@ -187,7 +187,7 @@ static PyObject* MapKeyToPython(MapContainer* self, const MapKey& key) { PyErr_Format( PyExc_SystemError, "Couldn't convert type %d to value", field_descriptor->cpp_type()); - return NULL; + return nullptr; } } @@ -219,7 +219,7 @@ PyObject* MapValueRefToPython(MapContainer* self, const MapValueRef& value) { PyErr_Format( PyExc_SystemError, "Couldn't convert type %d to value", field_descriptor->cpp_type()); - return NULL; + return nullptr; } } @@ -283,7 +283,7 @@ static bool PythonToMapValueRef(MapContainer* self, PyObject* obj, const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { value_ref->SetEnumValue(value); return true; } else { @@ -362,7 +362,7 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { MapKey map_key; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->ContainsMapKey(*message, self->parent_field_descriptor, @@ -378,14 +378,14 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { MapContainer* NewScalarMapContainer( CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } PyObject* obj(PyType_GenericAlloc(ScalarMapContainer_Type, 0)); - if (obj == NULL) { + if (obj == nullptr) { PyErr_Format(PyExc_RuntimeError, "Could not allocate new container."); - return NULL; + return nullptr; } MapContainer* self = GetMap(obj); @@ -408,7 +408,7 @@ PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self, MapValueRef value; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, @@ -432,12 +432,12 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, return -1; } - self->version++; - if (v) { // Set item to v. - reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, - map_key, &value); + if (reflection->InsertOrLookupMapValue( + message, self->parent_field_descriptor, map_key, &value)) { + self->version++; + } if (!PythonToMapValueRef(self, v, reflection->SupportsUnknownEnumValues(), &value)) { @@ -448,6 +448,7 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, // Delete key from map. if (reflection->DeleteMapValue(message, self->parent_field_descriptor, map_key)) { + self->version++; return 0; } else { PyErr_Format(PyExc_KeyError, "Key not present in map"); @@ -460,22 +461,22 @@ static PyObject* ScalarMapGet(PyObject* self, PyObject* args, PyObject* kwargs) { static const char* kwlist[] = {"key", "default", nullptr}; PyObject* key; - PyObject* default_value = NULL; + PyObject* default_value = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast<char**>(kwlist), &key, &default_value)) { - return NULL; + return nullptr; } ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key)); - if (is_present.get() == NULL) { - return NULL; + if (is_present.get() == nullptr) { + return nullptr; } if (PyObject_IsTrue(is_present.get())) { return MapReflectionFriend::ScalarMapGetItem(self, key); } else { - if (default_value != NULL) { + if (default_value != nullptr) { Py_INCREF(default_value); return default_value; } else { @@ -486,8 +487,8 @@ static PyObject* ScalarMapGet(PyObject* self, PyObject* args, PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) { ScopedPyObjectPtr dict(PyDict_New()); - if (dict == NULL) { - return NULL; + if (dict == nullptr) { + return nullptr; } ScopedPyObjectPtr key; ScopedPyObjectPtr value; @@ -500,15 +501,15 @@ PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) { it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { key.reset(MapKeyToPython(self, it.GetKey())); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } value.reset(MapValueRefToPython(self, it.GetValueRef())); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) { - return NULL; + return nullptr; } } return PyObject_Repr(dict.get()); @@ -545,7 +546,7 @@ static PyMethodDef ScalarMapMethods[] = { { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, "Outputs picklable representation of the repeated field." }, */ - {NULL, NULL}, + {nullptr, nullptr}, }; PyTypeObject* ScalarMapContainer_Type; @@ -557,7 +558,7 @@ static PyType_Slot ScalarMapContainer_Type_slots[] = { {Py_tp_methods, (void*)ScalarMapMethods}, {Py_tp_iter, (void*)MapReflectionFriend::GetIterator}, {Py_tp_repr, (void*)MapReflectionFriend::ScalarMapToStr}, - {0, 0}, + {0, nullptr}, }; PyType_Spec ScalarMapContainer_Type_spec = { @@ -582,13 +583,13 @@ MessageMapContainer* NewMessageMapContainer( CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor, CMessageClass* message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } PyObject* obj = PyType_GenericAlloc(MessageMapContainer_Type, 0); - if (obj == NULL) { + if (obj == nullptr) { PyErr_SetString(PyExc_RuntimeError, "Could not allocate new container."); - return NULL; + return nullptr; } MessageMapContainer* self = GetMessageMap(obj); @@ -663,7 +664,7 @@ PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self, MapValueRef value; if (!PythonToMapKey(self, key, &map_key)) { - return NULL; + return nullptr; } if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, @@ -676,8 +677,8 @@ PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self, PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { ScopedPyObjectPtr dict(PyDict_New()); - if (dict == NULL) { - return NULL; + if (dict == nullptr) { + return nullptr; } ScopedPyObjectPtr key; ScopedPyObjectPtr value; @@ -690,15 +691,15 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { key.reset(MapKeyToPython(self, it.GetKey())); - if (key == NULL) { - return NULL; + if (key == nullptr) { + return nullptr; } value.reset(GetCMessage(self, it.MutableValueRef()->MutableMessageValue())); - if (value == NULL) { - return NULL; + if (value == nullptr) { + return nullptr; } if (PyDict_SetItem(dict.get(), key.get(), value.get()) < 0) { - return NULL; + return nullptr; } } return PyObject_Repr(dict.get()); @@ -707,22 +708,22 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) { static const char* kwlist[] = {"key", "default", nullptr}; PyObject* key; - PyObject* default_value = NULL; + PyObject* default_value = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast<char**>(kwlist), &key, &default_value)) { - return NULL; + return nullptr; } ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key)); - if (is_present.get() == NULL) { - return NULL; + if (is_present.get() == nullptr) { + return nullptr; } if (PyObject_IsTrue(is_present.get())) { return MapReflectionFriend::MessageMapGetItem(self, key); } else { - if (default_value != NULL) { + if (default_value != nullptr) { Py_INCREF(default_value); return default_value; } else { @@ -765,7 +766,7 @@ static PyMethodDef MessageMapMethods[] = { { "__reduce__", (PyCFunction)Reduce, METH_NOARGS, "Outputs picklable representation of the repeated field." }, */ - {NULL, NULL}, + {nullptr, nullptr}, }; PyTypeObject* MessageMapContainer_Type; @@ -777,7 +778,7 @@ static PyType_Slot MessageMapContainer_Type_slots[] = { {Py_tp_methods, (void*)MessageMapMethods}, {Py_tp_iter, (void*)MapReflectionFriend::GetIterator}, {Py_tp_repr, (void*)MapReflectionFriend::MessageMapToStr}, - {0, 0}}; + {0, nullptr}}; PyType_Spec MessageMapContainer_Type_spec = { FULL_MODULE_NAME ".MessageMapContainer", sizeof(MessageMapContainer), 0, @@ -793,7 +794,7 @@ PyObject* MapReflectionFriend::GetIterator(PyObject *_self) { MapContainer* self = GetMap(_self); ScopedPyObjectPtr obj(PyType_GenericAlloc(&MapIterator_Type, 0)); - if (obj == NULL) { + if (obj == nullptr) { return PyErr_Format(PyExc_KeyError, "Could not allocate iterator"); } @@ -830,8 +831,8 @@ PyObject* MapReflectionFriend::IterNext(PyObject* _self) { "Map cleared during iteration."); } - if (self->iter.get() == NULL) { - return NULL; + if (self->iter.get() == nullptr) { + return nullptr; } Message* message = self->container->GetMutableMessage(); @@ -839,7 +840,7 @@ PyObject* MapReflectionFriend::IterNext(PyObject* _self) { if (*self->iter == reflection->MapEnd(message, self->container->parent_field_descriptor)) { - return NULL; + return nullptr; } PyObject* ret = MapKeyToPython(self->container, self->iter->GetKey()); @@ -858,60 +859,64 @@ static void DeallocMapIterator(PyObject* _self) { } PyTypeObject MapIterator_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".MapIterator", // tp_name - sizeof(MapIterator), // tp_basicsize - 0, // tp_itemsize - DeallocMapIterator, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A scalar map iterator", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, // tp_iter - MapReflectionFriend::IterNext, // tp_iternext - 0, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".MapIterator", // tp_name + sizeof(MapIterator), // tp_basicsize + 0, // tp_itemsize + DeallocMapIterator, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A scalar map iterator", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, // tp_iter + MapReflectionFriend::IterNext, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; bool InitMapContainers() { // ScalarMapContainer_Type derives from our MutableMapping type. ScopedPyObjectPtr abc(PyImport_ImportModule("collections.abc")); - if (abc == NULL) { + if (abc == nullptr) { return false; } ScopedPyObjectPtr mutable_mapping( PyObject_GetAttrString(abc.get(), "MutableMapping")); - if (mutable_mapping == NULL) { + if (mutable_mapping == nullptr) { return false; } Py_INCREF(mutable_mapping.get()); ScopedPyObjectPtr bases(PyTuple_Pack(1, mutable_mapping.get())); - if (bases == NULL) { + if (bases == nullptr) { return false; } diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.h b/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.h index 842602e79f..e14136efab 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/map_container.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <cstdint> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/message.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/message.cc index 3254be8a21..d416925f53 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/message.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/message.cc @@ -79,12 +79,13 @@ #define PyString_AsString(ob) \ (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob)) -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -108,7 +109,7 @@ static PyObject* kDESCRIPTOR; PyObject* EnumTypeWrapper_class; static PyObject* PythonMessage_class; static PyObject* kEmptyWeakref; -static PyObject* WKT_classes = NULL; +static PyObject* WKT_classes = nullptr; namespace message_meta { @@ -125,7 +126,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { const FieldDescriptor* field_descriptor = descriptor->field(i); ScopedPyObjectPtr property(NewFieldProperty(field_descriptor)); - if (property == NULL) { + if (property == nullptr) { return -1; } if (PyObject_SetAttrString(cls, field_descriptor->name().c_str(), @@ -139,13 +140,13 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { const EnumDescriptor* enum_descriptor = descriptor->enum_type(i); ScopedPyObjectPtr enum_type( PyEnumDescriptor_FromDescriptor(enum_descriptor)); - if (enum_type == NULL) { + if (enum_type == nullptr) { return -1; } // Add wrapped enum type to message class. ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs( - EnumTypeWrapper_class, enum_type.get(), NULL)); - if (wrapped == NULL) { + EnumTypeWrapper_class, enum_type.get(), nullptr)); + if (wrapped == nullptr) { return -1; } if (PyObject_SetAttrString( @@ -159,7 +160,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { enum_descriptor->value(j); ScopedPyObjectPtr value_number( PyLong_FromLong(enum_value_descriptor->number())); - if (value_number == NULL) { + if (value_number == nullptr) { return -1; } if (PyObject_SetAttrString(cls, enum_value_descriptor->name().c_str(), @@ -177,7 +178,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { for (int i = 0; i < descriptor->extension_count(); ++i) { const google::protobuf::FieldDescriptor* field = descriptor->extension(i); ScopedPyObjectPtr extension_field(PyFieldDescriptor_FromDescriptor(field)); - if (extension_field == NULL) { + if (extension_field == nullptr) { return -1; } @@ -192,7 +193,7 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) { } static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"name", "bases", "dict", 0}; + static const char* kwlist[] = {"name", "bases", "dict", nullptr}; PyObject *bases, *dict; const char* name; @@ -200,7 +201,7 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { if (!PyArg_ParseTupleAndKeywords( args, kwargs, "sO!O!:type", const_cast<char**>(kwlist), &name, &PyTuple_Type, &bases, &PyDict_Type, &dict)) { - return NULL; + return nullptr; } // Check bases: only (), or (message.Message,) are allowed @@ -209,7 +210,7 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { PyTuple_GET_ITEM(bases, 0) == PythonMessage_class))) { PyErr_SetString(PyExc_TypeError, "A Message class can only inherit from Message"); - return NULL; + return nullptr; } // Check dict['DESCRIPTOR'] @@ -232,25 +233,25 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // Messages have no __dict__ ScopedPyObjectPtr slots(PyTuple_New(0)); if (PyDict_SetItemString(dict, "__slots__", slots.get()) < 0) { - return NULL; + return nullptr; } // Build the arguments to the base metaclass. // We change the __bases__ classes. ScopedPyObjectPtr new_args; - if (WKT_classes == NULL) { + if (WKT_classes == nullptr) { ScopedPyObjectPtr well_known_types(PyImport_ImportModule( "google.protobuf.internal.well_known_types")); - GOOGLE_DCHECK(well_known_types != NULL); + GOOGLE_DCHECK(well_known_types != nullptr); WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES"); - GOOGLE_DCHECK(WKT_classes != NULL); + GOOGLE_DCHECK(WKT_classes != nullptr); } PyObject* well_known_class = PyDict_GetItemString( WKT_classes, message_descriptor->full_name().c_str()); - if (well_known_class == NULL) { + if (well_known_class == nullptr) { new_args.reset(Py_BuildValue("s(OO)O", name, CMessage_Type, PythonMessage_class, dict)); } else { @@ -258,21 +259,21 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { PythonMessage_class, well_known_class, dict)); } - if (new_args == NULL) { - return NULL; + if (new_args == nullptr) { + return nullptr; } // Call the base metaclass. - ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), NULL)); - if (result == NULL) { - return NULL; + ScopedPyObjectPtr result(PyType_Type.tp_new(type, new_args.get(), nullptr)); + if (result == nullptr) { + return nullptr; } CMessageClass* newtype = reinterpret_cast<CMessageClass*>(result.get()); // Cache the descriptor, both as Python object and as C++ pointer. const Descriptor* descriptor = PyMessageDescriptor_AsDescriptor(py_descriptor); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } Py_INCREF(py_descriptor); newtype->py_message_descriptor = py_descriptor; @@ -281,8 +282,8 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // use the MessageFactory optionally passed in the class dict. PyDescriptorPool* py_descriptor_pool = GetDescriptorPool_FromPool(descriptor->file()->pool()); - if (py_descriptor_pool == NULL) { - return NULL; + if (py_descriptor_pool == nullptr) { + return nullptr; } newtype->py_message_factory = py_descriptor_pool->py_message_factory; Py_INCREF(newtype->py_message_factory); @@ -292,12 +293,12 @@ static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { // MessageFactory is fully implemented in C++. if (message_factory::RegisterMessageClass(newtype->py_message_factory, descriptor, newtype) < 0) { - return NULL; + return nullptr; } // Continue with type initialization: add other descriptors, enum values... if (AddDescriptors(result.get(), descriptor) < 0) { - return NULL; + return nullptr; } return result.release(); } @@ -325,11 +326,11 @@ static int GcClear(PyObject* pself) { // The _extensions_by_name dictionary is built on every access. // TODO(amauryfa): Migrate all users to pool.FindAllExtensions() static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { - if (self->message_descriptor == NULL) { + if (self->message_descriptor == nullptr) { // This is the base Message object, simply raise AttributeError. PyErr_SetString(PyExc_AttributeError, "Base Message class has no DESCRIPTOR"); - return NULL; + return nullptr; } const PyDescriptorPool* pool = self->py_message_factory->pool; @@ -341,12 +342,12 @@ static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { for (int i = 0; i < extensions.size(); i++) { ScopedPyObjectPtr extension( PyFieldDescriptor_FromDescriptor(extensions[i])); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } if (PyDict_SetItemString(result.get(), extensions[i]->full_name().c_str(), extension.get()) < 0) { - return NULL; + return nullptr; } } return result.release(); @@ -355,11 +356,11 @@ static PyObject* GetExtensionsByName(CMessageClass *self, void *closure) { // The _extensions_by_number dictionary is built on every access. // TODO(amauryfa): Migrate all users to pool.FindExtensionByNumber() static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) { - if (self->message_descriptor == NULL) { + if (self->message_descriptor == nullptr) { // This is the base Message object, simply raise AttributeError. PyErr_SetString(PyExc_AttributeError, "Base Message class has no DESCRIPTOR"); - return NULL; + return nullptr; } const PyDescriptorPool* pool = self->py_message_factory->pool; @@ -371,24 +372,24 @@ static PyObject* GetExtensionsByNumber(CMessageClass *self, void *closure) { for (int i = 0; i < extensions.size(); i++) { ScopedPyObjectPtr extension( PyFieldDescriptor_FromDescriptor(extensions[i])); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } ScopedPyObjectPtr number(PyLong_FromLong(extensions[i]->number())); - if (number == NULL) { - return NULL; + if (number == nullptr) { + return nullptr; } if (PyDict_SetItem(result.get(), number.get(), extension.get()) < 0) { - return NULL; + return nullptr; } } return result.release(); } static PyGetSetDef Getters[] = { - {"_extensions_by_name", (getter)GetExtensionsByName, NULL}, - {"_extensions_by_number", (getter)GetExtensionsByNumber, NULL}, - {NULL} + {"_extensions_by_name", (getter)GetExtensionsByName, nullptr}, + {"_extensions_by_number", (getter)GetExtensionsByNumber, nullptr}, + {nullptr}, }; // Compute some class attributes on the fly: @@ -416,17 +417,17 @@ static PyObject* GetClassAttribute(CMessageClass *self, PyObject* name) { } } PyErr_SetObject(PyExc_AttributeError, name); - return NULL; + return nullptr; } static PyObject* GetAttr(CMessageClass* self, PyObject* name) { PyObject* result = CMessageClass_Type->tp_base->tp_getattro( reinterpret_cast<PyObject*>(self), name); - if (result != NULL) { + if (result != nullptr) { return result; } if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return NULL; + return nullptr; } PyErr_Clear(); @@ -449,42 +450,46 @@ static bool allow_oversize_protos = false; static PyTypeObject _CMessageClass_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".MessageMeta", // tp_name - sizeof(CMessageClass), // tp_basicsize - 0, // tp_itemsize - message_meta::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str + ".MessageMeta", // tp_name + sizeof(CMessageClass), // tp_basicsize + 0, // tp_itemsize + message_meta::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, /* tp_print */ +#else + 0, /* tp_vectorcall_offset */ +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str (getattrofunc)message_meta::GetAttr, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, // tp_flags "The metaclass of ProtocolMessages", // tp_doc message_meta::GcTraverse, // tp_traverse message_meta::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members message_meta::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc message_meta::New, // tp_new }; PyTypeObject* CMessageClass_Type = &_CMessageClass_Type; @@ -492,15 +497,15 @@ PyTypeObject* CMessageClass_Type = &_CMessageClass_Type; static CMessageClass* CheckMessageClass(PyTypeObject* cls) { if (!PyObject_TypeCheck(cls, CMessageClass_Type)) { PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name); - return NULL; + return nullptr; } return reinterpret_cast<CMessageClass*>(cls); } static const Descriptor* GetMessageDescriptor(PyTypeObject* cls) { CMessageClass* type = CheckMessageClass(cls); - if (type == NULL) { - return NULL; + if (type == nullptr) { + return nullptr; } return type->message_descriptor; } @@ -567,32 +572,24 @@ template <class T> bool CheckAndGetInteger(PyObject* arg, T* value) { // This effectively defines an integer as "an object that can be cast as // an integer and can be used as an ordinal number". - // This definition includes everything that implements numbers.Integral + // This definition includes everything with a valid __index__() implementation // and shouldn't cast the net too wide. - if (PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) { - FormatTypeError(arg, "int, long"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + PROTOBUF_PREDICT_FALSE(!PyIndex_Check(arg))) { + FormatTypeError(arg, "int"); + return false; + } + + PyObject* arg_py_int = PyNumber_Index(arg); + if (PyErr_Occurred()) { + // Propagate existing error. return false; } - // Now we have an integral number so we can safely use PyLong_ functions. - // We need to treat the signed and unsigned cases differently in case arg is - // holding a value above the maximum for signed longs. if (std::numeric_limits<T>::min() == 0) { // Unsigned case. - unsigned PY_LONG_LONG ulong_result; - if (PyLong_Check(arg)) { - ulong_result = PyLong_AsUnsignedLongLong(arg); - } else { - // Unlike PyLong_AsLongLong, PyLong_AsUnsignedLongLong is very - // picky about the exact type. - PyObject* casted = PyNumber_Long(arg); - if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) { - // Propagate existing error. - return false; - } - ulong_result = PyLong_AsUnsignedLongLong(casted); - Py_DECREF(casted); - } + unsigned PY_LONG_LONG ulong_result = PyLong_AsUnsignedLongLong(arg_py_int); + Py_DECREF(arg_py_int); if (VerifyIntegerCastAndRange<T, unsigned PY_LONG_LONG>(arg, ulong_result)) { *value = static_cast<T>(ulong_result); @@ -601,30 +598,14 @@ bool CheckAndGetInteger(PyObject* arg, T* value) { } } else { // Signed case. - PY_LONG_LONG long_result; - PyNumberMethods *nb; - if ((nb = arg->ob_type->tp_as_number) != NULL && nb->nb_int != NULL) { - // PyLong_AsLongLong requires it to be a long or to have an __int__() - // method. - long_result = PyLong_AsLongLong(arg); - } else { - // Valid subclasses of numbers.Integral should have a __long__() method - // so fall back to that. - PyObject* casted = PyNumber_Long(arg); - if (PROTOBUF_PREDICT_FALSE(casted == nullptr)) { - // Propagate existing error. - return false; - } - long_result = PyLong_AsLongLong(casted); - Py_DECREF(casted); - } + Py_DECREF(arg_py_int); + PY_LONG_LONG long_result = PyLong_AsLongLong(arg); if (VerifyIntegerCastAndRange<T, PY_LONG_LONG>(arg, long_result)) { *value = static_cast<T>(long_result); } else { return false; } } - return true; } @@ -637,8 +618,9 @@ template bool CheckAndGetInteger<uint64>(PyObject*, uint64*); bool CheckAndGetDouble(PyObject* arg, double* value) { *value = PyFloat_AsDouble(arg); - if (PROTOBUF_PREDICT_FALSE(*value == -1 && PyErr_Occurred())) { - FormatTypeError(arg, "int, long, float"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + PROTOBUF_PREDICT_FALSE(*value == -1 && PyErr_Occurred())) { + FormatTypeError(arg, "int, float"); return false; } return true; @@ -655,8 +637,9 @@ bool CheckAndGetFloat(PyObject* arg, float* value) { bool CheckAndGetBool(PyObject* arg, bool* value) { long long_value = PyLong_AsLong(arg); // NOLINT - if (long_value == -1 && PyErr_Occurred()) { - FormatTypeError(arg, "int, long, bool"); + if (!strcmp(Py_TYPE(arg)->tp_name, "numpy.ndarray") || + (long_value == -1 && PyErr_Occurred())) { + FormatTypeError(arg, "int, bool"); return false; } *value = static_cast<bool>(long_value); @@ -668,7 +651,7 @@ bool CheckAndGetBool(PyObject* arg, bool* value) { // valid UTF-8. bool IsValidUTF8(PyObject* obj) { if (PyBytes_Check(obj)) { - PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); + PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", nullptr); // Clear the error indicator; we report our own error when desired. PyErr_Clear(); @@ -693,7 +676,7 @@ PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) { if (descriptor->type() == FieldDescriptor::TYPE_STRING) { if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) { FormatTypeError(arg, "bytes, unicode"); - return NULL; + return nullptr; } if (!IsValidUTF8(arg) && !AllowInvalidUTF8(descriptor)) { @@ -704,21 +687,21 @@ PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) { "unicode objects before being added.", PyString_AsString(repr)); Py_DECREF(repr); - return NULL; + return nullptr; } } else if (!PyBytes_Check(arg)) { FormatTypeError(arg, "bytes"); - return NULL; + return nullptr; } - PyObject* encoded_string = NULL; + PyObject* encoded_string = nullptr; if (descriptor->type() == FieldDescriptor::TYPE_STRING) { if (PyBytes_Check(arg)) { // The bytes were already validated as correctly encoded UTF-8 above. encoded_string = arg; // Already encoded. Py_INCREF(encoded_string); } else { - encoded_string = PyUnicode_AsEncodedString(arg, "utf-8", NULL); + encoded_string = PyUnicode_AsEncodedString(arg, "utf-8", nullptr); } } else { // In this case field type is "bytes". @@ -737,7 +720,7 @@ bool CheckAndSetString( int index) { ScopedPyObjectPtr encoded_string(CheckString(arg, descriptor)); - if (encoded_string.get() == NULL) { + if (encoded_string.get() == nullptr) { return false; } @@ -765,12 +748,13 @@ PyObject* ToStringObject(const FieldDescriptor* descriptor, return PyBytes_FromStringAndSize(value.c_str(), value.length()); } - PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); + PyObject* result = + PyUnicode_DecodeUTF8(value.c_str(), value.length(), nullptr); // If the string can't be decoded in UTF-8, just return a string object that // contains the raw bytes. This can't happen if the value was assigned using // the members of the Python message object, but can happen if the values were // parsed from the wire (binary). - if (result == NULL) { + if (result == nullptr) { PyErr_Clear(); result = PyBytes_FromStringAndSize(value.c_str(), value.length()); } @@ -798,7 +782,6 @@ PyMessageFactory* GetFactoryForMessage(CMessage* message) { static int MaybeReleaseOverlappingOneofField( CMessage* cmessage, const FieldDescriptor* field) { -#ifdef GOOGLE_PROTOBUF_HAS_ONEOF Message* message = cmessage->message; const Reflection* reflection = message->GetReflection(); if (!field->containing_oneof() || @@ -818,7 +801,6 @@ static int MaybeReleaseOverlappingOneofField( if (InternalReleaseFieldByDescriptor(cmessage, existing_field) < 0) { return -1; } -#endif return 0; } @@ -860,7 +842,7 @@ int FixupMessageAfterMerge(CMessage* self) { // Making a message writable int AssureWritable(CMessage* self) { - if (self == NULL || !self->read_only) { + if (self == nullptr || !self->read_only) { return 0; } @@ -883,7 +865,7 @@ int AssureWritable(CMessage* self) { Message* mutable_message = reflection->MutableMessage( parent_message, self->parent_field_descriptor, GetFactoryForMessage(self->parent)->message_factory); - if (mutable_message == NULL) { + if (mutable_message == nullptr) { return -1; } self->message = mutable_message; @@ -902,7 +884,7 @@ const FieldDescriptor* GetExtensionDescriptor(PyObject* extension) { // allow input which is not a field descriptor, and simply pretend it does // not exist. PyErr_SetObject(PyExc_KeyError, extension); - return NULL; + return nullptr; } return PyFieldDescriptor_AsDescriptor(extension); } @@ -913,20 +895,20 @@ static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor, PyObject* value) { if (PyUnicode_Check(value)) { const EnumDescriptor* enum_descriptor = descriptor.enum_type(); - if (enum_descriptor == NULL) { + if (enum_descriptor == nullptr) { PyErr_SetString(PyExc_TypeError, "not an enum field"); - return NULL; + return nullptr; } char* enum_label; Py_ssize_t size; if (PyString_AsStringAndSize(value, &enum_label, &size) < 0) { - return NULL; + return nullptr; } const EnumValueDescriptor* enum_value_descriptor = enum_descriptor->FindValueByName(StringParam(enum_label, size)); - if (enum_value_descriptor == NULL) { + if (enum_value_descriptor == nullptr) { PyErr_Format(PyExc_ValueError, "unknown enum label \"%s\"", enum_label); - return NULL; + return nullptr; } return PyLong_FromLong(enum_value_descriptor->number()); } @@ -996,7 +978,7 @@ int DeleteRepeatedField( } } - Arena* arena = Arena::InternalHelper<Message>::GetArenaForAllocation(message); + Arena* arena = Arena::InternalGetArenaForAllocation(message); GOOGLE_DCHECK_EQ(arena, nullptr) << "python protobuf is expected to be allocated from heap"; // Remove items, starting from the end. @@ -1034,12 +1016,12 @@ int DeleteRepeatedField( // Initializes fields of a message. Used in constructors. int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { - if (args != NULL && PyTuple_Size(args) != 0) { + if (args != nullptr && PyTuple_Size(args) != 0) { PyErr_SetString(PyExc_TypeError, "No positional arguments allowed"); return -1; } - if (kwargs == NULL) { + if (kwargs == nullptr) { return 0; } @@ -1053,7 +1035,7 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { } ScopedPyObjectPtr property( PyObject_GetAttr(reinterpret_cast<PyObject*>(Py_TYPE(self)), name)); - if (property == NULL || + if (property == nullptr || !PyObject_TypeCheck(property.get(), CFieldProperty_Type)) { PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.", self->message->GetDescriptor()->name().c_str(), @@ -1070,23 +1052,24 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { if (descriptor->is_map()) { ScopedPyObjectPtr map(GetFieldValue(self, descriptor)); const FieldDescriptor* value_descriptor = - descriptor->message_type()->FindFieldByName("value"); + descriptor->message_type()->map_value(); if (value_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { - PyErr_Format(PyExc_TypeError, "Argument %s is not iterable", PyString_AsString(name)); + if (iter == nullptr) { + PyErr_Format(PyExc_TypeError, "Argument %s is not iterable", + PyString_AsString(name)); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { ScopedPyObjectPtr source_value(PyObject_GetItem(value, next.get())); ScopedPyObjectPtr dest_value(PyObject_GetItem(map.get(), next.get())); - if (source_value.get() == NULL || dest_value.get() == NULL) { + if (source_value.get() == nullptr || dest_value.get() == nullptr) { return -1; } ScopedPyObjectPtr ok(PyObject_CallMethod( dest_value.get(), "MergeFrom", "O", source_value.get())); - if (ok.get() == NULL) { + if (ok.get() == nullptr) { return -1; } } @@ -1094,36 +1077,36 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { ScopedPyObjectPtr function_return; function_return.reset( PyObject_CallMethod(map.get(), "update", "O", value)); - if (function_return.get() == NULL) { + if (function_return.get() == nullptr) { return -1; } } } else if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) { ScopedPyObjectPtr container(GetFieldValue(self, descriptor)); - if (container == NULL) { + if (container == nullptr) { return -1; } if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { RepeatedCompositeContainer* rc_container = reinterpret_cast<RepeatedCompositeContainer*>(container.get()); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { - PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : NULL); + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { + PyObject* kwargs = (PyDict_Check(next.get()) ? next.get() : nullptr); ScopedPyObjectPtr new_msg( - repeated_composite_container::Add(rc_container, NULL, kwargs)); - if (new_msg == NULL) { + repeated_composite_container::Add(rc_container, nullptr, kwargs)); + if (new_msg == nullptr) { return -1; } - if (kwargs == NULL) { + if (kwargs == nullptr) { // next was not a dict, it's a message we need to merge ScopedPyObjectPtr merged(MergeFrom( reinterpret_cast<CMessage*>(new_msg.get()), next.get())); - if (merged.get() == NULL) { + if (merged.get() == nullptr) { return -1; } } @@ -1136,20 +1119,20 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { RepeatedScalarContainer* rs_container = reinterpret_cast<RepeatedScalarContainer*>(container.get()); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); return -1; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { ScopedPyObjectPtr enum_value( GetIntegerEnumValue(*descriptor, next.get())); - if (enum_value == NULL) { + if (enum_value == nullptr) { return -1; } ScopedPyObjectPtr new_msg(repeated_scalar_container::Append( rs_container, enum_value.get())); - if (new_msg == NULL) { + if (new_msg == nullptr) { return -1; } } @@ -1160,26 +1143,25 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { } else { if (ScopedPyObjectPtr(repeated_scalar_container::Extend( reinterpret_cast<RepeatedScalarContainer*>(container.get()), - value)) == - NULL) { + value)) == nullptr) { return -1; } } } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { ScopedPyObjectPtr message(GetFieldValue(self, descriptor)); - if (message == NULL) { + if (message == nullptr) { return -1; } CMessage* cmessage = reinterpret_cast<CMessage*>(message.get()); if (PyDict_Check(value)) { // Make the message exist even if the dict is empty. AssureWritable(cmessage); - if (InitAttributes(cmessage, NULL, value) < 0) { + if (InitAttributes(cmessage, nullptr, value) < 0) { return -1; } } else { ScopedPyObjectPtr merged(MergeFrom(cmessage, value)); - if (merged == NULL) { + if (merged == nullptr) { return -1; } } @@ -1187,7 +1169,7 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { ScopedPyObjectPtr new_val; if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { new_val.reset(GetIntegerEnumValue(*descriptor, value)); - if (new_val == NULL) { + if (new_val == nullptr) { return -1; } value = new_val.get(); @@ -1205,19 +1187,19 @@ int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) { CMessage* NewEmptyMessage(CMessageClass* type) { CMessage* self = reinterpret_cast<CMessage*>( PyType_GenericAlloc(&type->super.ht_type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } - self->message = NULL; - self->parent = NULL; - self->parent_field_descriptor = NULL; + self->message = nullptr; + self->parent = nullptr; + self->parent_field_descriptor = nullptr; self->read_only = false; - self->composite_fields = NULL; - self->child_submessages = NULL; + self->composite_fields = nullptr; + self->child_submessages = nullptr; - self->unknown_field_set = NULL; + self->unknown_field_set = nullptr; return self; } @@ -1309,30 +1291,27 @@ static void Dealloc(CMessage* self) { PyObject* IsInitialized(CMessage* self, PyObject* args) { - PyObject* errors = NULL; + PyObject* errors = nullptr; if (!PyArg_ParseTuple(args, "|O", &errors)) { - return NULL; + return nullptr; } if (self->message->IsInitialized()) { Py_RETURN_TRUE; } - if (errors != NULL) { + if (errors != nullptr) { ScopedPyObjectPtr initialization_errors( FindInitializationErrors(self)); - if (initialization_errors == NULL) { - return NULL; + if (initialization_errors == nullptr) { + return nullptr; } ScopedPyObjectPtr extend_name(PyUnicode_FromString("extend")); - if (extend_name == NULL) { - return NULL; + if (extend_name == nullptr) { + return nullptr; } ScopedPyObjectPtr result(PyObject_CallMethodObjArgs( - errors, - extend_name.get(), - initialization_errors.get(), - NULL)); - if (result == NULL) { - return NULL; + errors, extend_name.get(), initialization_errors.get(), nullptr)); + if (result == nullptr) { + return nullptr; } } Py_RETURN_FALSE; @@ -1359,17 +1338,17 @@ const FieldDescriptor* FindFieldWithOneofs(const Message* message, const Descriptor* descriptor = message->GetDescriptor(); const FieldDescriptor* field_descriptor = descriptor->FindFieldByName(field_name); - if (field_descriptor != NULL) { + if (field_descriptor != nullptr) { return field_descriptor; } const OneofDescriptor* oneof_desc = descriptor->FindOneofByName(field_name); - if (oneof_desc != NULL) { + if (oneof_desc != nullptr) { *in_oneof = true; return message->GetReflection()->GetOneofFieldDescriptor(*message, oneof_desc); } - return NULL; + return nullptr; } bool CheckHasPresence(const FieldDescriptor* field_descriptor, bool in_oneof) { @@ -1397,25 +1376,25 @@ PyObject* HasField(CMessage* self, PyObject* arg) { Py_ssize_t size; field_name = const_cast<char*>(PyUnicode_AsUTF8AndSize(arg, &size)); if (!field_name) { - return NULL; + return nullptr; } Message* message = self->message; bool is_in_oneof; const FieldDescriptor* field_descriptor = FindFieldWithOneofs(message, StringParam(field_name, size), &is_in_oneof); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { if (!is_in_oneof) { PyErr_Format(PyExc_ValueError, "Protocol message %s has no field %s.", message->GetDescriptor()->name().c_str(), field_name); - return NULL; + return nullptr; } else { Py_RETURN_FALSE; } } if (!CheckHasPresence(field_descriptor, is_in_oneof)) { - return NULL; + return nullptr; } if (message->GetReflection()->HasField(*message, field_descriptor)) { @@ -1427,8 +1406,8 @@ PyObject* HasField(CMessage* self, PyObject* arg) { PyObject* ClearExtension(CMessage* self, PyObject* extension) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (ClearFieldByDescriptor(self, descriptor) < 0) { return nullptr; @@ -1438,8 +1417,8 @@ PyObject* ClearExtension(CMessage* self, PyObject* extension) { PyObject* HasExtension(CMessage* self, PyObject* extension) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } int has_field = HasFieldByDescriptor(self, descriptor); if (has_field < 0) { @@ -1582,20 +1561,20 @@ PyObject* ClearField(CMessage* self, PyObject* arg) { char* field_name; Py_ssize_t field_size; if (PyString_AsStringAndSize(arg, &field_name, &field_size) < 0) { - return NULL; + return nullptr; } AssureWritable(self); bool is_in_oneof; const FieldDescriptor* field_descriptor = FindFieldWithOneofs( self->message, StringParam(field_name, field_size), &is_in_oneof); - if (field_descriptor == NULL) { + if (field_descriptor == nullptr) { if (is_in_oneof) { // We gave the name of a oneof, and none of its fields are set. Py_RETURN_NONE; } else { PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.", field_name); - return NULL; + return nullptr; } } @@ -1622,7 +1601,7 @@ PyObject* Clear(CMessage* self) { } if (InternalReparentFields(self, messages_to_release, containers_to_release) < 0) { - return NULL; + return nullptr; } if (self->unknown_field_set) { unknown_fields::Clear( @@ -1636,7 +1615,7 @@ PyObject* Clear(CMessage* self) { // --------------------------------------------------------------------- static TProtoStringType GetMessageName(CMessage* self) { - if (self->parent_field_descriptor != NULL) { + if (self->parent_field_descriptor != nullptr) { return self->parent_field_descriptor->full_name(); } else { return self->message->GetDescriptor()->full_name(); @@ -1647,33 +1626,33 @@ static PyObject* InternalSerializeToString( CMessage* self, PyObject* args, PyObject* kwargs, bool require_initialized) { // Parse the "deterministic" kwarg; defaults to False. - static const char* kwlist[] = {"deterministic", 0}; + static const char* kwlist[] = {"deterministic", nullptr}; PyObject* deterministic_obj = Py_None; if (!PyArg_ParseTupleAndKeywords( args, kwargs, "|O", const_cast<char**>(kwlist), &deterministic_obj)) { - return NULL; + return nullptr; } // Preemptively convert to a bool first, so we don't need to back out of // allocating memory if this raises an exception. // NOTE: This is unused later if deterministic == Py_None, but that's fine. int deterministic = PyObject_IsTrue(deterministic_obj); if (deterministic < 0) { - return NULL; + return nullptr; } if (require_initialized && !self->message->IsInitialized()) { ScopedPyObjectPtr errors(FindInitializationErrors(self)); - if (errors == NULL) { - return NULL; + if (errors == nullptr) { + return nullptr; } ScopedPyObjectPtr comma(PyUnicode_FromString(",")); - if (comma == NULL) { - return NULL; + if (comma == nullptr) { + return nullptr; } ScopedPyObjectPtr joined( PyObject_CallMethod(comma.get(), "join", "O", errors.get())); - if (joined == NULL) { - return NULL; + if (joined == nullptr) { + return nullptr; } // TODO(haberman): this is a (hopefully temporary) hack. The unit testing @@ -1685,19 +1664,19 @@ static PyObject* InternalSerializeToString( // again every time. ScopedPyObjectPtr message_module(PyImport_ImportModule( "google.protobuf.message")); - if (message_module.get() == NULL) { - return NULL; + if (message_module.get() == nullptr) { + return nullptr; } ScopedPyObjectPtr encode_error( PyObject_GetAttrString(message_module.get(), "EncodeError")); - if (encode_error.get() == NULL) { - return NULL; + if (encode_error.get() == nullptr) { + return nullptr; } PyErr_Format(encode_error.get(), "Message %s is missing required fields: %s", GetMessageName(self).c_str(), PyString_AsString(joined.get())); - return NULL; + return nullptr; } // Ok, arguments parsed and errors checked, now encode to a string @@ -1714,9 +1693,9 @@ static PyObject* InternalSerializeToString( return nullptr; } - PyObject* result = PyBytes_FromStringAndSize(NULL, size); - if (result == NULL) { - return NULL; + PyObject* result = PyBytes_FromStringAndSize(nullptr, size); + if (result == nullptr) { + return nullptr; } io::ArrayOutputStream out(PyBytes_AS_STRING(result), size); io::CodedOutputStream coded_out(&out); @@ -1790,7 +1769,7 @@ static PyObject* ToStr(CMessage* self) { TProtoStringType output; if (!printer.PrintToString(*self->message, &output)) { PyErr_SetString(PyExc_ValueError, "Unable to convert message to str"); - return NULL; + return nullptr; } return PyUnicode_FromString(output.c_str()); } @@ -1803,7 +1782,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), Py_TYPE(arg)->tp_name); - return NULL; + return nullptr; } other_message = reinterpret_cast<CMessage*>(arg); @@ -1814,7 +1793,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), other_message->message->GetDescriptor()->full_name().c_str()); - return NULL; + return nullptr; } AssureWritable(self); @@ -1822,7 +1801,7 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) { // Child message might be lazily created before MergeFrom. Make sure they // are mutable at this point if child messages are really created. if (FixupMessageAfterMerge(self) < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; @@ -1836,7 +1815,7 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), Py_TYPE(arg)->tp_name); - return NULL; + return nullptr; } other_message = reinterpret_cast<CMessage*>(arg); @@ -1852,7 +1831,7 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) { "expected %s got %s.", self->message->GetDescriptor()->full_name().c_str(), other_message->message->GetDescriptor()->full_name().c_str()); - return NULL; + return nullptr; } AssureWritable(self); @@ -1872,7 +1851,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { if (!arg || !PyBool_Check(arg)) { PyErr_SetString(PyExc_TypeError, "Argument to SetAllowOversizeProtos must be boolean"); - return NULL; + return nullptr; } allow_oversize_protos = PyObject_IsTrue(arg); if (allow_oversize_protos) { @@ -1885,7 +1864,7 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { static PyObject* MergeFromString(CMessage* self, PyObject* arg) { Py_buffer data; if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) { - return NULL; + return nullptr; } AssureWritable(self); @@ -1907,19 +1886,29 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { // Child message might be lazily created before MergeFrom. Make sure they // are mutable at this point if child messages are really created. if (FixupMessageAfterMerge(self) < 0) { - return NULL; + return nullptr; } // Python makes distinction in error message, between a general parse failure // and in-correct ending on a terminating tag. Hence we need to be a bit more // explicit in our correctness checks. - if (ptr == nullptr || ctx.BytesUntilLimit(ptr) < 0) { - // Parse error or the parser overshoot the limit. + if (ptr == nullptr) { + // Parse error. PyErr_Format( DecodeError_class, "Error parsing message with type '%s'", self->GetMessageClass()->message_descriptor->full_name().c_str()); - return NULL; + return nullptr; + } + if (ctx.BytesUntilLimit(ptr) < 0) { + // The parser overshot the limit. + PyErr_Format( + DecodeError_class, + "Error parsing message as the message exceeded the protobuf limit " + "with type '%s'", + self->GetMessageClass()->message_descriptor->full_name().c_str()); + return nullptr; } + // ctx has an explicit limit set (length of string_view), so we have to // check we ended at that limit. if (!ctx.EndedAtLimit()) { @@ -1930,8 +1919,8 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { } static PyObject* ParseFromString(CMessage* self, PyObject* arg) { - if (ScopedPyObjectPtr(Clear(self)) == NULL) { - return NULL; + if (ScopedPyObjectPtr(Clear(self)) == nullptr) { + return nullptr; } return MergeFromString(self, arg); } @@ -1943,25 +1932,25 @@ static PyObject* ByteSize(CMessage* self, PyObject* args) { PyObject* RegisterExtension(PyObject* cls, PyObject* extension_handle) { const FieldDescriptor* descriptor = GetExtensionDescriptor(extension_handle); - if (descriptor == NULL) { - return NULL; + if (descriptor == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(cls, CMessageClass_Type)) { PyErr_Format(PyExc_TypeError, "Expected a message class, got %s", cls->ob_type->tp_name); - return NULL; + return nullptr; } CMessageClass *message_class = reinterpret_cast<CMessageClass*>(cls); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } // If the extension was already registered, check that it is the same. const FieldDescriptor* existing_extension = message_class->py_message_factory->pool->pool->FindExtensionByNumber( descriptor->containing_type(), descriptor->number()); - if (existing_extension != NULL && existing_extension != descriptor) { + if (existing_extension != nullptr && existing_extension != descriptor) { PyErr_SetString(PyExc_ValueError, "Double registration of Extensions"); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -1974,20 +1963,19 @@ static PyObject* SetInParent(CMessage* self, PyObject* args) { static PyObject* WhichOneof(CMessage* self, PyObject* arg) { Py_ssize_t name_size; char *name_data; - if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0) - return NULL; + if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0) return nullptr; const OneofDescriptor* oneof_desc = self->message->GetDescriptor()->FindOneofByName( StringParam(name_data, name_size)); - if (oneof_desc == NULL) { + if (oneof_desc == nullptr) { PyErr_Format(PyExc_ValueError, "Protocol message has no oneof \"%s\" field.", name_data); - return NULL; + return nullptr; } const FieldDescriptor* field_in_oneof = self->message->GetReflection()->GetOneofFieldDescriptor( *self->message, oneof_desc); - if (field_in_oneof == NULL) { + if (field_in_oneof == nullptr) { Py_RETURN_NONE; } else { const TProtoStringType& name = field_in_oneof->name(); @@ -2003,8 +1991,8 @@ static PyObject* ListFields(CMessage* self) { // Normally, the list will be exactly the size of the fields. ScopedPyObjectPtr all_fields(PyList_New(fields.size())); - if (all_fields == NULL) { - return NULL; + if (all_fields == nullptr) { + return nullptr; } // When there are unknown extensions, the py list will *not* contain @@ -2013,36 +2001,36 @@ static PyObject* ListFields(CMessage* self) { Py_ssize_t actual_size = 0; for (size_t i = 0; i < fields.size(); ++i) { ScopedPyObjectPtr t(PyTuple_New(2)); - if (t == NULL) { - return NULL; + if (t == nullptr) { + return nullptr; } if (fields[i]->is_extension()) { ScopedPyObjectPtr extension_field( PyFieldDescriptor_FromDescriptor(fields[i])); - if (extension_field == NULL) { - return NULL; + if (extension_field == nullptr) { + return nullptr; } // With C++ descriptors, the field can always be retrieved, but for // unknown extensions which have not been imported in Python code, there // is no message class and we cannot retrieve the value. // TODO(amauryfa): consider building the class on the fly! - if (fields[i]->message_type() != NULL && - message_factory::GetMessageClass( - GetFactoryForMessage(self), - fields[i]->message_type()) == NULL) { + if (fields[i]->message_type() != nullptr && + message_factory::GetMessageClass(GetFactoryForMessage(self), + fields[i]->message_type()) == + nullptr) { PyErr_Clear(); continue; } - ScopedPyObjectPtr extensions(GetExtensionDict(self, NULL)); - if (extensions == NULL) { - return NULL; + ScopedPyObjectPtr extensions(GetExtensionDict(self, nullptr)); + if (extensions == nullptr) { + return nullptr; } // 'extension' reference later stolen by PyTuple_SET_ITEM. PyObject* extension = PyObject_GetItem( extensions.get(), extension_field.get()); - if (extension == NULL) { - return NULL; + if (extension == nullptr) { + return nullptr; } PyTuple_SET_ITEM(t.get(), 0, extension_field.release()); // Steals reference to 'extension' @@ -2051,14 +2039,14 @@ static PyObject* ListFields(CMessage* self) { // Normal field ScopedPyObjectPtr field_descriptor( PyFieldDescriptor_FromDescriptor(fields[i])); - if (field_descriptor == NULL) { - return NULL; + if (field_descriptor == nullptr) { + return nullptr; } PyObject* field_value = GetFieldValue(self, fields[i]); - if (field_value == NULL) { + if (field_value == nullptr) { PyErr_SetString(PyExc_ValueError, fields[i]->name().c_str()); - return NULL; + return nullptr; } PyTuple_SET_ITEM(t.get(), 0, field_descriptor.release()); PyTuple_SET_ITEM(t.get(), 1, field_value); @@ -2067,9 +2055,9 @@ static PyObject* ListFields(CMessage* self) { ++actual_size; } if (static_cast<size_t>(actual_size) != fields.size() && - (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), NULL) < + (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), nullptr) < 0)) { - return NULL; + return nullptr; } return all_fields.release(); } @@ -2086,16 +2074,16 @@ PyObject* FindInitializationErrors(CMessage* self) { message->FindInitializationErrors(&errors); PyObject* error_list = PyList_New(errors.size()); - if (error_list == NULL) { - return NULL; + if (error_list == nullptr) { + return nullptr; } for (size_t i = 0; i < errors.size(); ++i) { const TProtoStringType& error = errors[i]; PyObject* error_string = PyUnicode_FromStringAndSize(error.c_str(), error.length()); - if (error_string == NULL) { + if (error_string == nullptr) { Py_DECREF(error_list); - return NULL; + return nullptr; } PyList_SET_ITEM(error_list, i, error_string); } @@ -2141,10 +2129,10 @@ PyObject* InternalGetScalar(const Message* message, const Reflection* reflection = message->GetReflection(); if (!CheckFieldBelongsToMessage(field_descriptor, message)) { - return NULL; + return nullptr; } - PyObject* result = NULL; + PyObject* result = nullptr; switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { int32_t value = reflection->GetInt32(*message, field_descriptor); @@ -2212,13 +2200,13 @@ CMessage* InternalGetSubMessage( factory, field_descriptor->message_type()); ScopedPyObjectPtr message_class_owner( reinterpret_cast<PyObject*>(message_class)); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } CMessage* cmsg = cmessage::NewEmptyMessage(message_class); - if (cmsg == NULL) { - return NULL; + if (cmsg == nullptr) { + return nullptr; } Py_INCREF(self); @@ -2304,7 +2292,7 @@ int InternalSetNonOneofScalar( const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { reflection->SetEnum(message, field_descriptor, enum_value); } else { PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value); @@ -2339,37 +2327,37 @@ int InternalSetScalar( } PyObject* FromString(PyTypeObject* cls, PyObject* serialized) { - PyObject* py_cmsg = PyObject_CallObject( - reinterpret_cast<PyObject*>(cls), NULL); - if (py_cmsg == NULL) { - return NULL; + PyObject* py_cmsg = + PyObject_CallObject(reinterpret_cast<PyObject*>(cls), nullptr); + if (py_cmsg == nullptr) { + return nullptr; } CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg); ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized)); - if (py_length == NULL) { + if (py_length == nullptr) { Py_DECREF(py_cmsg); - return NULL; + return nullptr; } return py_cmsg; } PyObject* DeepCopy(CMessage* self, PyObject* arg) { - PyObject* clone = PyObject_CallObject( - reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL); - if (clone == NULL) { - return NULL; + PyObject* clone = + PyObject_CallObject(reinterpret_cast<PyObject*>(Py_TYPE(self)), nullptr); + if (clone == nullptr) { + return nullptr; } if (!PyObject_TypeCheck(clone, CMessage_Type)) { Py_DECREF(clone); - return NULL; + return nullptr; } - if (ScopedPyObjectPtr(MergeFrom( - reinterpret_cast<CMessage*>(clone), - reinterpret_cast<PyObject*>(self))) == NULL) { + if (ScopedPyObjectPtr(MergeFrom(reinterpret_cast<CMessage*>(clone), + reinterpret_cast<PyObject*>(self))) == + nullptr) { Py_DECREF(clone); - return NULL; + return nullptr; } return clone; } @@ -2378,23 +2366,24 @@ PyObject* ToUnicode(CMessage* self) { // Lazy import to prevent circular dependencies ScopedPyObjectPtr text_format( PyImport_ImportModule("google.protobuf.text_format")); - if (text_format == NULL) { - return NULL; + if (text_format == nullptr) { + return nullptr; } ScopedPyObjectPtr method_name(PyUnicode_FromString("MessageToString")); - if (method_name == NULL) { - return NULL; + if (method_name == nullptr) { + return nullptr; } Py_INCREF(Py_True); ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs( - text_format.get(), method_name.get(), self, Py_True, NULL)); + text_format.get(), method_name.get(), self, Py_True, nullptr)); Py_DECREF(Py_True); - if (encoded == NULL) { - return NULL; + if (encoded == nullptr) { + return nullptr; } - PyObject* decoded = PyUnicode_FromEncodedObject(encoded.get(), "utf-8", NULL); - if (decoded == NULL) { - return NULL; + PyObject* decoded = + PyUnicode_FromEncodedObject(encoded.get(), "utf-8", nullptr); + if (decoded == nullptr) { + return nullptr; } return decoded; } @@ -2406,7 +2395,7 @@ PyObject* _CheckCalledFromGeneratedFile(PyObject* unused, PyErr_SetString(PyExc_TypeError, "Descriptors should not be created directly, " "but only retrieved from their parent."); - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -2417,20 +2406,20 @@ static PyObject* GetExtensionDict(CMessage* self, void *closure) { const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self)); if (!descriptor->extension_range_count()) { PyErr_SetNone(PyExc_AttributeError); - return NULL; + return nullptr; } if (!self->composite_fields) { self->composite_fields = new CMessage::CompositeFieldsMap(); } if (!self->composite_fields) { - return NULL; + return nullptr; } ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self); return reinterpret_cast<PyObject*>(extension_dict); } static PyObject* UnknownFieldSet(CMessage* self) { - if (self->unknown_field_set == NULL) { + if (self->unknown_field_set == nullptr) { self->unknown_field_set = unknown_fields::NewPyUnknownFields(self); } else { Py_INCREF(self->unknown_field_set); @@ -2449,75 +2438,70 @@ static PyObject* GetExtensionsByNumber(CMessage *self, void *closure) { } static PyGetSetDef Getters[] = { - {"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"}, - {"_extensions_by_name", (getter)GetExtensionsByName, NULL}, - {"_extensions_by_number", (getter)GetExtensionsByNumber, NULL}, - {NULL} + {"Extensions", (getter)GetExtensionDict, nullptr, "Extension dict"}, + {"_extensions_by_name", (getter)GetExtensionsByName, nullptr}, + {"_extensions_by_number", (getter)GetExtensionsByNumber, nullptr}, + {nullptr}, }; - static PyMethodDef Methods[] = { - { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS, - "Outputs a unicode representation of the message." }, - { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS, - "Returns the size of the message in bytes." }, - { "Clear", (PyCFunction)Clear, METH_NOARGS, - "Clears the message." }, - { "ClearExtension", (PyCFunction)ClearExtension, METH_O, - "Clears a message field." }, - { "ClearField", (PyCFunction)ClearField, METH_O, - "Clears a message field." }, - { "CopyFrom", (PyCFunction)CopyFrom, METH_O, - "Copies a protocol message into the current message." }, - { "DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS, - "Discards the unknown fields." }, - { "FindInitializationErrors", (PyCFunction)FindInitializationErrors, - METH_NOARGS, - "Finds unset required fields." }, - { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS, - "Creates new method instance from given serialized data." }, - { "HasExtension", (PyCFunction)HasExtension, METH_O, - "Checks if a message field is set." }, - { "HasField", (PyCFunction)HasField, METH_O, - "Checks if a message field is set." }, - { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS, - "Checks if all required fields of a protocol message are set." }, - { "ListFields", (PyCFunction)ListFields, METH_NOARGS, - "Lists all set fields of a message." }, - { "MergeFrom", (PyCFunction)MergeFrom, METH_O, - "Merges a protocol message into the current message." }, - { "MergeFromString", (PyCFunction)MergeFromString, METH_O, - "Merges a serialized message into the current message." }, - { "ParseFromString", (PyCFunction)ParseFromString, METH_O, - "Parses a serialized message into the current message." }, - { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, - "Registers an extension with the current message." }, - { "SerializePartialToString", (PyCFunction)SerializePartialToString, - METH_VARARGS | METH_KEYWORDS, - "Serializes the message to a string, even if it isn't initialized." }, - { "SerializeToString", (PyCFunction)SerializeToString, - METH_VARARGS | METH_KEYWORDS, - "Serializes the message to a string, only for initialized messages." }, - { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS, - "Sets the has bit of the given field in its parent message." }, - { "UnknownFields", (PyCFunction)UnknownFieldSet, METH_NOARGS, - "Parse unknown field set"}, - { "WhichOneof", (PyCFunction)WhichOneof, METH_O, - "Returns the name of the field set inside a oneof, " - "or None if no field is set." }, - - // Static Methods. - { "_CheckCalledFromGeneratedFile", (PyCFunction)_CheckCalledFromGeneratedFile, - METH_NOARGS | METH_STATIC, - "Raises TypeError if the caller is not in a _pb2.py file."}, - { NULL, NULL} -}; + {"__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, + "Makes a deep copy of the class."}, + {"__unicode__", (PyCFunction)ToUnicode, METH_NOARGS, + "Outputs a unicode representation of the message."}, + {"ByteSize", (PyCFunction)ByteSize, METH_NOARGS, + "Returns the size of the message in bytes."}, + {"Clear", (PyCFunction)Clear, METH_NOARGS, "Clears the message."}, + {"ClearExtension", (PyCFunction)ClearExtension, METH_O, + "Clears a message field."}, + {"ClearField", (PyCFunction)ClearField, METH_O, "Clears a message field."}, + {"CopyFrom", (PyCFunction)CopyFrom, METH_O, + "Copies a protocol message into the current message."}, + {"DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS, + "Discards the unknown fields."}, + {"FindInitializationErrors", (PyCFunction)FindInitializationErrors, + METH_NOARGS, "Finds unset required fields."}, + {"FromString", (PyCFunction)FromString, METH_O | METH_CLASS, + "Creates new method instance from given serialized data."}, + {"HasExtension", (PyCFunction)HasExtension, METH_O, + "Checks if a message field is set."}, + {"HasField", (PyCFunction)HasField, METH_O, + "Checks if a message field is set."}, + {"IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS, + "Checks if all required fields of a protocol message are set."}, + {"ListFields", (PyCFunction)ListFields, METH_NOARGS, + "Lists all set fields of a message."}, + {"MergeFrom", (PyCFunction)MergeFrom, METH_O, + "Merges a protocol message into the current message."}, + {"MergeFromString", (PyCFunction)MergeFromString, METH_O, + "Merges a serialized message into the current message."}, + {"ParseFromString", (PyCFunction)ParseFromString, METH_O, + "Parses a serialized message into the current message."}, + {"RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS, + "Registers an extension with the current message."}, + {"SerializePartialToString", (PyCFunction)SerializePartialToString, + METH_VARARGS | METH_KEYWORDS, + "Serializes the message to a string, even if it isn't initialized."}, + {"SerializeToString", (PyCFunction)SerializeToString, + METH_VARARGS | METH_KEYWORDS, + "Serializes the message to a string, only for initialized messages."}, + {"SetInParent", (PyCFunction)SetInParent, METH_NOARGS, + "Sets the has bit of the given field in its parent message."}, + {"UnknownFields", (PyCFunction)UnknownFieldSet, METH_NOARGS, + "Parse unknown field set"}, + {"WhichOneof", (PyCFunction)WhichOneof, METH_O, + "Returns the name of the field set inside a oneof, " + "or None if no field is set."}, + + // Static Methods. + {"_CheckCalledFromGeneratedFile", + (PyCFunction)_CheckCalledFromGeneratedFile, METH_NOARGS | METH_STATIC, + "Raises TypeError if the caller is not in a _pb2.py file."}, + {nullptr, nullptr}}; bool SetCompositeField(CMessage* self, const FieldDescriptor* field, ContainerBase* value) { - if (self->composite_fields == NULL) { + if (self->composite_fields == nullptr) { self->composite_fields = new CMessage::CompositeFieldsMap(); } (*self->composite_fields)[field] = value; @@ -2525,7 +2509,7 @@ bool SetCompositeField(CMessage* self, const FieldDescriptor* field, } bool SetSubmessage(CMessage* self, CMessage* submessage) { - if (self->child_submessages == NULL) { + if (self->child_submessages == nullptr) { self->child_submessages = new CMessage::SubMessagesMap(); } (*self->child_submessages)[submessage->message] = submessage; @@ -2536,11 +2520,11 @@ PyObject* GetAttr(PyObject* pself, PyObject* name) { CMessage* self = reinterpret_cast<CMessage*>(pself); PyObject* result = PyObject_GenericGetAttr( reinterpret_cast<PyObject*>(self), name); - if (result != NULL) { + if (result != nullptr) { return result; } if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return NULL; + return nullptr; } PyErr_Clear(); @@ -2565,7 +2549,7 @@ PyObject* GetFieldValue(CMessage* self, "descriptor to field '%s' doesn't apply to '%s' object", field_descriptor->full_name().c_str(), Py_TYPE(self)->tp_name); - return NULL; + return nullptr; } if (!field_descriptor->is_repeated() && @@ -2576,12 +2560,12 @@ PyObject* GetFieldValue(CMessage* self, ContainerBase* py_container = nullptr; if (field_descriptor->is_map()) { const Descriptor* entry_type = field_descriptor->message_type(); - const FieldDescriptor* value_type = entry_type->FindFieldByName("value"); + const FieldDescriptor* value_type = entry_type->map_value(); if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { CMessageClass* value_class = message_factory::GetMessageClass( GetFactoryForMessage(self), value_type->message_type()); - if (value_class == NULL) { - return NULL; + if (value_class == nullptr) { + return nullptr; } py_container = NewMessageMapContainer(self, field_descriptor, value_class); @@ -2592,8 +2576,8 @@ PyObject* GetFieldValue(CMessage* self, if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { CMessageClass* message_class = message_factory::GetMessageClass( GetFactoryForMessage(self), field_descriptor->message_type()); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } py_container = repeated_composite_container::NewContainer( self, field_descriptor, message_class); @@ -2608,12 +2592,12 @@ PyObject* GetFieldValue(CMessage* self, PyErr_SetString(PyExc_SystemError, "Should never happen"); } - if (py_container == NULL) { - return NULL; + if (py_container == nullptr) { + return nullptr; } if (!SetCompositeField(self, field_descriptor, py_container)) { Py_DECREF(py_container); - return NULL; + return nullptr; } return py_container->AsPyObject(); } @@ -2689,8 +2673,8 @@ CMessage* CMessage::BuildSubMessageFromPointer( } else { cmsg = cmessage::NewEmptyMessage(message_class); - if (cmsg == NULL) { - return NULL; + if (cmsg == nullptr) { + return nullptr; } cmsg->message = sub_message; Py_INCREF(this); @@ -2719,47 +2703,51 @@ CMessage* CMessage::MaybeReleaseSubMessage(Message* sub_message) { return released; } -static CMessageClass _CMessage_Type = { { { - PyVarObject_HEAD_INIT(&_CMessageClass_Type, 0) - FULL_MODULE_NAME ".CMessage", // tp_name - sizeof(CMessage), // tp_basicsize - 0, // tp_itemsize - (destructor)cmessage::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - (reprfunc)cmessage::ToStr, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - (reprfunc)cmessage::ToStr, // tp_str - cmessage::GetAttr, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_VERSION_TAG, // tp_flags - "A ProtocolMessage", // tp_doc - 0, // tp_traverse - 0, // tp_clear - (richcmpfunc)cmessage::RichCompare, // tp_richcompare - offsetof(CMessage, weakreflist), // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - cmessage::Methods, // tp_methods - 0, // tp_members - cmessage::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - (initproc)cmessage::Init, // tp_init - 0, // tp_alloc - cmessage::New, // tp_new -} } }; +static CMessageClass _CMessage_Type = {{{ + PyVarObject_HEAD_INIT(&_CMessageClass_Type, 0) FULL_MODULE_NAME + ".CMessage", // tp_name + sizeof(CMessage), // tp_basicsize + 0, // tp_itemsize + (destructor)cmessage::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + (reprfunc)cmessage::ToStr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + (reprfunc)cmessage::ToStr, // tp_str + cmessage::GetAttr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_VERSION_TAG, // tp_flags + "A ProtocolMessage", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + (richcmpfunc)cmessage::RichCompare, // tp_richcompare + offsetof(CMessage, weakreflist), // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + cmessage::Methods, // tp_methods + nullptr, // tp_members + cmessage::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + (initproc)cmessage::Init, // tp_init + nullptr, // tp_alloc + cmessage::New, // tp_new +}}}; PyTypeObject* CMessage_Type = &_CMessage_Type.super.ht_type; // --- Exposing the C proto living inside Python proto to C code: @@ -2769,18 +2757,18 @@ Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { const Message* message = PyMessage_GetMessagePointer(msg); - if (message == NULL) { + if (message == nullptr) { PyErr_Clear(); - return NULL; + return nullptr; } return message; } static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { Message* message = PyMessage_GetMutableMessagePointer(msg); - if (message == NULL) { + if (message == nullptr) { PyErr_Clear(); - return NULL; + return nullptr; } return message; } @@ -2788,7 +2776,7 @@ static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { const Message* PyMessage_GetMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a Message instance"); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast<CMessage*>(msg); return cmsg->message; @@ -2797,7 +2785,7 @@ const Message* PyMessage_GetMessagePointer(PyObject* msg) { Message* PyMessage_GetMutableMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a Message instance"); - return NULL; + return nullptr; } CMessage* cmsg = reinterpret_cast<CMessage*>(msg); @@ -2811,7 +2799,7 @@ Message* PyMessage_GetMutableMessagePointer(PyObject* msg) { PyErr_SetString(PyExc_ValueError, "Cannot reliably get a mutable pointer " "to a message with extra references"); - return NULL; + return nullptr; } cmessage::AssureWritable(cmsg); return cmsg->message; @@ -2884,8 +2872,8 @@ void InitGlobals() { // also be freed and reset to NULL during finalization. kDESCRIPTOR = PyUnicode_FromString("DESCRIPTOR"); - PyObject *dummy_obj = PySet_New(NULL); - kEmptyWeakref = PyWeakref_NewRef(dummy_obj, NULL); + PyObject* dummy_obj = PySet_New(nullptr); + kEmptyWeakref = PyWeakref_NewRef(dummy_obj, nullptr); Py_DECREF(dummy_obj); } @@ -2952,22 +2940,22 @@ bool InitProto2MessageModule(PyObject *m) { // Register them as MutableSequence. ScopedPyObjectPtr collections(PyImport_ImportModule("collections.abc")); - if (collections == NULL) { + if (collections == nullptr) { return false; } ScopedPyObjectPtr mutable_sequence( PyObject_GetAttrString(collections.get(), "MutableSequence")); - if (mutable_sequence == NULL) { + if (mutable_sequence == nullptr) { return false; } if (ScopedPyObjectPtr( PyObject_CallMethod(mutable_sequence.get(), "register", "O", - &RepeatedScalarContainer_Type)) == NULL) { + &RepeatedScalarContainer_Type)) == nullptr) { return false; } if (ScopedPyObjectPtr( PyObject_CallMethod(mutable_sequence.get(), "register", "O", - &RepeatedCompositeContainer_Type)) == NULL) { + &RepeatedCompositeContainer_Type)) == nullptr) { return false; } } @@ -3036,7 +3024,7 @@ bool InitProto2MessageModule(PyObject *m) { PyObject* enum_type_wrapper = PyImport_ImportModule( "google.protobuf.internal.enum_type_wrapper"); - if (enum_type_wrapper == NULL) { + if (enum_type_wrapper == nullptr) { return false; } EnumTypeWrapper_class = @@ -3045,7 +3033,7 @@ bool InitProto2MessageModule(PyObject *m) { PyObject* message_module = PyImport_ImportModule( "google.protobuf.message"); - if (message_module == NULL) { + if (message_module == nullptr) { return false; } EncodeError_class = PyObject_GetAttrString(message_module, "EncodeError"); @@ -3054,7 +3042,7 @@ bool InitProto2MessageModule(PyObject *m) { Py_DECREF(message_module); PyObject* pickle_module = PyImport_ImportModule("pickle"); - if (pickle_module == NULL) { + if (pickle_module == nullptr) { return false; } PickleError_class = PyObject_GetAttrString(pickle_module, "PickleError"); diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/message.h b/contrib/python/protobuf/py3/google/protobuf/pyext/message.h index ca81a87521..28dbda6798 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/message.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/message.h @@ -34,6 +34,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <cstdint> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.cc index 5483c56061..35d6214d7d 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.cc @@ -30,6 +30,7 @@ #include <unordered_map> +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/dynamic_message.h> @@ -38,12 +39,13 @@ #include <google/protobuf/pyext/message_factory.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> -#define PyString_AsStringAndSize(ob, charpp, sizep) \ - (PyUnicode_Check(ob) ? ((*(charpp) = const_cast<char*>( \ - PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL \ - ? -1 \ - : 0) \ - : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) +#define PyString_AsStringAndSize(ob, charpp, sizep) \ + (PyUnicode_Check(ob) \ + ? ((*(charpp) = const_cast<char*>( \ + PyUnicode_AsUTF8AndSize(ob, (sizep)))) == nullptr \ + ? -1 \ + : 0) \ + : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) namespace google { namespace protobuf { @@ -54,8 +56,8 @@ namespace message_factory { PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool) { PyMessageFactory* factory = reinterpret_cast<PyMessageFactory*>( PyType_GenericAlloc(type, 0)); - if (factory == NULL) { - return NULL; + if (factory == nullptr) { + return nullptr; } DynamicMessageFactory* message_factory = new DynamicMessageFactory(); @@ -72,25 +74,25 @@ PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool) } PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) { - static const char* kwlist[] = {"pool", 0}; - PyObject* pool = NULL; + static const char* kwlist[] = {"pool", nullptr}; + PyObject* pool = nullptr; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast<char**>(kwlist), &pool)) { - return NULL; + return nullptr; } ScopedPyObjectPtr owned_pool; - if (pool == NULL || pool == Py_None) { + if (pool == nullptr || pool == Py_None) { owned_pool.reset(PyObject_CallFunction( - reinterpret_cast<PyObject*>(&PyDescriptorPool_Type), NULL)); - if (owned_pool == NULL) { - return NULL; + reinterpret_cast<PyObject*>(&PyDescriptorPool_Type), nullptr)); + if (owned_pool == nullptr) { + return nullptr; } pool = owned_pool.get(); } else { if (!PyObject_TypeCheck(pool, &PyDescriptorPool_Type)) { PyErr_Format(PyExc_TypeError, "Expected a DescriptorPool, got %s", pool->ob_type->tp_name); - return NULL; + return nullptr; } } @@ -164,8 +166,8 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, } ScopedPyObjectPtr py_descriptor( PyMessageDescriptor_FromDescriptor(descriptor)); - if (py_descriptor == NULL) { - return NULL; + if (py_descriptor == nullptr) { + return nullptr; } // Create a new message class. ScopedPyObjectPtr args(Py_BuildValue( @@ -173,24 +175,24 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, "DESCRIPTOR", py_descriptor.get(), "__module__", Py_None, "message_factory", self)); - if (args == NULL) { - return NULL; + if (args == nullptr) { + return nullptr; } ScopedPyObjectPtr message_class(PyObject_CallObject( reinterpret_cast<PyObject*>(CMessageClass_Type), args.get())); - if (message_class == NULL) { - return NULL; + if (message_class == nullptr) { + return nullptr; } // Create messages class for the messages used by the fields, and registers // all extensions for these messages during the recursion. for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { const Descriptor* sub_descriptor = descriptor->field(field_idx)->message_type(); - // It is NULL if the field type is not a message. - if (sub_descriptor != NULL) { + // It is null if the field type is not a message. + if (sub_descriptor != nullptr) { CMessageClass* result = GetOrCreateMessageClass(self, sub_descriptor); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } Py_DECREF(result); } @@ -202,17 +204,17 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self, ScopedPyObjectPtr py_extended_class( GetOrCreateMessageClass(self, extension->containing_type()) ->AsPyObject()); - if (py_extended_class == NULL) { - return NULL; + if (py_extended_class == nullptr) { + return nullptr; } ScopedPyObjectPtr py_extension(PyFieldDescriptor_FromDescriptor(extension)); - if (py_extension == NULL) { - return NULL; + if (py_extension == nullptr) { + return nullptr; } ScopedPyObjectPtr result(cmessage::RegisterExtension( py_extended_class.get(), py_extension.get())); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } } return reinterpret_cast<CMessageClass*>(message_class.release()); @@ -226,14 +228,15 @@ CMessageClass* GetMessageClass(PyMessageFactory* self, if (ret == self->classes_by_descriptor->end()) { PyErr_Format(PyExc_TypeError, "No message class registered for '%s'", message_descriptor->full_name().c_str()); - return NULL; + return nullptr; } else { return ret->second; } } static PyMethodDef Methods[] = { - {NULL}}; + {nullptr}, +}; static PyObject* GetPool(PyMessageFactory* self, void* closure) { Py_INCREF(self->pool); @@ -241,8 +244,8 @@ static PyObject* GetPool(PyMessageFactory* self, void* closure) { } static PyGetSetDef Getters[] = { - {"pool", (getter)GetPool, NULL, "DescriptorPool"}, - {NULL} + {"pool", (getter)GetPool, nullptr, "DescriptorPool"}, + {nullptr}, }; } // namespace message_factory @@ -253,38 +256,42 @@ PyTypeObject PyMessageFactory_Type = { sizeof(PyMessageFactory), // tp_basicsize 0, // tp_itemsize message_factory::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - 0, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, // tp_flags "A static Message Factory", // tp_doc message_factory::GcTraverse, // tp_traverse message_factory::GcClear, // tp_clear - 0, // tp_richcompare + nullptr, // tp_richcompare 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext + nullptr, // tp_iter + nullptr, // tp_iternext message_factory::Methods, // tp_methods - 0, // tp_members + nullptr, // tp_members message_factory::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set 0, // tp_dictoffset - 0, // tp_init - 0, // tp_alloc + nullptr, // tp_init + nullptr, // tp_alloc message_factory::New, // tp_new PyObject_GC_Del, // tp_free }; diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.h b/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.h index 515c29cdb8..7dfe425dd5 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/message_factory.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <unordered_map> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/message_module.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/message_module.cc index 971d2bad70..2d3c1d2087 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/message_module.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/message_module.cc @@ -28,6 +28,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <google/protobuf/message_lite.h> @@ -93,28 +94,28 @@ static PyMethodDef ModuleMethods[] = { (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos, METH_O, "Enable/disable oversize proto parsing."}, // DO NOT USE: For migration and testing only. - {NULL, NULL}}; + {nullptr, nullptr}}; static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT, "_message", module_docstring, -1, ModuleMethods, /* m_methods */ - NULL, - NULL, - NULL, - NULL}; + nullptr, + nullptr, + nullptr, + nullptr}; PyMODINIT_FUNC PyInit__message() { PyObject* m; m = PyModule_Create(&_module); - if (m == NULL) { - return NULL; + if (m == nullptr) { + return nullptr; } if (!google::protobuf::python::InitProto2MessageModule(m)) { Py_DECREF(m); - return NULL; + return nullptr; } // Adds the C++ API @@ -126,7 +127,7 @@ PyMODINIT_FUNC PyInit__message() { })) { PyModule_AddObject(m, "proto_API", api); } else { - return NULL; + return nullptr; } return m; diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.cc index 2e8ff4b425..0b63f82256 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.cc @@ -40,12 +40,12 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/message.h> +#include <google/protobuf/reflection.h> #include <google/protobuf/pyext/descriptor.h> #include <google/protobuf/pyext/descriptor_pool.h> #include <google/protobuf/pyext/message.h> #include <google/protobuf/pyext/message_factory.h> #include <google/protobuf/pyext/scoped_pyobject_ptr.h> -#include <google/protobuf/reflection.h> #include <google/protobuf/stubs/map_util.h> namespace google { @@ -74,17 +74,15 @@ PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, if (cmessage::AssureWritable(self->parent) == -1) return nullptr; Message* message = self->parent->message; - Message* sub_message = - message->GetReflection()->AddMessage( - message, - self->parent_field_descriptor, - self->child_message_class->py_message_factory->message_factory); + Message* sub_message = message->GetReflection()->AddMessage( + message, self->parent_field_descriptor, + self->child_message_class->py_message_factory->message_factory); CMessage* cmsg = self->parent->BuildSubMessageFromPointer( self->parent_field_descriptor, sub_message, self->child_message_class); if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) { - message->GetReflection()->RemoveLast( - message, self->parent_field_descriptor); + message->GetReflection()->RemoveLast(message, + self->parent_field_descriptor); Py_DECREF(cmsg); return nullptr; } @@ -108,8 +106,7 @@ static PyObject* AddMessage(RepeatedCompositeContainer* self, PyObject* value) { if (py_cmsg == nullptr) return nullptr; CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg); if (ScopedPyObjectPtr(cmessage::MergeFrom(cmsg, value)) == nullptr) { - reflection->RemoveLast( - message, self->parent_field_descriptor); + reflection->RemoveLast(message, self->parent_field_descriptor); Py_DECREF(cmsg); return nullptr; } @@ -152,7 +149,7 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { Py_ssize_t end_index = index; if (end_index < 0) end_index += length; if (end_index < 0) end_index = 0; - for (Py_ssize_t i = length; i > end_index; i --) { + for (Py_ssize_t i = length; i > end_index; i--) { reflection->SwapElements(message, field_descriptor, i, i - 1); } @@ -268,8 +265,7 @@ static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) { return Subscript(reinterpret_cast<RepeatedCompositeContainer*>(self), slice); } -int AssignSubscript(RepeatedCompositeContainer* self, - PyObject* slice, +int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value) { if (value != nullptr) { PyErr_SetString(PyExc_TypeError, "does not support assignment"); @@ -368,27 +364,22 @@ static void ReorderAttached(RepeatedCompositeContainer* self, const FieldDescriptor* descriptor = self->parent_field_descriptor; const Py_ssize_t length = Length(reinterpret_cast<PyObject*>(self)); - // We need to rearrange things to match python's sort order. Because there - // was already an O(n*log(n)) step in python and a bunch of reflection, we - // expect an O(n**2) step in C++ won't hurt too much. + // We need to rearrange things to match python's sort order. + for (Py_ssize_t i = 0; i < length; ++i) { + reflection->UnsafeArenaReleaseLast(message, descriptor); + } for (Py_ssize_t i = 0; i < length; ++i) { Message* child_message = reinterpret_cast<CMessage*>(PyList_GET_ITEM(child_list, i))->message; - for (Py_ssize_t j = i; j < length; ++j) { - if (child_message == - &reflection->GetRepeatedMessage(*message, descriptor, j)) { - reflection->SwapElements(message, descriptor, i, j); - break; - } - } + reflection->UnsafeArenaAddAllocatedMessage(message, descriptor, + child_message); } } // Returns 0 if successful; returns -1 and sets an exception if // unsuccessful. -static int SortPythonMessages(RepeatedCompositeContainer* self, - PyObject* args, - PyObject* kwds) { +static int SortPythonMessages(RepeatedCompositeContainer* self, PyObject* args, + PyObject* kwds) { ScopedPyObjectPtr child_list( PySequence_List(reinterpret_cast<PyObject*>(self))); if (child_list == nullptr) { @@ -486,9 +477,8 @@ PyObject* DeepCopy(PyObject* pself, PyObject* arg) { } // The private constructor of RepeatedCompositeContainer objects. -RepeatedCompositeContainer *NewContainer( - CMessage* parent, - const FieldDescriptor* parent_field_descriptor, +RepeatedCompositeContainer* NewContainer( + CMessage* parent, const FieldDescriptor* parent_field_descriptor, CMessageClass* child_message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { return nullptr; @@ -525,9 +515,9 @@ static PySequenceMethods SqMethods = { }; static PyMappingMethods MpMethods = { - Length, /* mp_length */ - SubscriptMethod, /* mp_subscript */ - AssignSubscriptMethod, /* mp_ass_subscript */ + Length, /* mp_length */ + SubscriptMethod, /* mp_subscript */ + AssignSubscriptMethod, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { @@ -555,14 +545,14 @@ static PyMethodDef Methods[] = { PyTypeObject RepeatedCompositeContainer_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME - ".RepeatedCompositeContainer", // tp_name - sizeof(RepeatedCompositeContainer), // tp_basicsize - 0, // tp_itemsize - repeated_composite_container::Dealloc, // tp_dealloc + ".RepeatedCompositeContainer", // tp_name + sizeof(RepeatedCompositeContainer), // tp_basicsize + 0, // tp_itemsize + repeated_composite_container::Dealloc, // tp_dealloc #if PY_VERSION_HEX >= 0x03080000 - 0, // tp_vectorcall_offset + 0, // tp_vectorcall_offset #else - nullptr, // tp_print + nullptr, // tp_print #endif nullptr, // tp_getattr nullptr, // tp_setattr diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.h b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.h index e241827ef5..30536eabd4 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_composite_container.h @@ -34,6 +34,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <memory> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.cc index c7ebcbbf00..a9d96f03a0 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.cc @@ -274,6 +274,11 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { bool return_list = false; if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); + } else if (PyIndex_Check(slice)) { + from = to = PyNumber_AsSsize_t(slice, PyExc_ValueError); + if (from == -1 && PyErr_Occurred()) { + return nullptr; + } } else if (PySlice_Check(slice)) { length = Len(pself); if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.h b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.h index f9f0ea8f31..372b6f0a35 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/repeated_scalar_container.h @@ -34,6 +34,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <memory> diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/scoped_pyobject_ptr.h b/contrib/python/protobuf/py3/google/protobuf/pyext/scoped_pyobject_ptr.h index 6f7fc29813..ad3fa9462d 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/scoped_pyobject_ptr.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/scoped_pyobject_ptr.h @@ -35,6 +35,7 @@ #include <google/protobuf/stubs/common.h> +#define PY_SSIZE_T_CLEAN #include <Python.h> namespace google { namespace protobuf { @@ -47,7 +48,7 @@ class ScopedPythonPtr { public: // Takes the ownership of the specified object to ScopedPythonPtr. // The reference count of the specified py_object is not incremented. - explicit ScopedPythonPtr(PyObjectStruct* py_object = NULL) + explicit ScopedPythonPtr(PyObjectStruct* py_object = nullptr) : ptr_(py_object) {} // If a PyObject is owned, decrement its reference count. @@ -59,7 +60,7 @@ class ScopedPythonPtr { // This function must be called with a reference that you own. // this->reset(this->get()) is wrong! // this->reset(this->release()) is OK. - PyObjectStruct* reset(PyObjectStruct* p = NULL) { + PyObjectStruct* reset(PyObjectStruct* p = nullptr) { Py_XDECREF(ptr_); ptr_ = p; return ptr_; @@ -69,7 +70,7 @@ class ScopedPythonPtr { // The caller now owns the returned reference. PyObjectStruct* release() { PyObject* p = ptr_; - ptr_ = NULL; + ptr_ = nullptr; return p; } diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.cc b/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.cc index 7f4fb23edf..dcd63b2e29 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.cc +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.cc @@ -30,6 +30,7 @@ #include <google/protobuf/pyext/unknown_fields.h> +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <set> #include <memory> @@ -49,7 +50,7 @@ namespace unknown_fields { static Py_ssize_t Len(PyObject* pself) { PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>(pself); - if (self->fields == NULL) { + if (self->fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownFields does not exist. " "The parent message might be cleared."); @@ -64,7 +65,7 @@ void Clear(PyUnknownFields* self) { it != self->sub_unknown_fields.end(); it++) { Clear(*it); } - self->fields = NULL; + self->fields = nullptr; self->sub_unknown_fields.clear(); } @@ -74,11 +75,11 @@ PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent, static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>(pself); - if (self->fields == NULL) { + if (self->fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownFields does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } Py_ssize_t total_size = self->fields->field_count(); if (index < 0) { @@ -88,7 +89,7 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyErr_Format(PyExc_IndexError, "index (%zd) out of range", index); - return NULL; + return nullptr; } return unknown_fields::NewPyUnknownFieldRef(self, index); @@ -97,8 +98,8 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { PyObject* NewPyUnknownFields(CMessage* c_message) { PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>( PyType_GenericAlloc(&PyUnknownFields_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } // Call "placement new" to initialize PyUnknownFields. new (self) PyUnknownFields; @@ -116,8 +117,8 @@ PyObject* NewPyUnknownFieldRef(PyUnknownFields* parent, Py_ssize_t index) { PyUnknownFieldRef* self = reinterpret_cast<PyUnknownFieldRef*>( PyType_GenericAlloc(&PyUnknownFieldRef_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -137,58 +138,63 @@ static void Dealloc(PyObject* pself) { reinterpret_cast<CMessage*>(self->parent)->unknown_field_set = nullptr; } Py_CLEAR(self->parent); + auto* py_type = Py_TYPE(pself); self->~PyUnknownFields(); - Py_TYPE(pself)->tp_free(pself); + py_type->tp_free(pself); } static PySequenceMethods SqMethods = { - Len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ + Len, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item, /* sq_item */ + nullptr, /* sq_slice */ + nullptr, /* sq_ass_item */ }; } // namespace unknown_fields PyTypeObject PyUnknownFields_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".PyUnknownFields", // tp_name - sizeof(PyUnknownFields), // tp_basicsize - 0, // tp_itemsize - unknown_fields::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - &unknown_fields::SqMethods, // tp_as_sequence - 0, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "unknown field set", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".PyUnknownFields", // tp_name + sizeof(PyUnknownFields), // tp_basicsize + 0, // tp_itemsize + unknown_fields::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + &unknown_fields::SqMethods, // tp_as_sequence + nullptr, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "unknown field set", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; namespace unknown_field { @@ -196,8 +202,8 @@ static PyObject* PyUnknownFields_FromUnknownFieldSet( PyUnknownFields* parent, const UnknownFieldSet& fields) { PyUnknownFields* self = reinterpret_cast<PyUnknownFields*>( PyType_GenericAlloc(&PyUnknownFields_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } // Call "placement new" to initialize PyUnknownFields. new (self) PyUnknownFields; @@ -212,26 +218,26 @@ static PyObject* PyUnknownFields_FromUnknownFieldSet( const UnknownField* GetUnknownField(PyUnknownFieldRef* self) { const UnknownFieldSet* fields = self->parent->fields; - if (fields == NULL) { + if (fields == nullptr) { PyErr_Format(PyExc_ValueError, "UnknownField does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } - ssize_t total_size = fields->field_count(); + Py_ssize_t total_size = fields->field_count(); if (self->index >= total_size) { PyErr_Format(PyExc_ValueError, "UnknownField does not exist. " "The parent message might be cleared."); - return NULL; + return nullptr; } return &fields->field(self->index); } static PyObject* GetFieldNumber(PyUnknownFieldRef* self, void *closure) { const UnknownField* unknown_field = GetUnknownField(self); - if (unknown_field == NULL) { - return NULL; + if (unknown_field == nullptr) { + return nullptr; } return PyLong_FromLong(unknown_field->number()); } @@ -239,8 +245,8 @@ static PyObject* GetFieldNumber(PyUnknownFieldRef* self, void *closure) { using internal::WireFormatLite; static PyObject* GetWireType(PyUnknownFieldRef* self, void *closure) { const UnknownField* unknown_field = GetUnknownField(self); - if (unknown_field == NULL) { - return NULL; + if (unknown_field == nullptr) { + return nullptr; } // Assign a default value to suppress may-uninitialized warnings (errors @@ -268,19 +274,19 @@ static PyObject* GetWireType(PyUnknownFieldRef* self, void *closure) { static PyObject* GetData(PyUnknownFieldRef* self, void *closure) { const UnknownField* field = GetUnknownField(self); - if (field == NULL) { - return NULL; + if (field == nullptr) { + return nullptr; } - PyObject* data = NULL; + PyObject* data = nullptr; switch (field->type()) { case UnknownField::TYPE_VARINT: - data = PyLong_FromLong(field->varint()); + data = PyLong_FromUnsignedLongLong(field->varint()); break; case UnknownField::TYPE_FIXED32: - data = PyLong_FromLong(field->fixed32()); + data = PyLong_FromUnsignedLong(field->fixed32()); break; case UnknownField::TYPE_FIXED64: - data = PyLong_FromLong(field->fixed64()); + data = PyLong_FromUnsignedLongLong(field->fixed64()); break; case UnknownField::TYPE_LENGTH_DELIMITED: data = PyBytes_FromStringAndSize(field->length_delimited().data(), @@ -301,54 +307,57 @@ static void Dealloc(PyObject* pself) { } static PyGetSetDef Getters[] = { - {"field_number", (getter)GetFieldNumber, NULL}, - {"wire_type", (getter)GetWireType, NULL}, - {"data", (getter)GetData, NULL}, - {NULL} + {"field_number", (getter)GetFieldNumber, nullptr}, + {"wire_type", (getter)GetWireType, nullptr}, + {"data", (getter)GetData, nullptr}, + {nullptr}, }; } // namespace unknown_field PyTypeObject PyUnknownFieldRef_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".PyUnknownFieldRef", // tp_name - sizeof(PyUnknownFieldRef), // tp_basicsize - 0, // tp_itemsize - unknown_field::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - 0, // tp_repr - 0, // tp_as_number - 0, // tp_as_sequence - 0, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "unknown field", // tp_doc - 0, // tp_traverse - 0, // tp_clear - 0, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - 0, // tp_methods - 0, // tp_members - unknown_field::Getters, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".PyUnknownFieldRef", // tp_name + sizeof(PyUnknownFieldRef), // tp_basicsize + 0, // tp_itemsize + unknown_field::Dealloc, // tp_dealloc +#if PY_VERSION_HEX < 0x03080000 + nullptr, // tp_print +#else + 0, // tp_vectorcall_offset +#endif + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "unknown field", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + unknown_field::Getters, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; - } // namespace python } // namespace protobuf } // namespace google diff --git a/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.h b/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.h index 94d55e148d..e7b0b35c41 100644 --- a/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.h +++ b/contrib/python/protobuf/py3/google/protobuf/pyext/unknown_fields.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_UNKNOWN_FIELDS_H__ #define GOOGLE_PROTOBUF_PYTHON_CPP_UNKNOWN_FIELDS_H__ +#define PY_SSIZE_T_CLEAN #include <Python.h> #include <memory> diff --git a/contrib/python/protobuf/py3/google/protobuf/service_reflection.py b/contrib/python/protobuf/py3/google/protobuf/service_reflection.py index 75c51ff322..f82ab7145a 100644 --- a/contrib/python/protobuf/py3/google/protobuf/service_reflection.py +++ b/contrib/python/protobuf/py3/google/protobuf/service_reflection.py @@ -133,7 +133,7 @@ class _ServiceBuilder(object): """ self.descriptor = service_descriptor - def BuildService(self, cls): + def BuildService(builder, cls): """Constructs the service class. Args: @@ -143,18 +143,26 @@ class _ServiceBuilder(object): # CallMethod needs to operate with an instance of the Service class. This # internal wrapper function exists only to be able to pass the service # instance to the method that does the real CallMethod work. - def _WrapCallMethod(srvc, method_descriptor, - rpc_controller, request, callback): - return self._CallMethod(srvc, method_descriptor, - rpc_controller, request, callback) - self.cls = cls + # Making sure to use exact argument names from the abstract interface in + # service.py to match the type signature + def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): + return builder._CallMethod(self, method_descriptor, rpc_controller, + request, done) + + def _WrapGetRequestClass(self, method_descriptor): + return builder._GetRequestClass(method_descriptor) + + def _WrapGetResponseClass(self, method_descriptor): + return builder._GetResponseClass(method_descriptor) + + builder.cls = cls cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: self.descriptor) - cls.GetDescriptor.__doc__ = "Returns the service descriptor." - cls.GetRequestClass = self._GetRequestClass - cls.GetResponseClass = self._GetResponseClass - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) + cls.GetDescriptor = staticmethod(lambda: builder.descriptor) + cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' + cls.GetRequestClass = _WrapGetRequestClass + cls.GetResponseClass = _WrapGetResponseClass + for method in builder.descriptor.methods: + setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) def _CallMethod(self, srvc, method_descriptor, rpc_controller, request, callback): diff --git a/contrib/python/protobuf/py3/ya.make b/contrib/python/protobuf/py3/ya.make index 7850737cdc..93b23a6f9b 100644 --- a/contrib/python/protobuf/py3/ya.make +++ b/contrib/python/protobuf/py3/ya.make @@ -9,9 +9,9 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(3.19.0) +VERSION(3.20.3) -ORIGINAL_SOURCE(mirror://pypi/p/protobuf/protobuf-3.19.0.tar.gz) +ORIGINAL_SOURCE(mirror://pypi/p/protobuf/protobuf-3.20.3.tar.gz) PEERDIR( contrib/libs/protobuf @@ -64,6 +64,7 @@ PY_SRCS( google/protobuf/descriptor_pool.py google/protobuf/internal/__init__.py google/protobuf/internal/api_implementation.py + google/protobuf/internal/builder.py google/protobuf/internal/containers.py google/protobuf/internal/decoder.py google/protobuf/internal/encoder.py |