advanced.html revision 16a8d09569a2ebd598cef72fa605be6fb4563607
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly<!-- ***** BEGIN LICENSE BLOCK *****
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - Version: MPL 1.1/GPL 2.0/LGPL 2.1
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - The contents of this file are subject to the Mozilla Public License Version
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - 1.1 (the "License"); you may not use this file except in compliance with
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - the License. You may obtain a copy of the License at
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - Software distributed under the License is distributed on an "AS IS" basis,
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - for the specific language governing rights and limitations under the
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - The Original Code is PyXPCOM.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - The Initial Developer of the Original Code is
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - ActiveState Tool Corporation.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - Portions created by the Initial Developer are Copyright (C) 2000-2001
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - the Initial Developer. All Rights Reserved.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - Contributor(s):
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - Alternatively, the contents of this file may be used under the terms of
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - either the GNU General Public License Version 2 or later (the "GPL"), or
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - in which case the provisions of the GPL or the LGPL are applicable instead
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith - of those above. If you wish to allow use of your version of this file only
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - under the terms of either the GPL or the LGPL, and not to allow others to
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - use your version of this file under the terms of the MPL, indicate your
819e90d415ed17d59af3a247b2ad9d6feb0c21b5Luke Smith - decision by deleting the provisions above and replace them with the notice
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - and other provisions required by the LGPL or the GPL. If you do not delete
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - the provisions above, a recipient may use your version of this file under
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - the terms of any one of the MPL, the GPL or the LGPL.
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly - ***** END LICENSE BLOCK ***** -->
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<meta name="ProgId" content="FrontPage.Editor.Document">
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly<p>This document contains a series of tidbits that don't fit
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithanywhere else. As the Python XPCOM Package documentation matures, most of
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smiththese topics will have another home.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>An XPCOM service is simply a singleton registered by name. Python has
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithfull support for both using and implementing XPCOM services. To use a
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyservice, use <i>xpcom.components.services</i> just like the JavaScript
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellycounterpart. There is nothing special about implementing a service in
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny DonnellyPython; see the standard XPCOM documentation on services for more information.</p>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly<p>There is (almost) full support for <i>nsIVariant</i>. Any <i>nsIVariant</i>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyparameters will automatically be translated to and from regular Python objects
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellygiving, in effect, a multi-type parameter. This should be automatic, so
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellythere is not much else to say! Note that if you really want, you can
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellycreate and pass your own <i>nsIVariant</i> object instead of a regular Python
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyobject, thereby allowing explicit control over the type of variant created.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>There is a set of interfaces described in <i>nsISupportsPrimitives.idl</i>, which I
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyterm collectively the <i>nsISupports Primitives Interfaces</i>. These
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithare a set of interfaces a component can support to allow automatic conversion to
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithand from many basic types. For example, an interface can define that it
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithsupports the <i>nsISupportsCString</i> interface, and this could be used by any
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithprogram that wishes to get a string representation of the object. If an
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithinterface wishes to expose itself as a "boolean value", it may choose
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithto support the <i>nsISupportsPRBool</i> interface.</p>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly<p>When you call an XPCOM object (i.e., you have an XPCOM interface you are
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellycalling), you can use
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellythe builtin functions <i>str()</i>, <i>int()</i>, <i>long()</i> etc., on the
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellycase of <i>str()</i>, if the object does not support the <i>nsISupportsCString</i>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyor <i>nsISupportsString</i> interfaces, the default string <i>str()</i> for the
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyobject will be returned (i.e., what is normally returned for most XPCOM objects -
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellysupport for these interface is not very common!). In the case of the numeric functions, a <i>ValueError</i>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyexception will be raised if the objects do not support any interface that can be
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithused for the conversion. <i>ValueError</i> is used instead of <i>TypeError</i>,
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithas the type itself (i.e., an XPCOM object) can sometimes be used in this context -
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithhence it is the specific <i>value</i> of the object that is the problem.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>The use of <i>repr()</i> on an XPCOM interface object prevents support
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithattempts for these interfaces, and allows you to see the
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith"real" object, rather than what the object wants you to see!</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>When you implement an XPCOM object, you have two choices for implementation
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithof these interfaces:</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith <li>You can explicitly handle these interfaces like any other interface.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith In this case, you have full control. However, if you
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith implement only one of these standard interfaces, then you are only
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith overriding the default behavior for that specific interface - all other
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith interfaces not explicitly listed in your class will still get the behavior
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith described below.<br>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith <li>If your class does not define support for these interfaces, the framework
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith will use standard Python class semantics to implement them - i.e., if your
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith class provides a <i>__str__</i> method, it will be used to implement <i>nsISupportsCString</i>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith and <i>nsISupportsString</i>, if you provide <i>__int__</i>, <i>__long__</i>,
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith <i>__float__</i> etc., methods, they will be used to implement the numeric
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith interfaces. If your class defines no such special methods, then the <i>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith QueryInterface()</i> for those interfaces fails (rather than the QI succeeding
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith and the operation to fetch the data failing).</li>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>This allows for an interesting feature that would not normally be
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithpossible. Consider Python code that does a <i>str()</i> on an XPCOM
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithinterface, and where the XPCOM interface itself is implemented in Python and
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithprovides a <i>__str__</i> method. The <i>str()</i> on the original
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithinterface queries for the <i>nsISupportsCString</i> interface. The
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke SmithPython implemented object responds to this interface and delegates to the <i>__str__</i>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithmethod. At the end of all this, <i>str()</i> returns the same result
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithas if the objects were native Python objects with no XPCOM layer in between.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith</blockquote>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>The primary enumerator used by XPCOM is <i>nsISimpleEnumerator</i>.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke SmithAlthough the Python XPCOM package has full support for <i>nsIEnumerator</i>,
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithsince this interface is not "scriptable", you should avoided using it in interfaces
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithyou design.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>When you use <i>nsISimpleEnumerator</i> from Python, the following enhancements
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithare available:</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith <li>The <i>GetNext()</i> method takes an optional IID as a parameter. If
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith this is specified, the returned object will be of this interface. This
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith prevents the manual <i>QueryInterface()</i> generally required from other
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith languages.</li>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith <li>There is a <i>FetchBlock(num, [iid])</i> method, which fetches the
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith specified number of elements in one operation and returns a Python
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith list. This can be useful for large enumerator sets, so the loop
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith iterating the elements runs at full C++ speed.</li>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p><i>nsIEnumerator</i> has similar enhancements.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>When implementing a Python XPCOM object, the Python class <i>xpcom.server.enumerator.SimpleEnumerator()</i>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithcan be used. You can pass a standard Python sequence (list, etc), and it
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithwill be correctly wrapped in an <i>nsISimpleEnumerator</i> interface.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>The Python XPCOM package provides an <i> xpcom.file</i> module. This implements
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smitha Python-like file object on top of the XPCOM/Mozilla stream interfaces.
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke SmithWhen run from within the Mozilla environment, this allows you to open almost any
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke SmithURL supported by Mozilla (including "chrome://" etc.,).</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>See this module for more information, including test code.</p>
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnelly<p>XPCOM has defined rules for object identity and for how objects must behave
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyin their <i> QueryInterface()</i> implementations. The Python XPCOM framework
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellymanages this for you; your code can return new Python instances etc., when
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellyresponding to new interfaces, and the framework itself will ensure the XPCOM
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellysemantics are followed. Critically, the framework provides no mechanism
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithfor breaking these rules.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>The Python XPCOM framework has the concept of "policies" that
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithdefine how XPCOM semantics are mapped to Python objects. It is the policy
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smiththat implements delegation of <i> QueryInterface()</i>, translates property
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithreferences into direct property references, and failing that, "get_name"
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithand "set_name" calls, decides how to handle exceptions in the
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithcomponent, and so on.</p>
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smith<p>The default policy is very flexible and suitable for most purposes.
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny DonnellyIndeed, the Komodo project has never had to implement a custom policy.
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny DonnellyHowever, you should be aware the feature exists should you wish to do some
cf6c1ae1ed15095f8dc269bb9d7a373a1b87990eJenny Donnellybizarre things, such as using Python as a bridge between XPCOM and some other
68dfd2985f43ea9d8de9e52fa68ab5274917c045Luke Smithcomponent technology.</p>