1 | <html>
|
---|
2 | <!-- ***** BEGIN LICENSE BLOCK *****
|
---|
3 | - Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
4 | -
|
---|
5 | - The contents of this file are subject to the Mozilla Public License Version
|
---|
6 | - 1.1 (the "License"); you may not use this file except in compliance with
|
---|
7 | - the License. You may obtain a copy of the License at
|
---|
8 | - http://www.mozilla.org/MPL/
|
---|
9 | -
|
---|
10 | - Software distributed under the License is distributed on an "AS IS" basis,
|
---|
11 | - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
12 | - for the specific language governing rights and limitations under the
|
---|
13 | - License.
|
---|
14 | -
|
---|
15 | - The Original Code is PyXPCOM.
|
---|
16 | -
|
---|
17 | - The Initial Developer of the Original Code is
|
---|
18 | - ActiveState Tool Corporation.
|
---|
19 | - Portions created by the Initial Developer are Copyright (C) 2000-2001
|
---|
20 | - the Initial Developer. All Rights Reserved.
|
---|
21 | -
|
---|
22 | - Contributor(s):
|
---|
23 | -
|
---|
24 | - Alternatively, the contents of this file may be used under the terms of
|
---|
25 | - either the GNU General Public License Version 2 or later (the "GPL"), or
|
---|
26 | - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
27 | - in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
28 | - of those above. If you wish to allow use of your version of this file only
|
---|
29 | - under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
30 | - use your version of this file under the terms of the MPL, indicate your
|
---|
31 | - decision by deleting the provisions above and replace them with the notice
|
---|
32 | - and other provisions required by the LGPL or the GPL. If you do not delete
|
---|
33 | - the provisions above, a recipient may use your version of this file under
|
---|
34 | - the terms of any one of the MPL, the GPL or the LGPL.
|
---|
35 | -
|
---|
36 | - ***** END LICENSE BLOCK ***** -->
|
---|
37 |
|
---|
38 | <head>
|
---|
39 | <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
---|
40 | <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
---|
41 | <meta name="ProgId" content="FrontPage.Editor.Document">
|
---|
42 | <title>Python XPCOM Advanced Topics</title>
|
---|
43 | </head>
|
---|
44 |
|
---|
45 | <body>
|
---|
46 |
|
---|
47 | <h1>Python XPCOM Advanced Topics</h1>
|
---|
48 |
|
---|
49 | <p>This document contains a series of tidbits that don't fit
|
---|
50 | anywhere else. As the Python XPCOM Package documentation matures, most of
|
---|
51 | these topics will have another home.</p>
|
---|
52 |
|
---|
53 | <h2>XPCOM Services</h2>
|
---|
54 | <p>An XPCOM service is simply a singleton registered by name. Python has
|
---|
55 | full support for both using and implementing XPCOM services. To use a
|
---|
56 | service, use <i>xpcom.components.services</i> just like the JavaScript
|
---|
57 | counterpart. There is nothing special about implementing a service in
|
---|
58 | Python; see the standard XPCOM documentation on services for more information.</p>
|
---|
59 |
|
---|
60 | <h2>nsIVariant</h2>
|
---|
61 |
|
---|
62 | <p>There is (almost) full support for <i>nsIVariant</i>. Any <i>nsIVariant</i>
|
---|
63 | parameters will automatically be translated to and from regular Python objects
|
---|
64 | giving, in effect, a multi-type parameter. This should be automatic, so
|
---|
65 | there is not much else to say! Note that if you really want, you can
|
---|
66 | create and pass your own <i>nsIVariant</i> object instead of a regular Python
|
---|
67 | object, thereby allowing explicit control over the type of variant created.</p>
|
---|
68 |
|
---|
69 | <h2>nsISupports Primitives.</h2>
|
---|
70 |
|
---|
71 | <p>There is a set of interfaces described in <i>nsISupportsPrimitives.idl</i>, which I
|
---|
72 | term collectively the <i>nsISupports Primitives Interfaces</i>. These
|
---|
73 | are a set of interfaces a component can support to allow automatic conversion to
|
---|
74 | and from many basic types. For example, an interface can define that it
|
---|
75 | supports the <i>nsISupportsCString</i> interface, and this could be used by any
|
---|
76 | program that wishes to get a string representation of the object. If an
|
---|
77 | interface wishes to expose itself as a "boolean value", it may choose
|
---|
78 | to support the <i>nsISupportsPRBool</i> interface.</p>
|
---|
79 | <p>When you call an XPCOM object (i.e., you have an XPCOM interface you are
|
---|
80 | calling), you can use
|
---|
81 | the builtin functions <i>str()</i>, <i>int()</i>, <i>long()</i> etc., on the
|
---|
82 | object<i>.</i> In the
|
---|
83 | case of <i>str()</i>, if the object does not support the <i>nsISupportsCString</i>
|
---|
84 | or <i>nsISupportsString</i> interfaces, the default string <i>str()</i> for the
|
---|
85 | object will be returned (i.e., what is normally returned for most XPCOM objects -
|
---|
86 | support for these interface is not very common!). In the case of the numeric functions, a <i>ValueError</i>
|
---|
87 | exception will be raised if the objects do not support any interface that can be
|
---|
88 | used for the conversion. <i>ValueError</i> is used instead of <i>TypeError</i>,
|
---|
89 | as the type itself (i.e., an XPCOM object) can sometimes be used in this context -
|
---|
90 | hence it is the specific <i>value</i> of the object that is the problem.</p>
|
---|
91 | <p>The use of <i>repr()</i> on an XPCOM interface object prevents support
|
---|
92 | attempts for these interfaces, and allows you to see the
|
---|
93 | "real" object, rather than what the object wants you to see!</p>
|
---|
94 | <p>When you implement an XPCOM object, you have two choices for implementation
|
---|
95 | of these interfaces:</p>
|
---|
96 | <ul>
|
---|
97 | <li>You can explicitly handle these interfaces like any other interface.
|
---|
98 | In this case, you have full control. However, if you
|
---|
99 | implement only one of these standard interfaces, then you are only
|
---|
100 | overriding the default behavior for that specific interface - all other
|
---|
101 | interfaces not explicitly listed in your class will still get the behavior
|
---|
102 | described below.<br>
|
---|
103 | </li>
|
---|
104 | <li>If your class does not define support for these interfaces, the framework
|
---|
105 | will use standard Python class semantics to implement them - i.e., if your
|
---|
106 | class provides a <i>__str__</i> method, it will be used to implement <i>nsISupportsCString</i>
|
---|
107 | and <i>nsISupportsString</i>, if you provide <i>__int__</i>, <i>__long__</i>,
|
---|
108 | <i>__float__</i> etc., methods, they will be used to implement the numeric
|
---|
109 | interfaces. If your class defines no such special methods, then the <i>
|
---|
110 | QueryInterface()</i> for those interfaces fails (rather than the QI succeeding
|
---|
111 | and the operation to fetch the data failing).</li>
|
---|
112 | </ul>
|
---|
113 | <blockquote>
|
---|
114 | <p>This allows for an interesting feature that would not normally be
|
---|
115 | possible. Consider Python code that does a <i>str()</i> on an XPCOM
|
---|
116 | interface, and where the XPCOM interface itself is implemented in Python and
|
---|
117 | provides a <i>__str__</i> method. The <i>str()</i> on the original
|
---|
118 | interface queries for the <i>nsISupportsCString</i> interface. The
|
---|
119 | Python implemented object responds to this interface and delegates to the <i>__str__</i>
|
---|
120 | method. At the end of all this, <i>str()</i> returns the same result
|
---|
121 | as if the objects were native Python objects with no XPCOM layer in between.</p>
|
---|
122 |
|
---|
123 | </blockquote>
|
---|
124 |
|
---|
125 | <h2>Enumerators</h2>
|
---|
126 |
|
---|
127 | <p>The primary enumerator used by XPCOM is <i>nsISimpleEnumerator</i>.
|
---|
128 | Although the Python XPCOM package has full support for <i>nsIEnumerator</i>,
|
---|
129 | since this interface is not "scriptable", you should avoided using it in interfaces
|
---|
130 | you design.</p>
|
---|
131 |
|
---|
132 | <p>When you use <i>nsISimpleEnumerator</i> from Python, the following enhancements
|
---|
133 | are available:</p>
|
---|
134 | <ul>
|
---|
135 | <li>The <i>GetNext()</i> method takes an optional IID as a parameter. If
|
---|
136 | this is specified, the returned object will be of this interface. This
|
---|
137 | prevents the manual <i>QueryInterface()</i> generally required from other
|
---|
138 | languages.</li>
|
---|
139 | <li>There is a <i>FetchBlock(num, [iid])</i> method, which fetches the
|
---|
140 | specified number of elements in one operation and returns a Python
|
---|
141 | list. This can be useful for large enumerator sets, so the loop
|
---|
142 | iterating the elements runs at full C++ speed.</li>
|
---|
143 | </ul>
|
---|
144 | <p><i>nsIEnumerator</i> has similar enhancements.</p>
|
---|
145 | <p>When implementing a Python XPCOM object, the Python class <i>xpcom.server.enumerator.SimpleEnumerator()</i>
|
---|
146 | can be used. You can pass a standard Python sequence (list, etc), and it
|
---|
147 | will be correctly wrapped in an <i>nsISimpleEnumerator</i> interface.</p>
|
---|
148 | <h2>Files</h2>
|
---|
149 | <p>The Python XPCOM package provides an <i> xpcom.file</i> module. This implements
|
---|
150 | a Python-like file object on top of the XPCOM/Mozilla stream interfaces.
|
---|
151 | When run from within the Mozilla environment, this allows you to open almost any
|
---|
152 | URL supported by Mozilla (including "chrome://" etc.,).</p>
|
---|
153 | <p>See this module for more information, including test code.</p>
|
---|
154 | <h2>XPCOM Object Identity</h2>
|
---|
155 | <p>XPCOM has defined rules for object identity and for how objects must behave
|
---|
156 | in their <i> QueryInterface()</i> implementations. The Python XPCOM framework
|
---|
157 | manages this for you; your code can return new Python instances etc., when
|
---|
158 | responding to new interfaces, and the framework itself will ensure the XPCOM
|
---|
159 | semantics are followed. Critically, the framework provides no mechanism
|
---|
160 | for breaking these rules.</p>
|
---|
161 | <h2>Policies</h2>
|
---|
162 | <p>The Python XPCOM framework has the concept of "policies" that
|
---|
163 | define how XPCOM semantics are mapped to Python objects. It is the policy
|
---|
164 | that implements delegation of <i> QueryInterface()</i>, translates property
|
---|
165 | references into direct property references, and failing that, "get_name"
|
---|
166 | and "set_name" calls, decides how to handle exceptions in the
|
---|
167 | component, and so on.</p>
|
---|
168 | <p>The default policy is very flexible and suitable for most purposes.
|
---|
169 | Indeed, the Komodo project has never had to implement a custom policy.
|
---|
170 | However, you should be aware the feature exists should you wish to do some
|
---|
171 | bizarre things, such as using Python as a bridge between XPCOM and some other
|
---|
172 | component technology.</p>
|
---|
173 |
|
---|
174 | </body>
|
---|
175 |
|
---|
176 | </html>
|
---|