Breaking change: Remove deprecated syntax accessor.

This has been replaced by edition and feature getters.  Any code depending on syntax will likely be broken by editions files, and should be migrated to the finer-grained feature helpers.

PiperOrigin-RevId: 589866745
pull/14968/head
Mike Kruskal 1 year ago committed by Copybara-Service
parent a303ccbe05
commit fd40c87bef
  1. 41
      python/descriptor.c
  2. 28
      python/google/protobuf/descriptor.py
  3. 4
      python/google/protobuf/internal/descriptor_test.py
  4. 26
      python/google/protobuf/pyext/descriptor.cc

@ -648,18 +648,6 @@ static PyObject* PyUpb_Descriptor_GetOneofsByName(PyObject* _self,
return PyUpb_ByNameMap_New(&funcs, self->def, self->pool); return PyUpb_ByNameMap_New(&funcs, self->def, self->pool);
} }
static PyObject* PyUpb_Descriptor_GetSyntax(PyObject* self, void* closure) {
PyErr_WarnEx(NULL,
"descriptor.syntax is deprecated. It will be removed soon. "
"Most usages are checking field descriptors. Consider to use "
"has_presence, is_packed on field descriptors.",
1);
const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self);
const char* syntax =
upb_MessageDef_Syntax(msgdef) == kUpb_Syntax_Proto2 ? "proto2" : "proto3";
return PyUnicode_InternFromString(syntax);
}
static PyGetSetDef PyUpb_Descriptor_Getters[] = { static PyGetSetDef PyUpb_Descriptor_Getters[] = {
{"name", PyUpb_Descriptor_GetName, NULL, "Last name"}, {"name", PyUpb_Descriptor_GetName, NULL, "Last name"},
{"full_name", PyUpb_Descriptor_GetFullName, NULL, "Full name"}, {"full_name", PyUpb_Descriptor_GetFullName, NULL, "Full name"},
@ -694,13 +682,6 @@ static PyGetSetDef PyUpb_Descriptor_Getters[] = {
"Containing type"}, "Containing type"},
{"is_extendable", PyUpb_Descriptor_GetIsExtendable, NULL}, {"is_extendable", PyUpb_Descriptor_GetIsExtendable, NULL},
{"has_options", PyUpb_Descriptor_GetHasOptions, NULL, "Has Options"}, {"has_options", PyUpb_Descriptor_GetHasOptions, NULL, "Has Options"},
// begin:github_only
{"syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"},
// end:github_only
// begin:google_only
// // TODO Use this to open-source syntax deprecation.
// {"deprecated_syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"},
// end:google_only
{NULL}}; {NULL}};
static PyMethodDef PyUpb_Descriptor_Methods[] = { static PyMethodDef PyUpb_Descriptor_Methods[] = {
@ -1384,17 +1365,10 @@ static PyObject* PyUpb_FileDescriptor_GetPublicDependencies(PyObject* _self,
return PyUpb_GenericSequence_New(&funcs, self->def, self->pool); return PyUpb_GenericSequence_New(&funcs, self->def, self->pool);
} }
static PyObject* PyUpb_FileDescriptor_GetSyntax(PyObject* _self, static PyObject* PyUpb_FileDescriptor_GetEdition(PyObject* _self,
void* closure) { void* closure) {
PyErr_WarnEx(NULL,
"descriptor.syntax is deprecated. It will be removed soon. "
"Most usages are checking field descriptors. Consider to use "
"has_presence, is_packed on field descriptors.",
1);
PyUpb_DescriptorBase* self = (void*)_self; PyUpb_DescriptorBase* self = (void*)_self;
const char* syntax = return PyLong_FromLong(upb_FileDef_Edition(self->def));
upb_FileDef_Syntax(self->def) == kUpb_Syntax_Proto2 ? "proto2" : "proto3";
return PyUnicode_FromString(syntax);
} }
static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self, static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self,
@ -1445,14 +1419,7 @@ static PyGetSetDef PyUpb_FileDescriptor_Getters[] = {
{"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL, {"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL,
"Dependencies"}, "Dependencies"},
{"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"}, {"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"},
// begin:github_only {"edition", PyUpb_FileDescriptor_GetEdition, (setter)NULL, "Edition"},
{"syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL, "Syntax"},
// end:github_only
// begin:google_only
// // TODO Use this to open-source syntax deprecation.
// {"deprecated_syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL,
// "Syntax"},
// end:google_only
{NULL}, {NULL},
}; };

