[Checkins] SVN: zope.fssync/trunk/src/zope/fssync/ Added better
explanation of synchronizer lookup and fixed some overly long lines
Uwe Oestermeier
u.oestermeier at iwm-kmrc.de
Mon Jun 18 04:33:06 EDT 2007
Log message for revision 76752:
Added better explanation of synchronizer lookup and fixed some overly long lines
Changed:
U zope.fssync/trunk/src/zope/fssync/README.txt
U zope.fssync/trunk/src/zope/fssync/tests/test_docs.py
-=-
Modified: zope.fssync/trunk/src/zope/fssync/README.txt
===================================================================
--- zope.fssync/trunk/src/zope/fssync/README.txt 2007-06-18 06:18:54 UTC (rev 76751)
+++ zope.fssync/trunk/src/zope/fssync/README.txt 2007-06-18 08:33:03 UTC (rev 76752)
@@ -40,13 +40,14 @@
The main components are:
- ISyncTasks like Checkout, Check, and Commit which synchronize
- a content space with a repository. These tasks uses serializers to
- produce serialized data for a repository in an application
+ a content space with a repository. These tasks uses serializers
+ to produce serialized data for a repository in an application
specific format. They use deserializers to read the data back.
The default implementation uses xmlpickle for python objects,
- data streams for file contents, and special directories for extras
- and metadata. Alternative implementations may be use standard pickle,
- a human readable format like RDFa, or application specific formats.
+ data streams for file contents, and special directories for
+ extras and metadata. Alternative implementations may use
+ standard pickles, a human readable format like RDFa, or
+ application specific formats.
- ISynchronizer: Synchronizers produce serialized pieces of a
Python object (the ISerializer part of a synchronizer) and
@@ -129,7 +130,16 @@
>>> snarf = repository.SnarfRepository(StringIO())
>>> checkout = task.Checkout(synchronizer.getSynchronizer, snarf)
+Snarf is a Zope3 specific archive format where the key
+need is for simple software. The format is dead simple: each file
+is represented by the string
+ '<size> <pathname>\n'
+
+followed by exactly <size> bytes. Directories are not represented
+explicitly.
+
+
Entry Ids
=========
@@ -152,27 +162,37 @@
Synchronizer
============
-In the use case of data export / import it is crucial that fssync is able
-to serialize "all" object data. Note that it isn't always obvious what data is
-intrinsic to an object. Therefore we must provide special serialization /
-de-serialization tools which take care of writing and reading "all"
-data. An obvious solution would be to use inheriting synchronization
+In the use case of data export / import it is crucial that fssync is
+able to serialize "all" object data. Note that it isn't always obvious
+what data is intrinsic to an object. Therefore we must provide
+special serialization / de-serialization tools which take care of
+writing and reading "all" data.
+
+An obvious solution would be to use inheriting synchronization
adapters. But this solution bears a risk. If someone created a subclass
and forgot to create an adapter, then their data would be serialized
-incompletely.
+incompletely. To give an example: What happens if someone has a
+serialization adapter for class Person which serializes every aspect of
+Person instances and defines a subclass Employee(Person) later on?
+If the Employee class has some extra aspects (for example additional
+attributes like insurance id, wage, etc.) these would never be serialized
+as long as there is no special serialization adapter for Employees
+which handles this extra aspects. The behavior is different if the
+adapters are looked up by their dotted class name (i.e. the most specific
+class) and not their class or interface (which might led to adapters
+written for super classes). If no specific adapter exists a default
+serializer (e.g a xmlpickler) can serialize the object completely. So
+even if you forget to provide special serializers for all your classes
+you can be sure that your data are complete.
-A better solution is to provide class based adapters for special object
-types and a default serializer which tries to capture the forgotten
-serialization specifications of subclasses. We register the adapter classes
-as named ISynchronizerFactory utilities and use the dotted name
-of the class as lookup key.
+Since the component architecture doesn't support class-based adapters we
+register the adapter classes as named ISynchronizerFactory utilities and
+use the dotted name of the class as lookup key. The default synchronizer
+is registered as a unnamed ISynchronizerFactory utility. This synchronizer
+ensures that all data are pickled to the target repository.
-The default synchronizer is registered as a unnamed ISynchronizerFactory
-utility. This synchronizer ensures that all data are pickled to the
-target repository.
-
>>> component.provideUtility(synchronizer.DefaultSynchronizer,
- ... provides=interfaces.ISynchronizerFactory)
+ ... provides=interfaces.ISynchronizerFactory)
All special synchronizers are registered for a specific content class and
not an abstract interface. The class is represented by the dotted class
@@ -610,8 +630,8 @@
</pickle>
<BLANKLINE>
-If we provide a directory serializer for annotations and extras we get a a file for
-each extra attribute and annotation namespace.
+If we provide a directory serializer for annotations and extras we get a
+file for each extra attribute and annotation namespace.
>>> component.provideUtility(
... synchronizer.DirectorySynchronizer,
@@ -621,7 +641,8 @@
>>> component.provideUtility(
... synchronizer.DirectorySynchronizer,
... interfaces.ISynchronizerFactory,
- ... name=synchronizer.dottedname(synchronizer.SynchronizableAnnotations))
+ ... name=synchronizer.dottedname(
+ ... synchronizer.SynchronizableAnnotations))
Since the annotations are already handled by the Synchronizer base class
we only need to specify the extra attribute here:
@@ -635,8 +656,8 @@
... def load(self, readable):
... self.context.data = readable.read()
>>> component.provideUtility(SampleFileSynchronizer,
- ... interfaces.ISynchronizerFactory,
- ... name=synchronizer.dottedname(AnnotatableSample))
+ ... interfaces.ISynchronizerFactory,
+ ... name=synchronizer.dottedname(AnnotatableSample))
>>> interface.directlyProvides(sample, IMarkerInterface)
>>> root['test'] = sample
@@ -668,47 +689,7 @@
</klass>
<attributes>
<attribute name="__annotations__">
- <initialized_object>
- <klass>
- <global id="o0" name="__newobj__" module="copy_reg"/>
- </klass>
- <arguments>
- <tuple>
- <global name="OOBTree" module="BTrees.OOBTree"/>
- </tuple>
- </arguments>
- <state>
- <tuple>
- <tuple>
- <tuple>
- <tuple>
- <string>zope.fssync.doctest.TestAnnotations</string>
- <initialized_object>
- <klass> <reference id="o0"/> </klass>
- <arguments>
- <tuple>
- <global name="TestAnnotations" module="zope.fssync.doctest"/>
- </tuple>
- </arguments>
- <state>
- <dictionary>
- <item>
- <key> <string>a</string> </key>
- <value> <string>annotation a</string> </value>
- </item>
- <item>
- <key> <string>b</string> </key>
- <value> <none/> </value>
- </item>
- </dictionary>
- </state>
- </initialized_object>
- </tuple>
- </tuple>
- </tuple>
- </tuple>
- </state>
- </initialized_object>
+ ...
</attribute>
<attribute name="extra">
<string>extra</string>
@@ -788,7 +769,8 @@
test/test
The number of files can be reduced if we provide the default synchronizer
-which uses a single file for all annotations and a single file for all extras:
+which uses a single file for all annotations and a single file for
+all extras:
>>> component.provideUtility(
... synchronizer.DefaultSynchronizer,
@@ -798,7 +780,8 @@
>>> component.provideUtility(
... synchronizer.DefaultSynchronizer,
... interfaces.ISynchronizerFactory,
- ... name=synchronizer.dottedname(synchronizer.SynchronizableAnnotations))
+ ... name=synchronizer.dottedname(
+ ... synchronizer.SynchronizableAnnotations))
>>> root['test'] = sample
>>> snarf = repository.SnarfRepository(StringIO())
Modified: zope.fssync/trunk/src/zope/fssync/tests/test_docs.py
===================================================================
--- zope.fssync/trunk/src/zope/fssync/tests/test_docs.py 2007-06-18 06:18:54 UTC (rev 76751)
+++ zope.fssync/trunk/src/zope/fssync/tests/test_docs.py 2007-06-18 08:33:03 UTC (rev 76752)
@@ -83,12 +83,16 @@
globs=globs,
setUp=setUp, tearDown=tearDown,
optionflags=flags))
-
+
suite.addTest(doctest.DocFileSuite('../caseinsensitivity.txt',
globs=globs,
setUp=setUp, tearDown=tearDown,
optionflags=flags))
-
+
+ suite.addTest(doctest.DocFileSuite('../generic.txt',
+ globs=globs,
+ setUp=setUp, tearDown=tearDown,
+ optionflags=flags))
return suite
if __name__ == '__main__':
More information about the Checkins
mailing list