我想为一组protobuf消息发布一个python包。 protobuf编译器(protoc
)生成一个python库,它实际上并没有定义典型意义上的类型/类,而是动态地构造它们。有没有办法提示pylint这些类的成员和字段是什么?
例如,请考虑以下简单的protobuf消息规范:
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
}
编译器生成以下长堆代码:
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: test.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='test.proto',
package='',
serialized_pb=_b('\n\ntest.proto\"1\n\x06Person\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\n\n\x02id\x18\x02 \x02(\x05\x12\r\n\x05\x65mail\x18\x03 \x01(\t')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_PERSON = _descriptor.Descriptor(
name='Person',
full_name='Person',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='Person.name', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='id', full_name='Person.id', index=1,
number=2, type=5, cpp_type=1, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='email', full_name='Person.email', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=14,
serialized_end=63,
)
DESCRIPTOR.message_types_by_name['Person'] = _PERSON
Person = _reflection.GeneratedProtocolMessageType('Person', (_message.Message,), dict(
DESCRIPTOR = _PERSON,
__module__ = 'test_pb2'
# @@protoc_insertion_point(class_scope:Person)
))
_sym_db.RegisterMessage(Person)
# @@protoc_insertion_point(module_scope)
答案 0 :(得分:1)
似乎不支持自动提示proyluf消息上的字段名称给Pylint,因此我拼凑了一个对Pylint的扩展以静态确定它们。
from example_pb2 import Person
p = Person()
p.invalid_field = 123
用法:
$ pip install pylint-protobuf
$ pylint --load-plugins=pylint_protobuf example.py
************* Module example
E: 3, 0: Field 'invalid_field' does not appear in the declared
fields of protobuf-generated class 'Person' and will raise
AttributeError on access (protobuf-undefined-attribute)
警告:这是相当漂亮的Alpha,尚不支持(但!)功能,包括嵌套导入和重复字段。