@ -1179,24 +1179,23 @@ class FileDescriptor(DescriptorBase):
Attributes: Attributes:
name (str): Name of file, relative to root of source tree. name (str): Name of file, relative to root of source tree.
package (str): Name of the package package (str): Name of the package
syntax (str): string indicating syntax of the file (can be "proto2" or edition (Edition): Enum value indicating edition of the file
"proto3")
serialized_pb (bytes): Byte string of serialized serialized_pb (bytes): Byte string of serialized
:class:`descriptor_pb2.FileDescriptorProto`. :class:`descriptor_pb2.FileDescriptorProto`.
dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor`
objects this :class:`FileDescriptor` depends on. objects this :class:`FileDescriptor` depends on.
public_dependencies (list[FileDescriptor]): A subset of public_dependencies (list[FileDescriptor]): A subset of
:attr:`dependencies`, which were declared as "public". :attr:`dependencies`, which were declared as "public".
message_types_by_name (dict(str, Descriptor)): Mapping from message names message_types_by_name (dict(str, Descriptor)): Mapping from message names to
to their :class:`Descriptor`. their :class:`Descriptor`.
enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to
their :class:`EnumDescriptor`. their :class:`EnumDescriptor`.
extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension
names declared at file scope to their :class:`FieldDescriptor`. names declared at file scope to their :class:`FieldDescriptor`.
services_by_name (dict(str, ServiceDescriptor)): Mapping from services' services_by_name (dict(str, ServiceDescriptor)): Mapping from services'
names to their :class:`ServiceDescriptor`. names to their :class:`ServiceDescriptor`.
pool (DescriptorPool): The pool this descriptor belongs to. When not pool (DescriptorPool): The pool this descriptor belongs to. When not passed
passed to the constructor, the global default pool is used. to the constructor, the global default pool is used.
""" """
if _USE_C_DESCRIPTORS: if _USE_C_DESCRIPTORS:
@ -1260,7 +1259,6 @@ class FileDescriptor(DescriptorBase):
self.message_types_by_name = {} self.message_types_by_name = {}
self.name = name self.name = name
self.package = package self.package = package
self._deprecated_syntax = syntax or "proto2"
self.serialized_pb = serialized_pb self.serialized_pb = serialized_pb
self.enum_types_by_name = {} self.enum_types_by_name = {}
@ -1269,15 +1267,6 @@ class FileDescriptor(DescriptorBase):
self.dependencies = (dependencies or []) self.dependencies = (dependencies or [])
self.public_dependencies = (public_dependencies or []) self.public_dependencies = (public_dependencies or [])
@property
def syntax(self):
warnings.warn(
'descriptor.syntax is deprecated. It will be removed'
' soon. Most usages are checking field descriptors. Consider to use'
' has_presence, is_packed on field descriptors.'
)
return self._deprecated_syntax
def CopyToProto(self, proto): def CopyToProto(self, proto):
"""Copies this to a descriptor_pb2.FileDescriptorProto. """Copies this to a descriptor_pb2.FileDescriptorProto.
@ -1290,6 +1279,13 @@ class FileDescriptor(DescriptorBase):
def _parent(self): def _parent(self):
return None return None
@property
def edition(self):
# pylint: disable=g-import-not-at-top
from google.protobuf import descriptor_pb2
return descriptor_pb2.Edition.Value(self._edition)
def _ParseOptions(message, string): def _ParseOptions(message, string):
"""Parses serialized options. """Parses serialized options.

@ -539,7 +539,9 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(self.my_file.package, 'protobuf_unittest') self.assertEqual(self.my_file.package, 'protobuf_unittest')
self.assertEqual(self.my_file.pool, self.pool) self.assertEqual(self.my_file.pool, self.pool)
self.assertFalse(self.my_file.has_options) self.assertFalse(self.my_file.has_options)
self.assertEqual(self.my_file.syntax, 'proto2') self.assertEqual(
self.my_file.edition, descriptor_pb2.Edition.EDITION_PROTO2
)
file_proto = descriptor_pb2.FileDescriptorProto() file_proto = descriptor_pb2.FileDescriptorProto()
self.my_file.CopyToProto(file_proto) self.my_file.CopyToProto(file_proto)
self.assertEqual(self.my_file.serialized_pb, self.assertEqual(self.my_file.serialized_pb,

@ -22,7 +22,6 @@
#include "absl/log/absl_check.h" #include "absl/log/absl_check.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/dynamic_message.h" #include "google/protobuf/dynamic_message.h"
#include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/pyext/descriptor_containers.h" #include "google/protobuf/pyext/descriptor_containers.h"
@ -696,17 +695,6 @@ static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) {
return PyString_FromCppString(enum_value->name()); return PyString_FromCppString(enum_value->name());
} }
static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) {
PyErr_WarnEx(nullptr,
"descriptor.syntax is deprecated. It will be removed soon. "
"Most usages are checking field descriptors. Consider to use "
"has_presence, is_packed on field descriptors.",
1);
std::string syntax(FileDescriptorLegacy::SyntaxName(
FileDescriptorLegacy(_GetDescriptor(self)->file()).syntax()));
return PyUnicode_InternFromString(syntax.c_str());
}
static PyGetSetDef Getters[] = { static PyGetSetDef Getters[] = {
{"name", (getter)GetName, nullptr, "Last name"}, {"name", (getter)GetName, nullptr, "Last name"},
{"full_name", (getter)GetFullName, nullptr, "Full name"}, {"full_name", (getter)GetFullName, nullptr, "Full name"},
@ -743,7 +731,6 @@ static PyGetSetDef Getters[] = {
{"_options", (getter) nullptr, (setter)SetOptions, "Options"}, {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
{"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
"Serialized Options"}, "Serialized Options"},
{"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"},
{nullptr}, {nullptr},
}; };
@ -1542,15 +1529,8 @@ static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value,
return CheckCalledFromGeneratedFile("_serialized_options"); return CheckCalledFromGeneratedFile("_serialized_options");
} }
static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { static PyObject* GetEdition(PyFileDescriptor* self, void* closure) {
PyErr_WarnEx(nullptr, return PyLong_FromLong(_GetDescriptor(self)->edition());
"descriptor.syntax is deprecated. It will be removed soon. "
"Most usages are checking field descriptors. Consider to use "
"has_presence, is_packed on field descriptors.",
1);
std::string syntax(FileDescriptorLegacy::SyntaxName(
FileDescriptorLegacy(_GetDescriptor(self)).syntax()));
return PyUnicode_InternFromString(syntax.c_str());
} }
static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
@ -1579,7 +1559,7 @@ static PyGetSetDef Getters[] = {
{"_options", (getter) nullptr, (setter)SetOptions, "Options"}, {"_options", (getter) nullptr, (setter)SetOptions, "Options"},
{"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions,
"Serialized Options"}, "Serialized Options"},
{"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, {"edition", (getter)GetEdition, (setter) nullptr, "Edition"},
{nullptr}, {nullptr},
}; };

Loading…
Cancel
Save