Add Builder and Reader ABCs for each struct type

This has zero overhead if not used.  I decided that it was simpler
to use ABCs instead of real classes, given that using real classes
offers little benefit.

This also implements == and != for StructSchema objects.
This commit is contained in:
Andy Lutomirski
2013-09-03 11:01:12 -07:00
parent 47ee1a87a3
commit b3264a7292
2 changed files with 32 additions and 0 deletions

View File

@@ -807,6 +807,14 @@ cdef class _StructSchema:
def __get__(self): def __get__(self):
return _DynamicStructReader()._init(self.thisptr.getProto(), None) return _DynamicStructReader()._init(self.thisptr.getProto(), None)
def __richcmp__(_StructSchema self, _StructSchema other, mode):
if mode == 2:
return bool(self.thisptr == other.thisptr)
elif mode == 3:
return not (self.thisptr == other.thisptr)
else:
raise NotImplementedError()
def __repr__(self): def __repr__(self):
return '<schema for %s>' % self.node.displayName return '<schema for %s>' % self.node.displayName
@@ -831,6 +839,11 @@ cdef class _ParsedSchema:
cpdef getNested(self, name): cpdef getNested(self, name):
return _ParsedSchema()._init(self.thisptr.getNested(name)) return _ParsedSchema()._init(self.thisptr.getNested(name))
class _StructABCMeta(type):
"""A metaclass for the Type.Reader and Type.Builder ABCs."""
def __instancecheck__(cls, obj):
return isinstance(obj, cls.__base__) and obj.schema == cls._schema
cdef class SchemaParser: cdef class SchemaParser:
"""A class for loading Cap'n Proto schema files. """A class for loading Cap'n Proto schema files.
@@ -926,11 +939,28 @@ cdef class SchemaParser:
_from_dict(msg, d) _from_dict(msg, d)
return msg return msg
return helper return helper
class Reader(_DynamicStructReader):
"""An abstract base class. Readers are 'instances' of this class."""
__metaclass__ = _StructABCMeta
__slots__ = []
_schema = local_module.schema
def __new__(self):
raise TypeError('This is an abstract base class')
Reader._module = local_module
class Builder(_DynamicStructBuilder):
"""An abstract base class. Builders are 'instances' of this class."""
__metaclass__ = _StructABCMeta
__slots__ = []
_schema = local_module.schema
def __new__(self):
raise TypeError('This is an abstract base class')
local_module.read = read(local_module) local_module.read = read(local_module)
local_module.read_packed = read_packed(local_module) local_module.read_packed = read_packed(local_module)
local_module.new_message = new_message(local_module) local_module.new_message = new_message(local_module)
local_module.from_dict = from_dict(local_module) local_module.from_dict = from_dict(local_module)
local_module.Reader = Reader
local_module.Builder = Builder
elif proto.isConst: elif proto.isConst:
module.__dict__[node.name] = schema.as_const_value() module.__dict__[node.name] = schema.as_const_value()

View File

@@ -60,6 +60,8 @@ cdef extern from "capnp/schema.h" namespace " ::capnp":
Field getFieldByName(char * name) Field getFieldByName(char * name)
int operator == (StructSchema)
cdef cppclass EnumSchema: cdef cppclass EnumSchema:
cppclass Enumerant: cppclass Enumerant:
EnumNode.Enumerant.Reader getProto() EnumNode.Enumerant.Reader getProto()