File: advanced.html

package info (click to toggle)
mozilla-firefox 1.0.4-2sarge17
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 255,356 kB
  • ctags: 267,207
  • sloc: cpp: 1,623,961; ansic: 792,828; xml: 85,380; makefile: 41,934; perl: 27,802; asm: 14,884; sh: 14,807; cs: 4,507; python: 4,398; java: 4,004; yacc: 1,380; lex: 409; pascal: 354; php: 244; csh: 132; objc: 73; ada: 44; sql: 4
file content (144 lines) | stat: -rw-r--r-- 7,907 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<html>
<!-- Copyright (c) 2000-2001 ActiveState Tool Corporation.
     See the file LICENSE.txt for licensing information. -->


<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Python XPCOM Advanced Topics</title>
</head>

<body>

<h1>Python XPCOM Advanced Topics</h1>

<p>This document contains a series of tidbits that don't fit
anywhere else. As the Python XPCOM Package documentation matures, most of
these topics will have another home.</p>

<h2>XPCOM Services</h2>
<p>An XPCOM service is simply a singleton registered by name.&nbsp; Python has
full support for both using and implementing XPCOM services.&nbsp; To use a
service, use <i>xpcom.components.services</i> just like the JavaScript
counterpart.&nbsp; There is nothing special about implementing a service in
Python; see the standard XPCOM documentation on services for more information.</p>

<h2>nsIVariant</h2>

<p>There is (almost) full support for <i>nsIVariant</i>.&nbsp; Any <i>nsIVariant</i>
parameters will automatically be translated to and from regular Python objects
giving, in effect, a multi-type parameter.&nbsp; This should be automatic, so
there is not much else to say!&nbsp; Note that if you really want, you can
create and pass your own <i>nsIVariant</i> object instead of a regular Python
object, thereby allowing explicit control over the type of variant created.</p>

<h2>nsISupports Primitives.</h2>

<p>There is a set of interfaces described in <i>nsISupportsPrimitives.idl</i>, which I
term collectively the <i>nsISupports Primitives Interfaces</i>.&nbsp; These
are a set of interfaces a component can support to allow automatic conversion to
and from many basic types.&nbsp; For example, an interface can define that it
supports the <i>nsISupportsCString</i> interface, and this could be used by any
program that wishes to get a string representation of the object.&nbsp; If an
interface wishes to expose itself as a &quot;boolean value&quot;, it may choose
to support the <i>nsISupportsPRBool</i> interface.</p>
<p>When you call an XPCOM object (i.e., you have an XPCOM interface you are
calling), you can use
the builtin functions <i>str()</i>, <i>int()</i>, <i>long()</i> etc., on the
object<i>.</i>&nbsp; In the
case of <i>str()</i>, if the object does not support the <i>nsISupportsCString</i>
or <i>nsISupportsString</i> interfaces, the default string <i>str()</i> for the
object will be returned (i.e., what is normally returned for most XPCOM objects -
support for these interface is not very common!).&nbsp; In the case of the numeric functions, a <i>ValueError</i>
exception will be raised if the objects do not support any interface that can be
used for the conversion.&nbsp;<i>ValueError</i> is used instead of <i>TypeError</i>,
as the type itself (i.e., an XPCOM object) can sometimes be used in this context -
hence it is the specific <i>value</i> of the object that is the problem.</p>
<p>The use of <i>repr()</i> on an XPCOM interface object prevents support
attempts for these interfaces, and allows you to see the
&quot;real&quot; object, rather than what the object wants you to see!</p>
<p>When you implement an XPCOM object, you have two choices for implementation
of these interfaces:</p>
<ul>
  <li>You can explicitly handle these interfaces like any other interface.&nbsp;
    In this case, you have full control.&nbsp; However, if you
    implement only one of these standard interfaces, then you are only
    overriding the default behavior for that specific interface - all other
    interfaces not explicitly listed in your class will still get the behavior
    described below.<br>
  </li>
  <li>If your class does not define support for these interfaces, the framework
    will use standard Python class semantics to implement them - i.e., if your
    class provides a <i>__str__</i> method, it will be used to implement <i>nsISupportsCString</i>
    and <i>nsISupportsString</i>, if you provide <i>__int__</i>, <i>__long__</i>,
    <i>__float__</i> etc., methods, they will be used to implement the numeric
    interfaces.&nbsp; If your class defines no such special methods, then the <i>
    QueryInterface()</i> for those interfaces fails (rather than the QI succeeding
    and the operation to fetch the data failing).</li>
