Changeset 65:260fd72bdbb8

Show
Ignore:
Timestamp:
11/17/06 01:29:49 (2 years ago)
Author:
warner@lothar.com
branch:
default
Message:

[foolscap @ add more Copyable documentation]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • .darcs-boringfile

    r3 r65  
    3636 
    3737^_trial_temp($|/) 
     38^doc/.*\.html$ 
    3839 
  • ChangeLog

    r64 r65  
    112006-11-17  Brian Warner  <warner@lothar.com> 
     2 
     3        * doc/using-pb.xhtml: move and expand the section on Copyable and 
     4        other pass-by-copy things into a new file 
     5        * doc/copyable.xhtml: new document. Thanks to Ricky Iacovou for 
     6        the registerCopier examples. 
     7        * doc/listings/copyable-{receive|send}.py: new examples 
     8        * doc/stylesheet.css, doc/stylesheet-unprocessed.css 
     9        * doc/template.tpl: docs utilities 
     10        * Makefile: add 'make docs' target 
    211 
    312        * foolscap/__init__.py: export registerCopier and 
  • Makefile

    r54 r65  
    2525        chmod a+x debian/rules 
    2626        debuild -uc -us 
     27 
     28DOC_TEMPLATE=doc/template.tpl 
     29docs: 
     30        lore -p --config template=$(DOC_TEMPLATE) --config ext=.html \ 
     31        `find doc -name '*.xhtml'` 
  • doc/using-pb.xhtml

    r36 r65  
    787787</pre> 
    788788 
    789  
    790 <h2>Copyable</h2><a name="copyable" /> 
    791  
    792 <p>Subclasses of <code class="API" base="foolscap">pb.Copyable</code> are 
    793 serialized using copy-by-value semantics. Each such object is serialized as a 
    794 (type, state) pair of values. To use it, you can override <code class="API" 
    795 base="foolscap.copyable.ICopyable">getTypeToCopy</code> and <code 
    796 class="API" base="foolscap.copyable.ICopyable">getStateToCopy</code> to 
    797 provide this pair. The default implementations return the object's 
    798 fully-qualified class name, and <code>self.__dict__</code>, respectively. You 
    799 will want to override <code>getStateToCopy</code> in particular if there is 
    800 any portion of the object's state that should <b>not</b> be sent over the 
    801 wire: references to objects that can not or should not be serialized, or 
    802 things that are private to the application. It is common practice to create 
    803 an empty dictionary in this method and then copy items into it.</p> 
    804  
    805 <p>If you want to avoid subclassing (or wish to serialize instances of 
    806 third-party classes that are out of your control), you can also register an 
    807 <code class="API" base="foolscap.copyable">ICopyable</code> adapter to 
    808 provide these methods for those instances.</p> 
    809  
    810 <p>The receiving end needs a way to convert this (type, state) pair back into 
    811 an instance of some sort. The normal way of doing this is to create a <code 
    812 class="API" base="foolscap">pb.RemoteCopy</code> subclass. On your 
    813 subclass, you will need to set the <code>copytype</code> attribute to the 
    814 string returned by <code>getTypeToCopy</code>, and you will override the 
    815 <code class="API" base="foolscap.pb.RemoteCopy">setCopyableState</code> 
    816 method to accept and use the state dictionary returned by 
    817 <code>getStateToCopy</code>. There is a registry that maps the <q>type</q> 
    818 values into the matching <code>RemoteCopy</code> subclass: defining a 
    819 <code>pb.RemoteCopy</code> subclass uses metaclass magic to auto-register 
    820 your new class for you. You can also register the mapping separately, by 
    821 calling <code class="API" base="foolscap">pb.registerRemoteCopy</code>.</p> 
    822  
    823 <p>Copyable instances are copy-by-value instead of copy-by-reference, which 
    824 means that their remote representation does not retain any reference to the 
    825 original object. Sending the same Copyable twice will result in two 
    826 independent copies. Sending a RemoteCopy back to the broker it came from will 
    827 generally fail, unless your RemoteCopy subclass also inherits from 
    828 <code>Copyable</code>. If you want an object which is copied by value the 
    829 first time it traverses the wire, and then copied by reference all later 
    830 times, you will need to write a Slicer/Unslicer pair to implement this 
    831 functionality. Likewise the oldpb <code>Cacheable</code> class would need to 
    832 be implemented with a custom Slicer/Unslicer pair.</p> 
    833  
    834 <p>TODO: example</p> 
     789<h2>Pass-By-Copy</h2> 
     790 
     791<p>You can pass (nearly) arbitrary instances over the wire. Foolscap knows 
     792how to serialize all of Python's native data types already: numbers, strings, 
     793unicode strings, booleans, lists, tuples, dictionaries, sets, and the None 
     794object. You can teach it how to serialize instances of other types too. 
     795Foolscap will not serialize (or deserialize) any class that you haven't 
     796taught it about, both for security and because it refuses the temptation to 
     797guess your intentions about how these unknown classes ought to be 
     798serialized.</p> 
     799 
     800<p>The simplest possible way to pass things by copy is demonstrated in the 
     801following code fragment:</p> 
     802 
     803<pre class="python"> 
     804from foolscap import Copyable, RemoteCopy 
     805 
     806class MyPassByCopy(Copyable, RemoteCopy): 
     807    typeToCopy = copytype = "MyPassByCopy" 
     808    def __init__(self): 
     809        # RemoteCopy subclasses may not accept any __init__ arguments 
     810        pass 
     811    def setCopyableState(self, state): 
     812        self.__dict__ = state 
     813</pre> 
     814 
     815<p>If the code on both sides of the wire import this class, then any 
     816instances of <code>MyPassByCopy</code> that are present in the arguments of a 
     817remote method call (or returned as the result of a remote method call) will 
     818be serialized and reconstituted into an equivalent instance on the other 
     819side.</p> 
     820 
     821<p>For more complicated things to do with pass-by-copy, see the documentation 
     822on <a href="copyable.html">Copyable</a>. This explains the difference between 
     823<code>Copyable</code> and <code>RemoteCopy</code>, how to control the 
     824serialization and deserialization process, and how to arrange for 
     825serialization of third-party classes that are not subclasses of 
     826<code>Copyable</code>.</p> 
    835827 
    836828