LDP/LDP/retired/PLD-Guide/devel/python.xml

484 lines
21 KiB
XML

<section id='python'>
<title>Python Packages</title>
<abstract>
<para>
This section describes how to prepare packages which contain
applications written in Python, Python modules and Python language
itself.
</para>
</abstract>
<section id='python.dist'>
<title>What is distributed?</title>
<para>
There is no doubt when you create package with Python modules,
which sources are written in C language. Sources should be
compiled for given architecture, that&apos;s all. The problem arises
when modules are written in Python language. What should be
distributed? Sources - *.py files? Byte compiled files - *.pyc?
Optimized byte compiled files - *.pyo? All of them?
</para>
<para>
We have decided that packages with Python modules
should contain both, byte compiled and optimized byte compiled
files. Yes, *.pyc and *.pyo files.
Python interpreter cannot switch between .pyc and .pyo
files on runtime currently and it seems that it will never
be (please, read history of Python bug #570640:
http://sourceforge.net/tracker/index.php?func=detail&amp;aid=570640&amp;group_id=5470&amp;atid=105470).
</para>
<para>
We could force lub forbid the usage of optimized byte compiled
modules, but it is not practical due to possible binary only
packages from other vendors. Vendors can provide one of the
types of compiled modules, so we would create the big
inconvenience for PLD users and administrators.
</para>
<para>
Why not to distribute only *.py files?
PLD developers aim to
provide optimized software whenever it is possible.
We want to provide fully optimized Python modules too
as we provide packages
optimized for many architectures. It would be not a good idea if
users, who want to use optimized modules, have been forced
to create them manually because it requires root privileges
and creates files which are in <filename>/usr</filename>
filesystem hierarchy
and not in <application>RPM</application> database.
</para>
<para>
Distributing sources and byte compile them during package
installation (to avoid manual pain) is not an option, too. It
is because of general idea, which says that we distribute
prepared, binary packages so user is not forced to compile the
sources. Such philosophy applies also to Python language, which
should not be an exception.
</para>
</section>
<section id='python.lang'>
<title>Python Language</title>
<para>
Python language is splitted into several packages, which are listed below.
</para>
<para>
Package with Python library contains some basic modules. The modules are required
to use the library with applications embedding simple Python code.
Some people could complain, that there are no modules,
which seem to be basic. The word &apos;basic&apos; means &apos;is required&apos;,
so simple Python code embedding works. Consider following listing.
<programlisting>
<![CDATA[
#include <Python.h>;
int main(int argc, char *argv[]) {
Py_Initialize();
PyRun_SimpleString("print 2**4");
Py_Finalize();
return 0;
}]]>
</programlisting>
If the modules are not present, then there will be the error message
that Python cannot find platform independent libraries.
</para>
<variablelist>
<varlistentry>
<term role="rpm.package">python</term>
<listitem>
<para>
Python command line utility and its manual.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-modules</term>
<listitem>
<para>
Standard Python modules.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-libs</term>
<listitem>
<para>
Python library and basic modules.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">pydoc</term>
<listitem>
<para>
PyDoc module and command line utility.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">idle</term>
<listitem>
<para>
Idle - IDE for Python language.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-devel</term>
<listitem>
<para>
Development files, i.e. header and Python config files.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-devel-src</term>
<listitem>
<para>
Sources of all standard Python modules.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-static</term>
<listitem>
<para>
Python static library.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-examples</term>
<listitem>
<para>
All examples and tools which come with standard Python distribution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-doc</term>
<listitem>
<para>
Python documentation in HTML format. It contains tutorial, global module index, library and
language reference, etc.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-tkinter</term>
<listitem>
<para>
Standard Python interface to the Tk GUI toolkit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.package">python-old</term>
<listitem>
<para>
Obsoleted Python modules.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
One can easily note, that sources of standard Python modules are distributed
in <literal role="rpm.package">python-devel-src</literal> package. It is an exception to the rule,
that we do not distribute sources of modules for Python language.
</para>
<para>
There is one more confusing thing. Package <literal role="rpm.package">python-examples</literal>
contains examples and tools. We should split tools into subpackages and it will
certainly happen, but when... we do not know. Yes, we are lazy people! :-]
</para>
</section>
<section id='python.modules'>
<title>Python Modules</title>
<section id='python.modules.install'>
<title><application>RPM</application> Install Section</title>
<para>
Python modules can be installed with
<itemizedlist>
<listitem><simpara>autoconf/automake combo</simpara></listitem>
<listitem><simpara>distutils</simpara></listitem>
<listitem><simpara>other method (hand written Makefile files, manual
installation)</simpara></listitem>
</itemizedlist>
</para>
<para>
<application>Automake</application> 1.5 introduced Python
support. Developers want to use the same tool for
their projects written in Python or C and
<application>automake</application> gives such possibility to them.
</para>
<para>
Installing Python modules can be done the same way
as installing other applications or libraries, which
authors use <application>automake</application>.
Just remember to pass <envar>$RPM_BUILD_ROOT</envar>
to <envar>DESTDIR</envar>, so
<application>make</application> will install source files
(*.py), byte compiled (*.pyc) and optimized byte compiled
(*.pyo) files under <envar>$RPM_BUILD_ROOT</envar>
hierarchy.
<example>
<title>
Installing Python modules with Makefile files
created with <application>automake</application>.
</title>
<screen>%{__make} install DESTDIR=$RPM_BUILD_ROOT</screen>
</example>
</para>
<para>
Python <literal role='lib'>distutils</literal>
has ability to install optimized and
normal byte compiled files. It can be done with
<command>setup.py</command> script option
<parameter>--optimize</parameter>.
Option <parameter>--root</parameter> should
be used too, because installed files
should be put in <envar>$RPM_BUILD_ROOT</envar>
directory.
<example>
<title>
Installing Python modules in <application>RPM</application> install section
with <literal role='lib'>distutils</literal>.
</title>
<screen>python setup.py install --optimize=2 --root=$RPM_BUILD_ROOT</screen>
</example>
Sometimes <literal role='lib'>distutils</literal>
refuses to install files under
<envar>$RPM_BUILD_ROOT</envar> hierarchy. Set
<envar>$PYTHONPATH</envar> variable to
<literal>$RPM_BUILD_ROOT%{py_sitedir}</literal> value
before module installation.
</para>
<!-- para>
There can be other methods of installing Python modules.
The problem is, that a method could not provide support
to install byte compiled modules.
For example, you can be forced to install them manually
or provided Makefile installs only module sources.
There are
two macros <literal role="rpm.macro">py_comp</literal> and <literal role="rpm.macro">py_ocomp</literal>,
which help with installation. Look for macros descriptions below.
</para>
<para>
Macros, mentioned above, are useful when installing modules manually, too.
Just install module sources under <file>$RPM_BUILD_ROOT</file>.
</para -->
</section>
<section id='python.modules.groups'>
<title><application>RPM</application> groups</title>
<para>
Every package is assigned to <application>RPM</application>
group. Packages which contain developer files such as
header files should be assigned to
<literal role='rpm.group'>Development/Languages/Python</literal>
group.
Packages with just modules should be assigned to <literal
role='rpm.group'>Libraries/Python</literal> group.
</para>
<para>
Rules used to assign
<application>RPM</application> group to applications, apply
to applications written in Python, too. Taking
<application>sketch</application> for example, the
graphics manipulation program, there is
used <literal role='rpm.group'>X11/Application/Graphics</literal>
group. Another example is
<application>happydoc</application> with
<literal role='rpm.group'>Development/Tools</literal> group or
<application>ipython</application> with <literal
role='rpm.group'>Applications/Shells</literal> group.
</para>
</section>
</section>
<section id='python.macros'>
<title>Standard <application>RPM</application> Macros</title>
<para>
Following macros are defined to make Python packages developers&apos; life better.
<variablelist>
<varlistentry>
<term role="rpm.macro">py_ver</term>
<listitem>
<para>
Python main version. For example, Python 2.2, 2.2.1 and 2.2.2
main version is <literal>2.2</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_prefix</term>
<listitem>
<para>
Directory prefix, where Python is installed. It points to <filename>/usr</filename>, usually.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_libdir</term>
<listitem>
<para>
Directory, where Python is installed. It is created from prefix and Python main version,
i.e. <filename>/usr/lib/python2.2</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_incdir</term>
<listitem>
<para>
Directory, where Python header files are installed, i.e. <filename>/usr/include/python2.2</filename>. Yes, main version is used to build it.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_sitedir</term>
<listitem>
<para>
Directory, where all non-standard, site specific Python modules are installed. It is created from
library directory, i.e. <filename>/usr/lib/python2.2/site-packages</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_dyndir</term>
<listitem>
<para>
Directory, where all shared modules are installed. It is created
from library directory, i.e. <filename>/usr/lib/python2.2/lib-dynload</filename>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_comp</term>
<listitem>
<para>
Finds recursively all Python source files in
specified directory and compiles them into
bytecode.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">py_ocomp</term>
<listitem>
<para>
Finds recursively all Python source files in
specified directory and compiles them into
optymized bytecode.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term role="rpm.macro">pyrequires_eq()</term>
<listitem>
<para>
Creates dependency on specified package with main version
unchanged.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Most of above macros are self explanatory... and some not, so read on. :-)
</para>
<section id='python.macros.comp'>
<title>Modules Compilation Macros</title>
<para>
Macros <literal role="rpm.macro">py_comp</literal>
and <literal role="rpm.macro">py_ocomp</literal> should be used when
software installation routine does
not provide byte compiled modules installation.
</para>
<para>
The macros use Python <literal role="lib">compileall</literal>
module which scans given directory and its subdirectories for Python modules and compiles
them into bytecode.
<example>
<title>
Compiling Python modules into bytecode.
</title>
<screen>%install
...
%py_comp $RPM_BUILD_ROOT%{py_sitedir}
%py_ocomp $RPM_BUILD_ROOT%{py_sitedir}</screen>
</example>
</para>
<para>
Please note, that compilation must be performed after module source files installation, because
the directory path, where the sources reside, is put into binary files
during byte compilation.
Information about correct directory path in compiled modules is useful, due to
thrown exceptions which display it.
<!--Consider following
examples:
<programlisting>
<![CDATA[
Traceback (most recent call last):
File "tracedir.py", line 6, in ?
logging.setLoggerClass(X)
File "/home/users/user/tmp/python-2.3b1-root-user/usr/lib/python2.3/logging/__init__.py", line 729, in setLoggerClass
TypeError: logger not derived from logging.Logger: X
]]>
</programlisting>
<programlisting>
<![CDATA[
Traceback (most recent call last):
File "tracedir.py", line 6, in ?
logging.setLoggerClass(X)
File "/usr/lib/python2.3/logging/__init__.py", line 729, in setLoggerClass
TypeError: logger not derived from logging.Logger: X
]]>
</programlisting>
First example shows exception thrown by code compiled under
-->
</para>
</section>
<section id='python.macros.pyrequires_eq'>
<title>Requirements of Python Packages Macros</title>
<para>
Macro <literal role='rpm.macro'>pyrequires_eq</literal> is
very useful for packages which require software distributed
with Python language.
</para>
<para>
It creates dependency on specified package with main
version unchanged. For example, when you want
dependency on <literal role='rpm.package'>python-libs</literal> package and use this
macro, then created package will require
<literal role='rpm.package'>python-libs</literal> with
version greater or equal to 2.2 and less then 2.3 (when
Python 2.2.x is installed, of course).
</para>
<example>
<title>
Using <literal role='rpm.macro'>pyrequires_eq</literal>
macro.
</title>
<screen>...
URL: http://daa.com.au/~james/pygtk
%pyrequires_eq python-modules
BuildRequires: libglade2-devel >= 2.0.0
...</screen>
</example>
<para>
The macro is very useful, because new minor Python
language versions do not (or should not) introduce
any incompatible modifications such as library API.
Such way, it is easy to upgrade distribution software
without unnecessary recompilation of several modules.
</para>
</section>
</section>
</section>