</ul>
<blockquote>
<p>This allows for an interesting feature that would not normally be
possible.&nbsp; Consider Python code that does a <i>str()</i> on an&nbsp; XPCOM
interface, and where the XPCOM interface itself is implemented in Python and
provides a <i>__str__</i> method.&nbsp; The <i>str()</i> on the original
interface queries for the <i>nsISupportsCString</i> interface.&nbsp; The
Python implemented object responds to this interface and delegates to the <i>__str__</i>
method. At the end of all this, <i>str()</i> returns the same result
as if the objects were native Python objects with no XPCOM layer in between.</p>

</blockquote>

<h2>Enumerators</h2>

<p>The primary enumerator used by XPCOM is <i>nsISimpleEnumerator</i>.
Although the Python XPCOM package has full support for <i>nsIEnumerator</i>,
since this interface is not &quot;scriptable&quot;, you should avoided using it in interfaces
you design.</p>

<p>When you use <i>nsISimpleEnumerator</i> from Python, the following enhancements
are available:</p>
<ul>
  <li>The <i>GetNext()</i> method takes an optional IID as a parameter. If
    this is specified, the returned object will be of this interface.&nbsp; This
    prevents the manual <i>QueryInterface()</i> generally required from other
    languages.</li>
  <li>There is a <i>FetchBlock(num, [iid])</i> method, which fetches the
    specified number of elements in one operation and returns a Python
    list. This can be useful for large enumerator sets, so the loop
    iterating the elements runs at full C++ speed.</li>
</ul>
<p><i>nsIEnumerator</i> has similar enhancements.</p>
<p>When implementing a Python XPCOM object, the Python class <i>xpcom.server.enumerator.SimpleEnumerator()</i>
can be used.&nbsp; You can pass a standard Python sequence (list, etc), and it
will be correctly wrapped in an <i>nsISimpleEnumerator</i> interface.</p>
<h2>Files</h2>
<p>The Python XPCOM package provides an <i> xpcom.file</i> module.&nbsp; This implements
a Python-like file object on top of the XPCOM/Mozilla stream interfaces.&nbsp;
When run from within the Mozilla environment, this allows you to open almost any
URL supported by Mozilla (including &quot;chrome://&quot; etc.,).</p>
<p>See this module for more information, including test code.</p>
<h2>XPCOM Object Identity</h2>
<p>XPCOM has defined rules for object identity and for how objects must behave
in their <i> QueryInterface()</i> implementations.&nbsp; The Python XPCOM framework
manages this for you; your code can return new Python instances etc., when
responding to new interfaces, and the framework itself will ensure the XPCOM
semantics are followed.&nbsp; Critically, the framework provides no mechanism
for breaking these rules.</p>
<h2>Policies</h2>
<p>The Python XPCOM framework has the concept of &quot;policies&quot; that
define how XPCOM semantics are mapped to Python objects.&nbsp; It is the policy
that implements delegation of <i> QueryInterface()</i>, translates property
references into direct property references, and failing that, &quot;get_name&quot;
and &quot;set_name&quot; calls, decides how to handle exceptions in the
component, and so on.</p>
<p>The default policy is very flexible and suitable for most purposes.
Indeed, the Komodo project has never had to implement a custom policy.
However, you should be aware the feature exists should you wish to do some
bizarre things, such as using Python as a bridge between XPCOM and some other
component technology.</p>

</body>

</html>