[Checkins] SVN: keas.pbpersist/ Added keas.pbpersist, a layer over keas.pbstate that serializes in ZODB
Shane Hathaway
shane at hathawaymix.org
Wed Jan 21 19:48:09 EST 2009
Log message for revision 94914:
Added keas.pbpersist, a layer over keas.pbstate that serializes in ZODB
without any pickling.
Changed:
A keas.pbpersist/
A keas.pbpersist/trunk/
A keas.pbpersist/trunk/.installed.cfg
A keas.pbpersist/trunk/bootstrap.py
A keas.pbpersist/trunk/buildout.cfg
A keas.pbpersist/trunk/setup.py
A keas.pbpersist/trunk/src/
A keas.pbpersist/trunk/src/keas/
A keas.pbpersist/trunk/src/keas/__init__.py
A keas.pbpersist/trunk/src/keas/pbpersist/
A keas.pbpersist/trunk/src/keas/pbpersist/README.txt
A keas.pbpersist/trunk/src/keas/pbpersist/__init__.py
A keas.pbpersist/trunk/src/keas/pbpersist/pbformat.py
A keas.pbpersist/trunk/src/keas/pbpersist/persistent.proto
A keas.pbpersist/trunk/src/keas/pbpersist/persistent_pb2.py
A keas.pbpersist/trunk/src/keas/pbpersist/tests.py
-=-
Added: keas.pbpersist/trunk/.installed.cfg
===================================================================
--- keas.pbpersist/trunk/.installed.cfg (rev 0)
+++ keas.pbpersist/trunk/.installed.cfg 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,69 @@
+[buildout]
+installed_develop_eggs = /home/shane/svn/keas.pbpersist/trunk/develop-eggs/keas.pbstate.egg-link
+parts = test python coverage-test coverage-report
+
+[test]
+__buildout_installed__ = /home/shane/svn/keas.pbpersist/trunk/parts/test
+ /home/shane/svn/keas.pbpersist/trunk/bin/test
+__buildout_signature__ = zc.recipe.testrunner-1.1.0-py2.5.egg zc.recipe.egg-1.1.0-py2.5.egg setuptools-0.6c9-py2.5.egg zope.testing-3.7.1-py2.5.egg zc.buildout-1.1.1-py2.5.egg zc.buildout-1.1.1-py2.5.egg zope.interface-3.5.0-py2.5-linux-x86_64.egg
+_b = /home/shane/svn/keas.pbpersist/trunk/bin
+_d = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+_e = /home/shane/.buildout/eggs
+bin-directory = /home/shane/svn/keas.pbpersist/trunk/bin
+develop-eggs-directory = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+eggs = keas.pbpersist
+eggs-directory = /home/shane/.buildout/eggs
+executable = /usr/bin/python
+find-links = http://packages.willowrise.org
+location = /home/shane/svn/keas.pbpersist/trunk/parts/test
+recipe = zc.recipe.testrunner
+script = /home/shane/svn/keas.pbpersist/trunk/bin/test
+
+[python]
+__buildout_installed__ = /home/shane/svn/keas.pbpersist/trunk/bin/python
+__buildout_signature__ = zc.recipe.egg-1.1.0-py2.5.egg setuptools-0.6c9-py2.5.egg zc.buildout-1.1.1-py2.5.egg
+_b = /home/shane/svn/keas.pbpersist/trunk/bin
+_d = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+_e = /home/shane/.buildout/eggs
+bin-directory = /home/shane/svn/keas.pbpersist/trunk/bin
+develop-eggs-directory = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+eggs = keas.pbpersist
+eggs-directory = /home/shane/.buildout/eggs
+executable = /usr/bin/python
+find-links = http://packages.willowrise.org
+interpreter = python
+recipe = zc.recipe.egg
+
+[coverage-test]
+__buildout_installed__ = /home/shane/svn/keas.pbpersist/trunk/parts/coverage-test
+ /home/shane/svn/keas.pbpersist/trunk/bin/coverage-test
+__buildout_signature__ = zc.recipe.testrunner-1.1.0-py2.5.egg zc.recipe.egg-1.1.0-py2.5.egg setuptools-0.6c9-py2.5.egg zope.testing-3.7.1-py2.5.egg zc.buildout-1.1.1-py2.5.egg zc.buildout-1.1.1-py2.5.egg zope.interface-3.5.0-py2.5-linux-x86_64.egg
+_b = /home/shane/svn/keas.pbpersist/trunk/bin
+_d = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+_e = /home/shane/.buildout/eggs
+bin-directory = /home/shane/svn/keas.pbpersist/trunk/bin
+defaults = ['--coverage', '../../coverage']
+develop-eggs-directory = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+eggs = keas.pbpersist
+eggs-directory = /home/shane/.buildout/eggs
+executable = /usr/bin/python
+find-links = http://packages.willowrise.org
+location = /home/shane/svn/keas.pbpersist/trunk/parts/coverage-test
+recipe = zc.recipe.testrunner
+script = /home/shane/svn/keas.pbpersist/trunk/bin/coverage-test
+
+[coverage-report]
+__buildout_installed__ = /home/shane/svn/keas.pbpersist/trunk/bin/coverage-report
+__buildout_signature__ = zc.recipe.egg-1.1.0-py2.5.egg setuptools-0.6c9-py2.5.egg zc.buildout-1.1.1-py2.5.egg
+_b = /home/shane/svn/keas.pbpersist/trunk/bin
+_d = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+_e = /home/shane/.buildout/eggs
+arguments = ('coverage', 'coverage/report')
+bin-directory = /home/shane/svn/keas.pbpersist/trunk/bin
+develop-eggs-directory = /home/shane/svn/keas.pbpersist/trunk/develop-eggs
+eggs = z3c.coverage
+eggs-directory = /home/shane/.buildout/eggs
+executable = /usr/bin/python
+find-links = http://packages.willowrise.org
+recipe = zc.recipe.egg
+scripts = coverage=coverage-report
Added: keas.pbpersist/trunk/bootstrap.py
===================================================================
--- keas.pbpersist/trunk/bootstrap.py (rev 0)
+++ keas.pbpersist/trunk/bootstrap.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py,v 1.1 2009/01/10 15:13:39 shane Exp $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+# use pkg_resources from the package just downloaded.
+del sys.modules['pkg_resources']
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: keas.pbpersist/trunk/buildout.cfg
===================================================================
--- keas.pbpersist/trunk/buildout.cfg (rev 0)
+++ keas.pbpersist/trunk/buildout.cfg 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,29 @@
+[buildout]
+develop = .
+ ../../keas.pbstate/trunk
+parts = test python coverage-test coverage-report
+find-links = http://packages.willowrise.org
+versions = versions
+
+[versions]
+ZODB3 = 3.8.1-polling-serial
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = keas.pbpersist
+
+[python]
+recipe = zc.recipe.egg
+eggs = keas.pbpersist
+interpreter = python
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = keas.pbpersist
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
Added: keas.pbpersist/trunk/setup.py
===================================================================
--- keas.pbpersist/trunk/setup.py (rev 0)
+++ keas.pbpersist/trunk/setup.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from setuptools import setup
+
+setup(
+ name='keas.pbpersist',
+ version='0.1dev',
+ author='Shane Hathaway and the Zope Community',
+ author_email='zope-dev at zope.org',
+ description='ZODB Persistence in a Google Protocol Buffer',
+ license='ZPL 2.1',
+
+ package_dir={'': 'src'},
+ packages=['keas.pbpersist'],
+ namespace_packages=['keas'],
+ install_requires=[
+ 'setuptools',
+ 'keas.pbstate',
+ 'ZODB3',
+ ],
+)
Added: keas.pbpersist/trunk/src/keas/__init__.py
===================================================================
--- keas.pbpersist/trunk/src/keas/__init__.py (rev 0)
+++ keas.pbpersist/trunk/src/keas/__init__.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
Added: keas.pbpersist/trunk/src/keas/pbpersist/README.txt
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/README.txt (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/README.txt 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,47 @@
+
+
+Tests of keas.pbpersist
+=======================
+
+Create a PContact instance. PContact is a Persistent class that stores
+its state in a protobuf instance.
+
+ >>> from keas.pbpersist.tests import PContact
+ >>> pc = PContact()
+ >>> pc.__getstate__()
+ Traceback (most recent call last):
+ ...
+ EncodeError: Required field ContactPB.name is not set.
+ >>> pc.name = u'Joe'
+ >>> pc.__getstate__()
+ ('\x08\x01\x12\x03Joe', {})
+
+Register the protobuf serializer with ZODB.
+
+ >>> from keas.pbpersist.pbformat import register
+ >>> register()
+
+Set up an in-memory database and put the PContact in it.
+
+ >>> from ZODB.DemoStorage import DemoStorage
+ >>> from ZODB.DB import DB
+ >>> import transaction
+ >>> storage = DemoStorage()
+ >>> db = DB(storage)
+ >>> conn1 = db.open()
+ >>> conn1.root()['contact'] = pc
+ >>> transaction.commit()
+
+Read the PContact from another connection.
+
+ >>> conn2 = db.open()
+ >>> pc2 = conn2.root()['contact']
+ >>> pc2.name
+ u'Joe'
+ >>> conn2.close()
+
+Close the object database.
+
+ >>> transaction.abort()
+ >>> conn1.close()
+ >>> db.close()
Added: keas.pbpersist/trunk/src/keas/pbpersist/__init__.py
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/__init__.py (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/__init__.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1 @@
+
Added: keas.pbpersist/trunk/src/keas/pbpersist/pbformat.py
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/pbformat.py (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/pbformat.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,180 @@
+
+
+"""A serializer for ZODB that stores protobuf messages instead of pickles."""
+
+from zope.interface import implements
+from ZODB.interfaces import ISerialFormat, ISerializer, IDeserializer
+from ZODB.format import register_format
+from ZODB.utils import p64, u64
+from ZODB.POSException import POSError
+from keas.pbstate.state import StateTuple
+
+from keas.pbpersist.persistent_pb2 import ClassMetadata
+from keas.pbpersist.persistent_pb2 import ObjectRecord
+from keas.pbpersist.persistent_pb2 import Reference
+
+format_prefix = "{%s}" % StateTuple.serial_format
+
+def decode_record(data):
+ """Deserialize an ObjectRecord.
+
+ The serialized data must start with the serialization format prefix.
+ """
+ if not data.startswith(format_prefix):
+ raise POSError("Not a protobuf record: %s" % repr(data))
+ res = ObjectRecord()
+ res.MergeFromString(data[len(format_prefix):])
+ return res
+
+def read_class_meta(class_meta):
+ """Return a ZODB formatted tuple given a ClassMetadata.
+
+ This uses class metadata format #3 described by the
+ ZODB.serialize docstring.
+ """
+ return (class_meta.module_name, class_meta.class_name), None
+
+def write_class_meta(class_meta, source):
+ """Set attributes of a ClassMetadata from a source class metadata object.
+
+ The source is in any of the formats described by the
+ ZODB.serialize docstring.
+ """
+ if not isinstance(source, tuple):
+ # source is in format #1
+ class_meta.module_name = source.__module__
+ class_meta.class_name = source.__name__
+ else:
+ klass, args = source
+ if args is not None:
+ # source is in format #2, 4, 6, or 7
+ raise POSError(
+ "ProtobufSerializer can not serialize classes "
+ "using __getnewargs__ or __getinitargs__")
+ if isinstance(klass, tuple):
+ # source is in format #3
+ class_meta.module_name, class_meta.class_name = klass
+ else:
+ # source is in format #5
+ class_meta.module_name = klass.__module__
+ class_meta.class_name = klass.__name__
+
+def read_reference(ref):
+ """Return a ZODB formatted reference given a Reference message."""
+ oid = p64(ref.zoid)
+ if ref.weak:
+ return ['w', (oid,)]
+ elif ref.database:
+ if ref.class_meta:
+ cm = read_class_meta(ref.class_meta)
+ return ['m', (ref.database, oid, cm)]
+ else:
+ return ['n', (ref.database, oid)]
+ elif ref.class_meta:
+ cm = read_class_meta(ref.class_meta)
+ return (oid, cm)
+ else:
+ return oid
+
+
+class ProtobufFormat(object):
+ implements(ISerialFormat)
+
+ def makeSerializer(self, persistent_id):
+ return ProtobufSerializer(persistent_id)
+
+ def makeDeserializer(self, persistent_load, find_global=None):
+ return ProtobufDeserializer(persistent_load, find_global)
+
+ def listPersistentReferences(self, data):
+ record = decode_record(data)
+ return (read_reference(ref) for ref in record.references)
+
+
+class ProtobufSerializer(object):
+ implements(ISerializer)
+
+ def __init__(self, persistent_id):
+ self.persistent_id = persistent_id
+
+ def dump(self, classmeta, state):
+ """Serialize a persistent object as an ObjectRecord message."""
+ record = ObjectRecord()
+ write_class_meta(record.class_meta, classmeta)
+ record.state, refs = state
+
+ for refid, target in refs.iteritems():
+ p = self.persistent_id(target)
+ if p is None:
+ # All references must point to Persistent objects because
+ # the serialization format requires references to have an OID
+ # and only Persistent objects have an OID.
+ raise POSError(
+ "Protobuf reference target is not a Persistent object: %s"
+ % repr(target))
+ self.add_reference(record, refid, p)
+
+ return '%s%s' % (format_prefix, record.SerializeToString())
+
+ def add_reference(self, record, refid, p):
+ """Add a reference to an ObjectRecord.
+
+ p is a reference, created by the persistent_id() function,
+ in one of the formats documented by ZODB.serialize.
+ """
+ r = record.references.add()
+ r.refid = refid
+ oid = None
+ cm = None
+ if isinstance(p, tuple):
+ oid, cm = p
+ elif isinstance(p, str):
+ oid = p
+ elif len(p) == 1:
+ # old weakref format: [oid]
+ (oid,) = p
+ r.weak = True
+ else:
+ ref_type, args = p
+ if ref_type == 'm':
+ r.database, oid, cm = args
+ elif ref_type == 'w':
+ (oid,) = args
+ r.weak = True
+ elif ref_type == 'n':
+ r.database, oid = args
+ else:
+ raise POSError("Unknown reference type: %s" % repr(ref_type))
+ r.zoid = u64(oid)
+ if cm is not None:
+ write_class_meta(r.class_meta, cm)
+
+
+class ProtobufDeserializer(object):
+ implements(IDeserializer)
+
+ def __init__(self, persistent_load, find_global=None):
+ self.persistent_load = persistent_load
+ self.find_global = find_global
+
+ def getClassAndState(self, data):
+ record = decode_record(data)
+ yield read_class_meta(record.class_meta)
+ ref_dict = {}
+ for ref in record.references:
+ zodb_ref = read_reference(ref)
+ target = self.persistent_load(zodb_ref)
+ ref_dict[ref.refid] = target
+ yield record.state, ref_dict
+
+ def getClassMetadata(self, data):
+ return self.getClassAndState(data).next()
+
+ def getState(self, data):
+ i = self.getClassAndState(data)
+ i.next()
+ return i.next()
+
+
+def register():
+ register_format(StateTuple.serial_format, ProtobufFormat())
Added: keas.pbpersist/trunk/src/keas/pbpersist/persistent.proto
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/persistent.proto (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/persistent.proto 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,23 @@
+// This structure is derived from the documentation in the
+// ZODB.serialize module, although this version restricts the structure of
+// class metadata.
+
+message ClassMetadata {
+ required string module_name = 1;
+ required string class_name = 2;
+}
+
+message Reference {
+ required uint32 refid = 1; // Identity within the persistent object record
+ required uint64 zoid = 2; // ZODB OID as an integer
+ optional ClassMetadata class_meta = 3; // Optimization for loading ghosts
+ optional string database = 4; // for inter-database references
+ optional bool weak = 5; // True for weak references
+ // note that weak references ignore class_meta and database.
+}
+
+message ObjectRecord {
+ required ClassMetadata class_meta = 1;
+ required bytes state = 2;
+ repeated Reference references = 3;
+}
Added: keas.pbpersist/trunk/src/keas/pbpersist/persistent_pb2.py
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/persistent_pb2.py (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/persistent_pb2.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,143 @@
+#!/usr/bin/python2.4
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+from google.protobuf import service
+from google.protobuf import service_reflection
+from google.protobuf import descriptor_pb2
+
+
+
+_CLASSMETADATA = descriptor.Descriptor(
+ name='ClassMetadata',
+ full_name='ClassMetadata',
+ filename='persistent.proto',
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='module_name', full_name='ClassMetadata.module_name', index=0,
+ number=1, type=9, cpp_type=9, label=2,
+ default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='class_name', full_name='ClassMetadata.class_name', index=1,
+ number=2, type=9, cpp_type=9, label=2,
+ default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[], # TODO(robinson): Implement.
+ enum_types=[
+ ],
+ options=None)
+
+
+_REFERENCE = descriptor.Descriptor(
+ name='Reference',
+ full_name='Reference',
+ filename='persistent.proto',
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='refid', full_name='Reference.refid', index=0,
+ number=1, type=13, cpp_type=3, label=2,
+ default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='zoid', full_name='Reference.zoid', index=1,
+ number=2, type=4, cpp_type=4, label=2,
+ default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='class_meta', full_name='Reference.class_meta', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='database', full_name='Reference.database', index=3,
+ number=4, type=9, cpp_type=9, label=1,
+ default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='weak', full_name='Reference.weak', index=4,
+ number=5, type=8, cpp_type=7, label=1,
+ default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[], # TODO(robinson): Implement.
+ enum_types=[
+ ],
+ options=None)
+
+
+_OBJECTRECORD = descriptor.Descriptor(
+ name='ObjectRecord',
+ full_name='ObjectRecord',
+ filename='persistent.proto',
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='class_meta', full_name='ObjectRecord.class_meta', index=0,
+ number=1, type=11, cpp_type=10, label=2,
+ default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='state', full_name='ObjectRecord.state', index=1,
+ number=2, type=12, cpp_type=9, label=2,
+ default_value="",
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='references', full_name='ObjectRecord.references', index=2,
+ number=3, type=11, cpp_type=10, label=3,
+ default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[], # TODO(robinson): Implement.
+ enum_types=[
+ ],
+ options=None)
+
+
+_REFERENCE.fields_by_name['class_meta'].message_type = _CLASSMETADATA
+_OBJECTRECORD.fields_by_name['class_meta'].message_type = _CLASSMETADATA
+_OBJECTRECORD.fields_by_name['references'].message_type = _REFERENCE
+
+class ClassMetadata(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _CLASSMETADATA
+
+class Reference(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _REFERENCE
+
+class ObjectRecord(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _OBJECTRECORD
+
Added: keas.pbpersist/trunk/src/keas/pbpersist/tests.py
===================================================================
--- keas.pbpersist/trunk/src/keas/pbpersist/tests.py (rev 0)
+++ keas.pbpersist/trunk/src/keas/pbpersist/tests.py 2009-01-22 00:48:09 UTC (rev 94914)
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import time
+import unittest
+
+from zope.testing import doctest
+from persistent import Persistent
+from keas.pbstate.meta import ProtobufState
+from keas.pbstate.testclasses_pb2 import ContactPB
+
+
+class PContact(Persistent):
+ __metaclass__ = ProtobufState
+ protobuf_type = ContactPB
+
+ def __init__(self):
+ self.create_time = 1
+
+
+def test_suite():
+ return unittest.TestSuite([
+ doctest.DocFileSuite(
+ 'README.txt',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+ ])
+
+if __name__ == '__main__':
+ unittest.main()
More information about the Checkins
mailing list