A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/protocolbuffers/protobuf/commit/49d9e2dca5dfc2bd662e87a9039e1270391803ec below:

Change proto_api work with custom pool for upb and pure python. · protocolbuffers/protobuf@49d9e2d · GitHub

@@ -34,29 +34,9 @@ namespace {

34 34 35 35

class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase {

36 36

public:

37 -

ProtoAPIDescriptorDatabase() {

38 -

PyObject* descriptor_pool =

39 -

PyImport_ImportModule("google.protobuf.descriptor_pool");

40 -

if (descriptor_pool == nullptr) {

41 -

ABSL_LOG(ERROR)

42 -

<< "Failed to import google.protobuf.descriptor_pool module.";

43 -

}

37 +

ProtoAPIDescriptorDatabase(PyObject* py_pool) : pool_(py_pool) {};

44 38 45 -

pool_ = PyObject_CallMethod(descriptor_pool, "Default", nullptr);

46 -

if (pool_ == nullptr) {

47 -

ABSL_LOG(ERROR) << "Failed to get python Default pool.";

48 -

}

49 -

Py_DECREF(descriptor_pool);

50 -

};

51 - 52 -

~ProtoAPIDescriptorDatabase() {

53 -

// Objects of this class are meant to be `static`ally initialized and

54 -

// never destroyed. This is a commonly used approach, because the order

55 -

// in which destructors of static objects run is unpredictable. In

56 -

// particular, it is possible that the Python interpreter may have been

57 -

// finalized already.

58 -

ABSL_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";

59 -

};

39 +

~ProtoAPIDescriptorDatabase() {};

60 40 61 41

bool FindFileByName(StringViewArg filename,

62 42

google::protobuf::FileDescriptorProto* output) override {

@@ -112,52 +92,150 @@ class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase {

112 92

PyObject* pool_;

113 93

};

114 94 95 +

struct DescriptorPoolState {

96 +

// clang-format off

97 +

PyObject_HEAD

98 + 99 +

std::unique_ptr<google::protobuf::DescriptorPool> pool;

100 +

std::unique_ptr<ProtoAPIDescriptorDatabase> database;

101 +

};

102 + 103 +

void DeallocDescriptorPoolState (DescriptorPoolState* self) {

104 +

self->database.reset();

105 +

self->pool.reset();

106 +

Py_TYPE(self)->tp_free((PyObject *)self);

107 +

}

108 + 109 +

PyTypeObject PyDescriptorPoolState_Type = {

110 +

PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME

111 +

".DescriptorPoolState", // tp_name

112 +

sizeof(DescriptorPoolState), // tp_basicsize

113 +

0, // tp_itemsize

114 +

(destructor)DeallocDescriptorPoolState, // tp_dealloc

115 +

0, // tp_vectorcall_offset

116 +

nullptr, // tp_getattr

117 +

nullptr, // tp_setattr

118 +

nullptr, // tp_compare

119 +

nullptr, // tp_repr

120 +

nullptr, // tp_as_number

121 +

nullptr, // tp_as_sequence

122 +

nullptr, // tp_as_mapping

123 +

PyObject_HashNotImplemented, // tp_hash

124 +

nullptr, // tp_call

125 +

nullptr, // tp_str

126 +

nullptr, // tp_getattro

127 +

nullptr, // tp_setattro

128 +

nullptr, // tp_as_buffer

129 +

Py_TPFLAGS_DEFAULT, // tp_flags

130 +

"DescriptorPoolState", // tp_doc

131 +

};

132 + 133 +

PyObject* PyDescriptorPoolState_New(PyObject* pyfile_pool) {

134 +

PyObject* pypool_state = PyType_GenericAlloc(&PyDescriptorPoolState_Type, 0);

135 +

if (pypool_state == nullptr) {

136 +

PyErr_SetString(PyExc_MemoryError,

137 +

"Fail to new PyDescriptorPoolState_Type");

138 +

return nullptr;

139 +

}

140 +

DescriptorPoolState* pool_state =

141 +

reinterpret_cast<DescriptorPoolState*>(pypool_state);

142 +

pool_state->database =

143 +

std::make_unique<ProtoAPIDescriptorDatabase>(pyfile_pool);

144 +

pool_state->pool =

145 +

std::make_unique<google::protobuf::DescriptorPool>(pool_state->database.get());

146 +

return pypool_state;

147 +

}

148 + 149 +

PyObject* InitAndGetPoolMap() {

150 +

#if PY_VERSION_HEX >= 0x030C0000

151 +

// Returns a WeakKeyDictionary. The key will be a python pool and

152 +

// the value will be PyDescriptorPoolState_Type.

153 +

// PyDescriptorPoolState_Type should be ready for the usage.

154 +

if (PyType_Ready(&PyDescriptorPoolState_Type) < 0) {

155 +

return nullptr;

156 +

}

157 +

PyObject* weakref = PyImport_ImportModule("weakref");

158 +

PyObject* pypool_map =

159 +

PyObject_CallMethod(weakref, "WeakKeyDictionary", NULL);

160 +

Py_DECREF(weakref);

161 +

return pypool_map;

162 +

#else

163 +

return PyDict_New();

164 +

#endif

165 +

}

166 + 115 167

absl::StatusOr<const google::protobuf::Descriptor*> FindMessageDescriptor(

116 168

PyObject* pyfile, const char* descriptor_full_name) {

117 -

static auto* database = new ProtoAPIDescriptorDatabase();

118 -

static auto* pool = new google::protobuf::DescriptorPool(database);

119 -

PyObject* pyfile_name = PyObject_GetAttrString(pyfile, "name");

169 +

static PyObject* pypool_map = InitAndGetPoolMap();

170 +

if (pypool_map == nullptr) {

171 +

return absl::InternalError("Fail to create pypool_map");

172 +

}

173 +

PyObject* pyfile_name = nullptr;

174 +

PyObject* pyfile_pool = nullptr;

175 +

PyObject* pypool_state = nullptr;

176 +

google::protobuf::DescriptorPool* pool;

177 +

DescriptorPoolState* pool_state;

178 +

const char* pyfile_name_char_ptr;

179 +

const google::protobuf::FileDescriptor* file_descriptor;

180 +

absl::StatusOr<const google::protobuf::Descriptor*> ret;

181 + 182 +

pyfile_name = PyObject_GetAttrString(pyfile, "name");

120 183

if (pyfile_name == nullptr) {

121 -

return absl::InvalidArgumentError("FileDescriptor has no attribute 'name'");

184 +

ret = absl::InvalidArgumentError("FileDescriptor has no attribute 'name'");

185 +

goto err;

122 186

}

123 -

PyObject* pyfile_pool = PyObject_GetAttrString(pyfile, "pool");

187 +

pyfile_pool = PyObject_GetAttrString(pyfile, "pool");

124 188

if (pyfile_pool == nullptr) {

125 -

Py_DECREF(pyfile_name);

126 -

return absl::InvalidArgumentError("FileDescriptor has no attribute 'pool'");

189 +

ret = absl::InvalidArgumentError("FileDescriptor has no attribute 'pool'");

190 +

goto err;

191 +

}

192 + 193 +

pypool_state = PyObject_GetItem(pypool_map, pyfile_pool);

194 +

if (pypool_state == nullptr) {

195 +

if (PyErr_ExceptionMatches(PyExc_KeyError)) {

196 +

// Ignore the KeyError

197 +

PyErr_Clear();

198 +

}

199 +

PyErr_Print();

200 +

pypool_state = PyDescriptorPoolState_New(pyfile_pool);

201 +

if (pypool_state == nullptr) {

202 +

ret = absl::InternalError("Fail to create PyDescriptorPoolState_Type");

203 +

goto err;

204 +

}

205 +

if (PyObject_SetItem(pypool_map, pyfile_pool, pypool_state) < 0) {

206 +

ret = absl::InternalError(

207 +

"Fail to insert PyDescriptorPoolState_Type into pypool_map");

208 +

goto err;

209 +

}

127 210

}

128 -

// Check the file descriptor is from generated pool.

129 -

bool is_from_generated_pool = database->pool() == pyfile_pool;

130 -

Py_DECREF(pyfile_pool);

131 -

const char* pyfile_name_char_ptr = PyUnicode_AsUTF8(pyfile_name);

211 +

pool_state = reinterpret_cast<DescriptorPoolState*>(pypool_state);

212 +

pool = pool_state->pool.get();

213 +

pyfile_name_char_ptr = PyUnicode_AsUTF8(pyfile_name);

132 214

if (pyfile_name_char_ptr == nullptr) {

133 -

Py_DECREF(pyfile_name);

134 -

return absl::InvalidArgumentError(

215 +

ret = absl::InvalidArgumentError(

135 216

"FileDescriptor 'name' PyUnicode_AsUTF8() failure.");

217 +

goto err;

136 218

}

137 -

if (!is_from_generated_pool) {

138 -

std::string error_msg = absl::StrCat(pyfile_name_char_ptr,

139 -

" is not from generated pool");

140 -

Py_DECREF(pyfile_name);

141 -

return absl::InvalidArgumentError(error_msg);

142 -

}

143 -

const google::protobuf::FileDescriptor* file_descriptor =

144 -

pool->FindFileByName(pyfile_name_char_ptr);

145 -

Py_DECREF(pyfile_name);

219 +

file_descriptor = pool->FindFileByName(pyfile_name_char_ptr);

146 220

if (file_descriptor == nullptr) {

147 -

// Already checked the file is from generated pool above, this

148 -

// error should never be reached.

221 +

// This error should never be reached.

149 222

ABSL_DLOG(ERROR) << "MEANT TO BE UNREACHABLE.";

150 223

std::string error_msg = absl::StrCat("Fail to find/build file ",

151 224

pyfile_name_char_ptr);

152 -

return absl::InternalError(error_msg);

225 +

ret = absl::InternalError(error_msg);

226 +

goto err;

153 227

}

154 228 155 -

const google::protobuf::Descriptor* descriptor =

156 -

pool->FindMessageTypeByName(descriptor_full_name);

157 -

if (descriptor == nullptr) {

158 -

return absl::InternalError("Fail to find descriptor by name.");

229 +

ret = pool->FindMessageTypeByName(descriptor_full_name);

230 +

if (ret.value() == nullptr) {

231 +

ret = absl::InternalError("Fail to find descriptor by name.");

159 232

}

160 -

return descriptor;

233 + 234 +

err:

235 +

Py_XDECREF(pyfile_name);

236 +

Py_XDECREF(pyfile_pool);

237 +

Py_XDECREF(pypool_state);

238 +

return ret;

161 239

}

162 240 163 241

google::protobuf::DynamicMessageFactory* GetFactory() {

@@ -199,8 +277,8 @@ absl::StatusOr<google::protobuf::Message*> CreateNewMessage(PyObject* py_msg) {

199 277

}

200 278

auto d = FindMessageDescriptor(pyfile, descriptor_full_name);

201 279

Py_DECREF(pyfile);

202 -

RETURN_IF_ERROR(d.status());

203 280

Py_DECREF(fn);

281 +

RETURN_IF_ERROR(d.status());

204 282

return GetFactory()->GetPrototype(*d)->New();

205 283

}

206 284

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4