mirror of https://github.com/tLDP/LDP
484 lines
21 KiB
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'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&aid=570640&group_id=5470&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 'basic' means 'is required',
|
|
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' 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>
|