First checkin of the Python XPCOM bindings.
git-svn-id: svn://10.0.0.236/trunk@87331 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
135
mozilla/extensions/python/xpcom/doc/advanced.html
Normal file
135
mozilla/extensions/python/xpcom/doc/advanced.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<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. Python has
|
||||
full support for both using and implementing XPCOM services. To use a
|
||||
service, use <i>xpcom.components.services</i> just like the JavaScript
|
||||
counterpart. There is nothing special about implementing a service in
|
||||
Python; see the standard XPCOM documentation on services for more information.</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>. These
|
||||
are a set of interfaces a component can support to allow automatic conversion to
|
||||
and from many basic types. For example, an interface can define that it
|
||||
supports the <i>nsISupportsString</i> interface, and this could be used by any
|
||||
program that wishes to get a string representation of the object. If an
|
||||
interface wishes to expose itself as a "boolean value", 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> In the
|
||||
case of <i>str()</i>, if the object does not support the <i>nsISupportsString</i>
|
||||
or <i>nsISupportsWString</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!). 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. <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
|
||||
"real" 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.
|
||||
In this case, you have full control. 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>nsISupportsString</i>
|
||||
and <i>nsISupportsWString</i>, if you provide <i>__int__</i>, <i>__long__</i>,
|
||||
<i>__float__</i> etc., methods, they will be used to implement the numeric
|
||||
interfaces. 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. Consider Python code that does a <i>str()</i> on an XPCOM
|
||||
interface, and where the XPCOM interface itself is implemented in Python and
|
||||
provides a <i>__str__</i> method. The <i>str()</i> on the original
|
||||
interface queries for the <i>nsISupportsString</i> interface. 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 "scriptable", 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. 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. 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. This implements
|
||||
a Python-like file object on top of the XPCOM/Mozilla stream interfaces.
|
||||
When run from within the Mozilla environment, this allows you to open almost any
|
||||
URL supported by Mozilla (including "chrome://" 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. 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. Critically, the framework provides no mechanism
|
||||
for breaking these rules.</p>
|
||||
<h2>Policies</h2>
|
||||
<p>The Python XPCOM framework has the concept of "policies" that
|
||||
define how XPCOM semantics are mapped to Python objects. It is the policy
|
||||
that implements delegation of <i> QueryInterface()</i>, translates property
|
||||
references into direct property references, and failing that, "get_name"
|
||||
and "set_name" 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>
|
||||
84
mozilla/extensions/python/xpcom/doc/architecture.html
Normal file
84
mozilla/extensions/python/xpcom/doc/architecture.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<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>Architecture</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Python XPCOM Package Architecture</h1>
|
||||
<h2><a name="Architecture">Architecture</a></h2>
|
||||
<p>Much of the design for the Python XPCOM Package has been borrowed from the Python MS-COM
|
||||
extensions in <i>win32com</i>. Most of the major limitations and drawbacks in the <i>win32com</i>
|
||||
design have been addressed, mainly "auto-wrapping" of
|
||||
interface objects, which is not supported by <i>win32com</i>.</p>
|
||||
<p>Like <i>win32com</i>, this architecture includes the concept of <i>client COM</i> and <i>server
|
||||
COM.</i> </p>
|
||||
<p>Client COM:</p>
|
||||
<ul>
|
||||
<li>calls other interfaces</li>
|
||||
<li>is supported by <i>PyInterfaces</i> implemented in C++, which assists
|
||||
in making the COM calls</li>
|
||||
<li>is supported by <i>PyGateways</i>, which assists in receiving
|
||||
external COM calls and dispatching them to the correct Python object</li>
|
||||
<li> is supported in the <i>xpcom/client</i> package</li>
|
||||
</ul>
|
||||
<p>Server COM:</p>
|
||||
<ul>
|
||||
<li>implements interfaces for use by other XPCOM applications or components</li>
|
||||
<li> is
|
||||
supported in the <i>xpcom/server</i> package</li>
|
||||
</ul>
|
||||
<p>The XPConnect framework is very powerful, and far exceeds what COM's <i>
|
||||
IDispatch</i> can offer. Thus, we are able to get by with far fewer interfaces
|
||||
supported in the C++ level, and defer most things to the Python code that uses
|
||||
XPConnect. As a result, the requirement for a huge number of interfaces to
|
||||
exist in the <i>.pyd</i> does not exist. There are, however, a number of
|
||||
interfaces that do require native C++ support: these are interfaces
|
||||
required to "boot" the XPConnect support (i.e., the interfaces that are
|
||||
used to get information about interfaces), and also two gateways that need to
|
||||
work without interface information available. This last requirement is
|
||||
due to the XPCOM shutdown-ordering - it may be a bug, but is not an unreasonable
|
||||
amount of code anyway.</p>
|
||||
<p><b>Auto-wrapping</b> of COM objects is supported by both client COM and
|
||||
server COM. For client COM, auto-wrapping means that the
|
||||
Python programmer always sees Python "component" objects, rather than
|
||||
raw C++ interface objects; to the user, it all appears to "just
|
||||
work". This is a major source of frustration in the <i>win32com</i>
|
||||
framework.</p>
|
||||
<p>For server COM, auto-wrapping means that you can
|
||||
pass Python instances wherever a COM object is expected. If the Python
|
||||
instance supports COM interfaces, by virtue of having a <i>_com_interfaces_</i>
|
||||
attribute that lists the interface requested, it will be automatically wrapped
|
||||
in the correct COM object. </p>
|
||||
<p><b>Error Handling:</b> The C++ framework has good error handling support,
|
||||
and uses the XPCOM console service to log debug messages, Python exceptions and
|
||||
tracebacks. <i>win32com</i> does not have good exception/traceback support
|
||||
at the C++ level, mainly because COM does not define a service like
|
||||
the console where debug messages can go. This does mean that in Mozilla
|
||||
release builds, these debug messages are likely to be lost, but the <i>--console</i>
|
||||
command line option to a release Mozilla will get them back. Therefore,
|
||||
the other error-support utilities, such as the error callbacks made on the
|
||||
policy object, may be used.</p>
|
||||
<p><b>Component Loader, Modules and Factories:</b> XPCOM has the concept
|
||||
of a component loader - a module used to load all components of a
|
||||
particular type. For example, the <i>moz.jsloader.1</i> component loads all
|
||||
the JavaScript components. Similarly, the <i>moz.pyloader.1</i>
|
||||
component loads all Python components. However, unlike
|
||||
JavaScript, the Python component loader is actually implemented in Python
|
||||
itself! Since the Python component loader can not be used to load
|
||||
itself, this component has some special code, <i>pyloader.dll,</i> to boot-strap itself.</p>
|
||||
<p>This means is that all XPCOM components, including the Python loader itself and all
|
||||
XPCOM module and factory interfaces, are implemented in
|
||||
Python. <b>There are no components or interfaces implemented purely in C++
|
||||
in this entire package!</b></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
198
mozilla/extensions/python/xpcom/doc/configure.html
Normal file
198
mozilla/extensions/python/xpcom/doc/configure.html
Normal file
@@ -0,0 +1,198 @@
|
||||
<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>Configuring your Environment</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Building, Configuring and Testing Python XPCOM Package</h1>
|
||||
<p>This document attempts to explain how to build, configure and test the
|
||||
Python XPCOM Package. This document assumes you have already successfully
|
||||
built
|
||||
Mozilla from source and your environment is currently set up for such a build -
|
||||
see the <a href="http://www.mozilla.org/build/">Mozilla build documentation</a>
|
||||
for more information.</p>
|
||||
<p>This section covers:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p align="left"><a href="#ConfigureTheEnvironment">Configuring your
|
||||
Environment</a></li>
|
||||
<li>
|
||||
<p align="left"><a href="#BuildingTheExtensions">Building</a></li>
|
||||
<li>
|
||||
<p align="left"><a href="#RunningTheTests">Testing your Setup</a></li>
|
||||
<li><a href="#Registration">Registering the Loader and Test
|
||||
Component</a></li>
|
||||
<li><a href="#RunningTheTests">Running the test suite</a></li>
|
||||
</ul>
|
||||
<h2><a name="ConfigureTheEnvironment">Configuring your Environment</a></h2>
|
||||
<p>In addition to the existing environment requirements for building Mozilla itself, the
|
||||
Python XPCOM package has the following requirements:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a name="MozillaDirectory"><b>Mozilla Directory</b></a><b> - </b>Ensure the Mozilla
|
||||
<i> bin</i> directory is on your PATH
|
||||
(LD_LIBRARY_PATH
|
||||
on Unix) so Python can locate the <i> xpcom.dll</i> module needed for
|
||||
core XPCOM services.</li>
|
||||
<li><a name="PYTHONPATH"><b>PYTHONPATH</b></a> - <tt>PYTHONPATH</tt> needs to be set appropriately. Ensure
|
||||
the parent to this <i>xpcom</i> directory is on your path so "import
|
||||
xpcom" locates this directory. Note that the Mozilla <i>components</i> directory does not need to be on the <tt>PYTHONPATH</tt>,
|
||||
but any modules used by your components must be set correctly. If anything
|
||||
is wrong here you should get a normal <tt>ImportError</tt>.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Note that on Windows, the PYTHONPATH is generally maintained in the
|
||||
Registry; however, you can set this variable at a DOS prompt, and it will still be
|
||||
added to the core PYTHONPATH.
|
||||
</blockquote>
|
||||
<h2><a name="BuildingTheExtensions">Building</a></h2>
|
||||
<p>The initial release of the Python XPCOM package has a very simple, hard-coded
|
||||
build process. The intention is to include this package in the Mozilla
|
||||
source tree, and integrate the build with the Mozilla build. Until this
|
||||
happens, perform the following steps:</p>
|
||||
<ul>
|
||||
<li>Ensure you can successfully build Mozilla itself from source-code.</li>
|
||||
<li>Unpack this source code, and change to the <i>xpcom</i> directory under
|
||||
the root <i>PyXPCOM</i> directory.</li>
|
||||
<li>For Windows, edit <i>makefile.stupid.win</i>, while for Linux, edit <i>makefile.stupid.linux</i></li>
|
||||
<li>As per the instructions at the top of the makefile, edit the MOZ_SRC,
|
||||
INSTALLDIR and PYTHON_SRC definitions appropriately.</li>
|
||||
</ul>
|
||||
<h3>Build Example: Building on Windows</h3>
|
||||
<p>For this example, we will assume that the source-code for Mozilla is in C:\src\mozilla,
|
||||
the source-code for the PyXPCOM package is in <i>c:\src\pyxpcom</i>. Further, we assume
|
||||
that you have Python 2.0 installed in <i>C:\Python20</i>, and wish to install
|
||||
the built Python XPCOM package so it exists in <i>C:\Python20\xpcom</i>.</p>
|
||||
<p>To build the package in this environment, you would perform the following
|
||||
steps:</p>
|
||||
<ul>
|
||||
<li>Unpack the PyXPCOM package source-code into the appropriate directory</li>
|
||||
<li>Edit makefile.stupid.win with the following changes:<br>
|
||||
<i>MOZ_SRC=c:\src<br>
|
||||
INSTALLDIR=C:\Python20<br>
|
||||
PYTHON_SRC=C:\Python20</i></li>
|
||||
<li> From the top-level Python xpcom source directory (i.e., the
|
||||
directory with <i>makefile.stupid.win</i>), execute the command:<br>
|
||||
<i>nmake -f makefile.stupid.win install</i></li>
|
||||
</ul>
|
||||
<p>NOTE: To build a Debug version of the Python XPCOM library, you can add <i>DEBUG=1</i>
|
||||
to the nmake command-line.</p>
|
||||
<p>If everything appears to work and you are brave, you may also like to execute
|
||||
<i>make -f makefile.stupid.win test</i> to execute the test script.
|
||||
Otherwise, continue to the following section where we confirm the installation
|
||||
step-by-step.</p>
|
||||
<h3>Build Example: Building on Linux</h3>
|
||||
<p>For this example, we will assume that the source-code for Mozilla is in ~/src/mozilla,
|
||||
the source-code for the PyXPCOM package is in ~/src/pyxpcom. Further, we assume
|
||||
that you have ActivePython 2.0 installed in <i>/usr/local/ActivePython2.0</i>,
|
||||
and wish to install the built Python XPCOM package so it exists in <i>/usr/local/ActivePython2.0/lib/python2.0/site-packages/xpcom</i>.</p>
|
||||
<p>To build the package in this environment, you would perform the following
|
||||
steps:</p>
|
||||
<ul>
|
||||
<li>Unpack the PyXPCOM package source-code into the appropriate directory</li>
|
||||
<li>Edit makefile.stupid.linux with the following changes (substituting
|
||||
username accordingly):<br>
|
||||
<i>MOZ_SRC=/home/username/src<br>
|
||||
INSTALLDIR=/usr/local/ActivePython-2.0/site-packages<br>
|
||||
PYTHON_SRC=/usr/local/ActivePython-2.0</i></li>
|
||||
<li>Build: As a regular user, from the top-level Python xpcom source
|
||||
directory (i.e., the directory with <i>makefile.stupid.linux</i>), execute
|
||||
the command:<br>
|
||||
<i>make -f makefile.stupid.linux DEBUG=1</i></li>
|
||||
<li>Install: Log in as a user with permissions to install into the relevant directories
|
||||
(usually the root user). From the top-level Python xpcom source
|
||||
directory (i.e., the directory with <i>makefile.stupid.linux</i>), execute
|
||||
the command:<br>
|
||||
<i>make -f makefile.stupid.linux DEBUG=1 install</i></li>
|
||||
<li>Switch back to a regular user, ready for testing!</li>
|
||||
</ul>
|
||||
<p>NOTE: The instructions above are for a Debug build, as this is the default
|
||||
Mozilla build type. If you have configured Mozilla to build a Release
|
||||
version of Mozilla, you can drop the DEBUG=1 option. It is important that
|
||||
PyXPCOM and Mozilla itself are consistent with respect to Release and Debug
|
||||
builds. For more details, please consult the makefile.</p>
|
||||
<p>If everything appears to work and you are brave, you may also like to execute
|
||||
<i>make -f makefile.stupid.linux test</i> to execute the test script.
|
||||
Otherwise, continue to the following section where we confirm the installation
|
||||
step--by-step.</p>
|
||||
<h2><a name="RunningTheTests">Testing your Setup</a></h2>
|
||||
<p>The Python XPCOM Package has a complete test suite. If you are
|
||||
impatient, you can simply execute <i>make -f makefile.stupid.linux test</i> (for
|
||||
Linux) or <i>nmake -f makefile.stupid.linux test</i> (for Windows). If
|
||||
this command indicates that the tests succeeded, then you can ignore the rest of
|
||||
this section.</p>
|
||||
<p>In the rest of this section, we walk through some simpler tests a step at a time,
|
||||
to help diagnose any problems.</p>
|
||||
<p><b>Note:</b> We recommend you do all your testing outside of <i> mozilla.exe</i>; it is far simpler to test all of
|
||||
this using the PyXPCOM package stand-alone.</p>
|
||||
<p><b>Note:</b> On Windows, if you use a debug build of Mozilla (i.e., in <i>dist\WIN32_D.OBJ\bin)</i>,
|
||||
you <b>must</b> use <i>python_d.exe</i>; if you use a release build (i.e., in
|
||||
a <i>dist\WIN32_O.OBJ\bin</i> directory), you must use <i>python.exe</i>.
|
||||
<i>makefile.stupid.win</i> handles this automatically.</p>
|
||||
<p>To test your setup:</p>
|
||||
<ol>
|
||||
<li>Start Python, and check<br>
|
||||
>>> <i>import xpcom</i><br>
|
||||
works. If not, <a href="#PYTHONPATH">check your PYTHONPATH</a> - the
|
||||
main PyXPCOM package can not be located..</li>
|
||||
<li>Check<i><br>
|
||||
>>> import xpcom._xpcom</i><br>
|
||||
|
||||
works. If not, then most likely your <a href="#MozillaDirectory">Mozilla
|
||||
directory is not on your path</a>, or something is wrong with <i>_xpcom(_d).pyd/_xpcommodule.so</i>.</li>
|
||||
|
||||
<li>Next run a simple test: <i>test/test_misc.py</i>. With a Windows debug build, the command may look like:<br>
|
||||
<i>C:\Anywhere> python_d \src\python\xpcom\test\test_misc.py<br>
|
||||
</i>or on Linux<br>
|
||||
<i>/home/user/src/mozilla/dist/bin$ python /home/user/src/python/xpcom/test/test_misc.py</i></li>
|
||||
</ol>
|
||||
<p>If you can't get this going, you won't get much further! If you do, the
|
||||
next step is to register our test component and run our full test suite.</p>
|
||||
<h2><a name="Registration">Registering the Loader and Test Component</a></h2>
|
||||
<p>First register the generic Python loader. For instructions, see the <a href="file:///F:/src/as/Komodo/src/pyxpcom/xpcom/doc/architecture.html">architecture
|
||||
document</a>. Do this only once, regardless of how many
|
||||
Python components you have. Then install the test component itself, and
|
||||
finally you can test it!</p>
|
||||
<h3>Registering the Python Loader and Component</h3>
|
||||
<p>To register the Python Loader and Component:</p>
|
||||
<ol>
|
||||
<li>Ensure the build process has put <i>pyloader.dll </i>(or <i>modpyloader.so</i>
|
||||
for Unix), and the files <i> py_test_component.py </i> and <i> py_test_component.idl</i> into
|
||||
the Mozilla <i>bin/components</i> directory. If not, copy the files
|
||||
there manually.</li>
|
||||
<li>Run <i>regxpcom</i>. <i>regxpcom</i> is a standard Mozilla
|
||||
executable, found in the <i>bin</i> directory, that detects whether the DLL and .py
|
||||
files have been added and registers them accordingly. You should
|
||||
see a few messages that include the following:</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<pre>Registering: PythonComponentLoader
|
||||
Registered 1 Python components in pyloader.dll
|
||||
nsNativeComponentLoader: autoregistering succeeded
|
||||
Auto-registering all Python components in F:\src\mozilla\dist\WIN32_D.OBJ\bin\components
|
||||
Registering: PythonTestComponent
|
||||
Registered 1 Python components in py_test_component.py</pre>
|
||||
</blockquote>
|
||||
<p>If so (or you see no message at all), you are ready to run the test suite.</p>
|
||||
<p><b>Note</b>: If you execute this same step a second time, you will not
|
||||
see any of the above mentioned messages. XPCOM knows that nothing has
|
||||
changed since you last ran <i>regxpcom</i>, so nothing is registered. If
|
||||
you do not see these messages the first time you run it, there is the
|
||||
possibility that some other process, possibly the build process, has already
|
||||
executed this step.</p>
|
||||
<h2><b>Running the Test Suite</b></h2>
|
||||
<p>To run the test suite, run <i>xpcom/test/regrtest.py.</i> This runs the
|
||||
tests and ensures that the test output is as expected. If all tests
|
||||
pass, you have a fully functioning Python XPCOM package. Enjoy!</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
54
mozilla/extensions/python/xpcom/doc/credits.html
Normal file
54
mozilla/extensions/python/xpcom/doc/credits.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<html>
|
||||
<!-- Copyright (c) 2000-2001 ActiveState Tool Corporation.
|
||||
See the file LICENSE.txt for licensing information. -->
|
||||
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-au">
|
||||
<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>Credits and Acknowledgements</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Credits and Acknowledgements</h1>
|
||||
<h2>ActiveState Tool Corporation</h2>
|
||||
<p>The Python XPCOM Package was developed primarily by <a href="mailto:markh@activestate.com">Mark
|
||||
Hammond</a> of <a href="http://www.ActiveState.com">ActiveState Tool Corporation</a>.</p>
|
||||
<p>The developers on the <a href="http://www.ActiveState.com/Products/Komodo">Komodo
|
||||
project</a> deserve high praise for putting up with early versions when almost
|
||||
nothing worked, and for believing in Python as a viable XPCOM language.
|
||||
Their feedback and patience has allowed the first public release to be amazingly
|
||||
functional and bug-free.</p>
|
||||
<h3>Komodo Development Team (at December 2000)</h3>
|
||||
<p><a href="mailto:davida@activestate.com">David Ascher</a>, <a href="mailto:aaronb@ActiveState.com">Aaron Bingham</a>,
|
||||
<a href="mailto:bindu@activestate.com">Bin Du</a>, <a href="mailto:markh@activestate.com">Mark
|
||||
Hammond</a>, <a href="mailto:trentm@activestate.com">Trent Mick (build god)</a>,
|
||||
<a href="mailto:paulp@activestate.com">Paul Prescod</a>, <a href="mailto:ericp@ActiveState.com">Eric Promislow</a>,
|
||||
<a href="mailto:kens@ActiveState.com">Ken Simpson</a>, <a href="mailto:neilw@ActiveState.com">Neil Watkiss</a>,
|
||||
<a href="mailto:AudreyS@ActiveState.com">Audrey Schumacher</a>.</p>
|
||||
<h2>Mozilla/Netscape</h2>
|
||||
<p>The following people at <a href="http://www.netscape.com">Netscape</a> and <a href="http://www.mozilla.org">Mozilla</a>
|
||||
(or not there but still heavily involved in the project) have provided enormous
|
||||
help in getting things integrated with their build system, answering us on the
|
||||
newsgroup, teaching us the finer points of XPCOM, gently slapping us for accidentally
|
||||
referring to <i>jscript</i>, etc., and otherwise lending us a clue in the
|
||||
Mozilla/Netscape/XPCOM world.</p>
|
||||
<p><a href="mailto:jband@netscape.com">John Bandhauer</a>, <a href="mailto:brendan@meer.net">Brendan
|
||||
Eich</a>, <a href="mailto:shaver@zeroknowledge.com">Mike Shaver</a>, <a href="mailto:evaughan@netscape.com">Eric Vaughan</a>,
|
||||
<a href="mailto:hyatt@netscape.com">David Hyatt</a></p>
|
||||
<h2>External Contributors</h2>
|
||||
<p>The following people have made contributions to the project, simply because
|
||||
they find it useful and enjoy supporting Open Source projects.</p>
|
||||
<p><a href="mailto:cmeerw@web.de">Christof Meerwald</a></p>
|
||||
<h2>Documentation Credits</h2>
|
||||
<p>The following people have contributed to the Python XPCOM Package
|
||||
documentation </p>
|
||||
<p><a href="mailto:markh@activestate.com">Mark
|
||||
Hammond</a>, <a href="mailto:AudreyS@ActiveState.com">Audrey Schumacher</a></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
240
mozilla/extensions/python/xpcom/doc/tutorial.html
Normal file
240
mozilla/extensions/python/xpcom/doc/tutorial.html
Normal file
@@ -0,0 +1,240 @@
|
||||
<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 Package Tutorial</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Python XPCOM Package Tutorial</h1>
|
||||
<p>This is a quick introduction to the Python XPCOM Package. We assume that you have a good understanding of Python and <a href="http://www.mozilla.org/projects/xpcom/">XPCOM</a>,
|
||||
and have experience both using and implementing XPCOM objects in some other
|
||||
language (e.g., C++ or JavaScript). We <b><i>do not</i></b> attempt to
|
||||
provide a tutorial to XPCOM or Python itself, only to using Python <i>and</i>
|
||||
XPCOM.</p>
|
||||
<p>This tutorial contains the following sections:</p>
|
||||
<ul>
|
||||
<li><a href="#Using">Using XPCOM Objects and Interfaces</a> - when you wish to
|
||||
<i>use</i> a component written by anyone else in any XPCOM supported
|
||||
language.</li>
|
||||
<li><a href="#Implementing">Implementing XPCOM Objects and Interfaces</a> -
|
||||
when you wish to implement a component for use by anyone else in any xpcom
|
||||
supported language.</li>
|
||||
<li><a href="#Parameters">Parameters and Types</a> - useful information
|
||||
regarding how Python translates XPCOM types, and handles byref parameters.</li>
|
||||
</ul>
|
||||
<p>For anything not covered here, try the <a href="advanced.html">advanced
|
||||
documentation</a>, and if that fails, use the source, Luke!</p>
|
||||
<h2><a name="Using">Using XPCOM object and interfaces.</a></h2>
|
||||
<p>The techniques for using XPCOM in Python have been borrowed from JavaScript -
|
||||
thus, the model described here should be quite familiar to existing JavaScript
|
||||
XPCOM programmers.</p>
|
||||
<h3>xpcom.components module</h3>
|
||||
<p>When using an XPCOM object, the primary module used is the <u><i>xpcom.components</i></u>
|
||||
module. Using this module, you can get a Python object that supports any
|
||||
scriptable XPCOM interface. Once you have this Python object, you can
|
||||
simply call XPCOM methods on the object, as normal.</p>
|
||||
<p>The <u><i>xpcom.components</i></u> module defines the following public
|
||||
members:</p>
|
||||
<table border="1" width="100%">
|
||||
<tr>
|
||||
<td width="16%"><b>Name</b></td>
|
||||
<td width="84%"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="16%">classes</td>
|
||||
<td width="84%">A mapping (dictionary-like object) used to get XPCOM
|
||||
"classes". These are indexed by XPCOM contract ID, just
|
||||
like the JavaScript object of the same name.
|
||||
<p>Example:</p>
|
||||
<pre>cls = components.classes["@mozilla.org/sample;1"]
|
||||
ob = cls.createInstance() # Now have an nsISupports</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="16%">interfaces</td>
|
||||
<td width="84%">An object that exposes all XPCOM interface IDs (IIDs).
|
||||
Like the JavaScript object of the same name, this object uses
|
||||
"dot" notation, as demonstrated below.
|
||||
<p>Example:</p>
|
||||
<pre>ob = cls.createInstance(components.interfaces.nsISample)
|
||||
# Now have an nsISample</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>For many people, this is all you need to know. Consider the Mozilla Sample Component. The Mozilla Sample
|
||||
Component has a contract ID of <i>@mozilla.org/sample;1</i>,
|
||||
and implements the <i>nsISample</i> interface.</p>
|
||||
<p>Thus, a complete Python program that uses this component is shown below.</p>
|
||||
<pre>from xpcom import components
|
||||
cls = components.classes["@mozilla.org/sample;1"]
|
||||
ob = cls.createInstance(components.interfaces.nsISample)
|
||||
# nsISample defines a "value" property - let's use it!
|
||||
ob.value = "new value"
|
||||
if ob.value != "new value":
|
||||
print "Eeek - what happened?"</pre>
|
||||
<p>And that is it - a complete Python program that uses XPCOM.</p>
|
||||
<h2><a name="Implementing">Implementing XPCOM Objects and Interfaces.</a></h2>
|
||||
<p>Implementing XPCOM objects is almost as simple as using them. The
|
||||
basic strategy is this:</p>
|
||||
<ol>
|
||||
<li>Create a standard Python source file, with a standard Python class.</li>
|
||||
<li>Add some special <a href="#Attributes"> attributes</a> to your class for use by the Python XPCOM
|
||||
framework. This controls the XPCOM behavior of your object.</li>
|
||||
<li>Implement the XPCOM <a href="#Properties"> properties</a> and methods of your classes as normal.</li>
|
||||
<li>Put the Python source file in the Mozilla <i> components</i> directory.</li>
|
||||
<li>Run <i> regxpcom.</i></li>
|
||||
</ol>
|
||||
<p>Your component is now ready to be used.</p>
|
||||
<h3><a name="Attributes">Attributes</a></h3>
|
||||
<p>There are two classes of attributes: those used at runtime to define the object
|
||||
behavior and those used at registration time to control object
|
||||
registration. Not all objects require registration, thus not all
|
||||
Python XPCOM objects will have registration-related attributes.</p>
|
||||
<table border="1" width="100%">
|
||||
<tr>
|
||||
<td width="17%"><b>Attribute</b></td>
|
||||
<td width="83%"><b>Description</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="17%">_com_interfaces_</td>
|
||||
<td width="83%">The interface IDs (IIDs) supported by the component.
|
||||
For simplicity, this may be either a single IID, or a list of IIDs.
|
||||
There is no need to specify base interfaces, as all parent interfaces are
|
||||
automatically supported. Thus, it is never necessary to nominate <i>
|
||||
nsISupports</i> in the list of interfaces.
|
||||
<p>This attribute is required. Objects without such an attribute are
|
||||
deemed unsuitable for use as a XPCOM object.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="17%">_reg_contractid_</td>
|
||||
<td width="83%">The contract ID of the component. Required if the
|
||||
component requires registration (i.e., exists in the components directory).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="17%">_reg_clsid_</td>
|
||||
<td width="83%">The Class ID (CLSID) of the component, as a string in the
|
||||
standard "{XXX-XXX-XXX-XXX}" format. Required if the
|
||||
component requires registration (i.e., exists in the components directory).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="17%">_reg_registrar_</td>
|
||||
<td width="83%">Nominates a function that is called at registration
|
||||
time. The default is for no extra function to be called. This can
|
||||
be useful if a component has special registration requirements and needs
|
||||
to hook into the registration process.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="17%">_reg_desc_</td>
|
||||
<td width="83%">The description of the XPCOM object. This may be used by
|
||||
browsers or other such objects. If not specified, the contract ID
|
||||
is used.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h3><a name="Properties">Properties</a></h3>
|
||||
<p>A Python class can support XPCOM properties in one of two ways. Either
|
||||
a standard Python property of the same name can exist - our sample
|
||||
component demonstrates this with the <i>boolean_value</i> property.
|
||||
Alternatively, the class can provide the <i>get_propertyName(self)</i> and <i>set_propertyName(self,
|
||||
value)</i> functions (with <i>propertyName</i> changed to the appropriate value for the
|
||||
property), and these functions will be called instead.</p>
|
||||
<h4>Example: The Python XPCOM Test Component</h4>
|
||||
<p>As an example, examine the Python XPCOM Test Component. This
|
||||
code can be found in <i>py_test_component.py</i>.</p>
|
||||
<pre>from xpcom import components
|
||||
|
||||
class PythonTestComponent:
|
||||
_com_interfaces_ = components.interfaces.nsIPythonTestInterface
|
||||
_reg_clsid_ = "{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}"
|
||||
_reg_contractid_ = "Python.TestComponent"
|
||||
def __init__(self):
|
||||
self.boolean_value = 1
|
||||
...
|
||||
def do_boolean(self, p1, p2):
|
||||
ret = p1 ^ p2
|
||||
return ret, not ret, ret
|
||||
...</pre>
|
||||
<p><b>Note:</b> This component only specifies the mandatory attributes - <i>_com_interfaces</i>,
|
||||
<i>_reg_clsid_</i> and <i>_reg_contractid_</i>.</p>
|
||||
<p>This sample code demonstrates supporting the <i>boolean_value</i> attribute,
|
||||
supported implicitly, as it is defined in the IDL and exists as a real Python
|
||||
attribute of that name, and a method called <i>do_boolean</i>.</p>
|
||||
<h4>Tip: The xpcom/xpt.py Script</h4>
|
||||
<p> The xpcom/xpt.py script is a useful script that can generate the skeleton of a class for
|
||||
any XPCOM interface. Just specify the interface name on the command-line,
|
||||
and paste the output into your source file.</p>
|
||||
<p>This is the output of running this program over the <i>nsISample</i>
|
||||
interface (i.e., assuming we wanted to implement a component that supported this
|
||||
interface):</p>
|
||||
<pre>class nsISample:
|
||||
_com_interfaces_ = xpcom.components.interfaces.nsISample
|
||||
# If this object needs to be registered, the following 2 are also needed.
|
||||
# _reg_clsid_ = {a new clsid generated for this object}
|
||||
# _reg_contractid_ = "The.Object.Name"
|
||||
|
||||
def get_value( self ):
|
||||
# Result: string
|
||||
pass
|
||||
def set_value( self, param0 ):
|
||||
# Result: void - None
|
||||
# In: param0: string
|
||||
pass
|
||||
def writeValue( self, param0 ):
|
||||
# Result: void - None
|
||||
# In: param0: string
|
||||
pass
|
||||
def poke( self, param0 ):
|
||||
# Result: void - None
|
||||
# In: param0: string
|
||||
pass</pre>
|
||||
<p><b>Note:</b> The types of the parameters and the function itself are included in
|
||||
the comments. You need to implement the functions
|
||||
themselves. Another advantage of this script is that the <a href="#HiddenParams">hidden
|
||||
parameters</a> are handled for you; the comments indicate when parameters
|
||||
have been hidden.</p>
|
||||
<h2><a name="Parameters">Parameters and Types</a></h2>
|
||||
<p>This section briefly describes the XPCOM type support in
|
||||
Python.</p>
|
||||
<p>All XPCOM interfaces define parameters of a specific type. There is
|
||||
currently no concept of a variant, or union of all types. Thus, the
|
||||
conversion rules are very straightforward, and generally surprise free: for
|
||||
any given XPCOM method, there is only one possible type for a given parameter.</p>
|
||||
<h3>Type Conversion Rules:</h3>
|
||||
<ul>
|
||||
<li>All numeric types will attempt to be coerced to the correct type.
|
||||
Thus, you can pass a Python float to an XPCOM method expecting an integer,
|
||||
or vice-versa. Specifically, when an integer is required, you can pass
|
||||
any Python object for which <i>int()</i> would succeed; for a Python float,
|
||||
any object for which <i>float()</i> would succeed is acceptable. This
|
||||
means that you can pass a Python string object as an integer, as long as the
|
||||
string was holding a valid integer.</li>
|
||||
<li>Strings and Unicode objects are interchangeable, but no other automatic
|
||||
string conversions are performed. Thus, you can not pass an integer
|
||||
where a string is expected, even though the reverse is true.</li>
|
||||
<li>Any sequence object can be passed as an array. List objects are
|
||||
always returned for arrays.</li>
|
||||
<li>Any Python instance suitable for use as a XPCOM object (i.e., with the
|
||||
<a href="#Implementing">necessary annotations</a>) can be
|
||||
passed as a XPCOM object. No special wrapping step is needed to turn a
|
||||
Python instance into a XPCOM object. Note you must pass a class <i>instance</i>,
|
||||
not the class itself.</li>
|
||||
<li><a name="HiddenParams">Many XPCOM <b> method signatures</b> specify
|
||||
"count" or "size" parameters. For example, every
|
||||
time an array is passed via XPCOM, the method signature will always specify
|
||||
an integer that holds the count of the array. These parameters are
|
||||
always hidden in Python. As the size param can be implied from the
|
||||
length of the Python sequence passed, the Python programmer need never pass
|
||||
these parameters; in contrast, JavaScript requires these redundant parameters.</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user