Compound Code
Brought to you by:
cpavlina
File | Date | Author | Commit |
---|---|---|---|
Compound | 2010-10-21 |
![]() |
[759234] Prepare 1.1 stable release |
CompoundChild | 2010-05-19 |
![]() |
[d160bd] Added Windows compatibility. |
CompoundCommon | 2010-10-21 |
![]() |
[759234] Prepare 1.1 stable release |
distutils | 2010-05-30 |
![]() |
[50d524] 1.0 release (stable) |
.hgignore | 2010-05-19 |
![]() |
[83b921] Created repository |
COPYING | 2010-05-19 |
![]() |
[a05bd1] Alpha 0.1 |
ChangeLog | 2010-10-21 |
![]() |
[759234] Prepare 1.1 stable release |
Makefile | 2010-05-19 |
![]() |
[a05bd1] Alpha 0.1 |
README.html | 2010-10-21 |
![]() |
[759234] Prepare 1.1 stable release |
TODO | 2010-10-21 |
![]() |
[759234] Prepare 1.1 stable release |
install.bat | 2010-05-19 |
![]() |
[45ad4a] Finished Windows compatibility. |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Compound 1.1</title> <style type="text/css"> a { color: blue; } pre.code { background-color: #bbb; border-left: 1px solid black; padding-left: .5em; } div.ref { padding-left: 1em; margin-bottom: .2in; } </style> </head> <body> <h1>Compound 1.1</h1> <a name="intro"></a> <p>Compound is a library that allows the use of Python 2 modules from within Python 3. It is compatible with Linux and NT-based Windows, and possibly Mac OS X. Python 2.6 is required, and Python 3.1 is recommended. </p> <h2>Table of Contents</h2> <ol> <li><a href="#intro">Introduction</a></li> <li><a href="#install">Installation</a></li> <li><a href="#bytes">About <tt>bytes</tt></a></li> <li><a href="#ref">Library reference</a> <ol> <li><a href="#r_start"><tt>start ()</tt></a></li> <li><a href="#r_register"><tt>register ()</tt></a></li> <li><a href="#r_load"><tt>load (name)</tt></a></li> <li><a href="#r_isinstance"><tt>isinstance (obj, cls)</tt></a></li> <li><a href="#r_byteswrapper"><tt>BytesWrapper (fxn, <i>(argindices, ...)</i>)</tt></a></li> <li><a href="#r_debug"><tt>debug (level)</tt></a></li> <li><a href="#r_listen_tb"><tt>listen_tb ()</tt></a></li> <li><a href="#r_EW"><tt>class ExceptionWrapper</tt></a></li> <li><a href="#r_P"><tt>class Proxy</tt></a></li> <li><a href="#r_CE"><tt>class CompoundError</tt></a></li> </ol> </li> <li><a href="#examples">Examples</a> <ol> <li><a href="#e_basic">Basic version check</a></li> <li><a href="#e_gtk">Gtk+ Hello World</a></li> <li><a href="#e_gtk_r">Gtk+ Hello World, with import hook</a></li> </ol> </li> <li><a href="#hacking">Hacking</a></li> <li><a href="#license">License</a></li> </ol> <hr /> <a name="install"></a> <h2>Installation</h2> <p>On Linux or other Unix-like systems, Compound can be installed in the usual way. There is no need to build it (it is pure Python). </p> <pre class="code"># make install</pre> <p>On Windows, Compound can be installed by running <tt>install.bat</tt>. </p> <p>It is also possible to run Compound directly without installing it, by simply starting Python within the source directory.</p> <hr /> <a name="bytes"></a> <h2>About <tt>bytes</tt></h2> <p>Compound 1.1 supports <tt>bytes</tt>. When a Python 2 function returns a non-Unicode string containing character codes in the upper half, the whole string will automatically be returned as a <tt>bytes</tt>. If you want a certain function to always receive <tt>bytes</tt>, see <a href="#r_byteswrapper"><tt>BytesWrapper</tt></a>. </p> <hr /> <a name="ref"></a> <h2>Library reference</h2> <a name="r_start"></a> <tt>Compound.<b>start</b> ()</tt> <div class="ref"> Starts Compound. Either <tt>start()</tt> or <a href="#r_register"><tt>register()</tt></a> must be run before anything else. Note that it is safe to call <tt>start()</tt> multiple times. </div> <a name="r_register"></a> <tt>Compound.<b>register</b> ()</tt> <div class="ref"> Starts Compound and registers it with Python's import mechanism. See the <a href="#examples">Examples section</a> to see how this works. </div> <a name="r_load"></a> <tt>Compound.<b>load</b> (name)</tt> <div class="ref"> Loads the Python 2 module given by <tt>name</tt> and returns it. If no such module exists, an <tt>ImportError</tt> will be raised. </div> <a name="r_isinstance"></a> <tt>Compound.<b>isinstance</b> (obj, cls)</tt> <div class="ref"> Returns whether <tt>obj</tt> is an instance of <tt>cls</tt>. Works for all objects, including Compound proxy objects and native Python 3 objects. It is safe to always use this, with a simple assignment: <pre class="code">isinstance = Compound.isinstance</pre> </div> <a name="r_byteswrapper"></a> <tt>Compound.<b>BytesWrapper</b> (fxn, <i>(argindices, ...)</i>)</tt> <div class="ref"> Wraps a function that must always take a <tt>bytes</tt> (for example, <tt>f.write</tt> on a file opened <tt>"wb"</tt>). The second argument is a tuple of argument indices which will be converted, and if not given, is assumed to be all. For example, if you wrap <tt>test</tt> as <tt>BytesWrapper(test, (0,2))</tt>, then if you call <tt>test("a", "b", "c")</tt>, it will be called <tt>test(b"a", "b", b"c")</tt>. The example is: <pre class="code">f = open (filename, "wb") f.write = Compound.BytesWrapper (f.write, (0,)) <i>Pass f to some Python 2 code that puts bytes into it</i> f.close ()</pre> </div> <a name="r_debug"></a> <tt>Compound.<b>debug</b> (level)</tt> <div class="ref"> Enables debug messages for the given level and all lower. Messages are given with line numbers and file names. Debug levels are: <ol> <li>Start and stop, module load, invalid commands</li> <li>Commands passed</li> <li>Proxy instances and subclasses created</li> <li><i>Unused</i></li> <li>All socket communication</li> <li>All lock acquires and releases</li> </ol> </div> <a name="r_listen_tb"></a> <tt>Compound.<b>listen_tb</b> ()</tt> <div class="ref"> After running this function, both the parent and child process will listen for SIGQUIT, and will output a traceback upon receiving it. This function will print the process ID for both parent and child. Only available on Linux. </div> <a name="r_EW"></a> <tt>class CompoundCommon.<b>ExceptionWrapper</b> (BaseException)</tt> <div class="ref"> All Compound proxies that are raised as exceptions are wrapped in this class. <tt>ExceptionWrapper</tt> serves as a full proxy and should act just like the object itself. </div> <a name="r_P"></a> <tt>class Compound.ser.<b>Proxy</b> (object)</tt> <div class="ref"> All objects other than basic types (<tt>str</tt>, <tt>int</tt>, <tt>bool</tt>, <tt>float</tt>, <tt>complex</tt>, <tt>type(None)</tt>, <tt>tuple</tt>, <tt>list</tt>, <tt>set</tt>, <tt>dict</tt>) are returned as a proxy to the actual object. </div> <a name="r_CE"></a> <tt>class CompoundCommon.<b>CompoundError</b> (Exception)</tt> <div class="ref"> All errors returned by Compound other than the standard types (<tt>ImportError</tt>, <tt>AttributeError</tt>, <tt>KeyError</tt>, etc.) derive from this class. Subclasses are: <tt>ChildError</tt>, <tt>ChildNotFound</tt>, <tt>ChildStartError</tt>, <tt>ChildQuitError</tt>, <tt>InternalError</tt>. </div> <hr /> <a name="examples"></a> <h2>Examples</h2> <a name="e_basic"></a> <h3>Basic version check</h3> <pre class="code"><b>>>> import Compound >>> Compound.start () >>> >>> import sys >>> sys2 = Compound.load ('sys') >>> >>> sys.version</b> '3.1.2 (r312:79147, Apr 15 2010, 15:35:48) \n[GCC 4.4.3]' <b>>>> sys2.version</b> '2.6.5 (r265:79063, Apr 16 2010, 13:57:41) \n[GCC 4.4.3]'</pre> <a name="e_gtk"></a> <h3>Gtk+ Hello World</h3> <pre class="code"><b>>>> import Compound >>> Compound.start() >>> gtk = Compound.load ('gtk') >>> >>> class HW (object): ... def hello (self, widget, data=None): ... print ("Hello World") ... def delete_event (self, widget, event, data=None): ... print ("delete event occurred") ... return False ... def destroy (self, widget, data=None): ... gtk.main_quit () ... def __init__ (self): ... self.window = gtk.Window (gtk.WINDOW_TOPLEVEL) ... self.window.connect ("delete_event", self.delete_event) ... self.window.connect ("destroy", self.destroy) ... self.window.set_border_width (10) ... self.button = gtk.Button ("Hello World") ... self.button.connect ("clicked", self.hello, None) ... self.window.add (self.button) ... self.button.show () ... self.window.show () ... def main (self): ... gtk.main () ... >>> hw = HW () >>> hw.main () >>></b>Hello World delete event occurred <b>>>></b> </pre> <a name="e_gtk_r"></a> <h3>Gtk+ Hello World, with import hook</h3> <pre class="code"><b>>>> import Compound >>> Compound.register() >>> import gtk >>> >>> class HW (object): ... def hello (self, widget, data=None): ... print ("Hello World") ... def delete_event (self, widget, event, data=None): ... print ("delete event occurred") ... return False ... def destroy (self, widget, data=None): ... gtk.main_quit () ... def __init__ (self): ... self.window = gtk.Window (gtk.WINDOW_TOPLEVEL) ... self.window.connect ("delete_event", self.delete_event) ... self.window.connect ("destroy", self.destroy) ... self.window.set_border_width (10) ... self.button = gtk.Button ("Hello World") ... self.button.connect ("clicked", self.hello, None) ... self.window.add (self.button) ... self.button.show () ... self.window.show () ... def main (self): ... gtk.main () ... >>> hw = HW () >>> hw.main () >>></b>Hello World delete event occurred <b>>>></b> </pre> <hr /> <a name="hacking"></a> <h2>Hacking</h2> <p>When making changes to files in <tt>CompoundCommon/</tt>, note that the code must be written to run in both Python 2 and Python 3. Hints: </p> <ul> <li><tt>bytes</tt> is present in Python 2.6, and is an alias for <tt>str</tt>.</li> <li>The <tt>b''</tt> notation for <tt>bytes</tt> is also present in 2.6.</li> <li>Remember that <tt>unicode</tt> and <tt>long</tt> do not exist in Python 3. It can be helpful to alias <tt>str</tt> and <tt>int</tt> to them, respectively.</li> <li>Python 3 only supports <tt>print()</tt>. Since extra parentheses never hurt, you can use that notation in Python 2 as well.</li> <li>Don't ever do something specifically for <tt>bytes</tt> without making sure it isn't just an alias for <tt>str</tt>.</li> <li>There is no need to go mucking with the <tt>types</tt> module to get <tt>NoneType</tt>. <tt>type(None)</tt> will do just fine. <li>Compound is meant to be thread-safe. Be careful. If you touch <i>anything</i> around a lock, run Compound, set the debug level to 6, and check the (long!) outputs to make sure you didn't screw anything up. </li> <li><tt><a href="#r_listen_tb">listen_tb()</a> is your friend.</tt></li> </ul> <hr /> <a name="license"></a> <h2>License</h2> <p>Copyright © 2010, Christopher Pavlina.</p> <p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p> <p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p> <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR DEALINGS IN THE SOFTWARE.</p> <hr /> <p style="font-style:italic;">No copyright is claimed on this documentation. Written by <a href="mailto:pavlina.chris@gmail.com">Christopher Pavlina</a>, October 2010.</p> </body> </html>