From Fedora Project Wiki

m (1 revision(s))
m (Fixed templates)
Line 9: Line 9:


= Hints on how to Package Python modules =
= Hints on how to Package Python modules =


== Python version ==
== Python version ==
Line 36: Line 35:
</pre>
</pre>


{{Template:Note}} For python modules that include any architecture-specific libraries (like those written in C), you should additionally use:
{{Admon/note | For python modules that include any architecture-specific libraries (like those written in C), you should additionally use:}}


<pre>
<pre>
Line 44: Line 43:
This will ensure the package is installed correctly on multilib architectures.  By using these macros instead of hardcoding the directory in the specfile your spec remains compatible with the installed python version even if the diretory structure changes radically (for instance, if python_sitelib moves into %{_datadir})
This will ensure the package is installed correctly on multilib architectures.  By using these macros instead of hardcoding the directory in the specfile your spec remains compatible with the installed python version even if the diretory structure changes radically (for instance, if python_sitelib moves into %{_datadir})


{{Template:Warning}} You shouldn't rely on INSTALLED_FILES, as that will not list directories, which will need to be specified in the %files section as well. Using globs in the %files section is safer.
{{Admon/warning | You shouldn't rely on INSTALLED_FILES, as that will not list directories, which will need to be specified in the %files section as well. Using globs in the %files section is safer.}}


== setuptools/eggs ==
== setuptools/eggs ==
Line 100: Line 99:
=== Including pyos ===
=== Including pyos ===
In the past it was common practice to %ghost .pyo files in order to save a small amount of space on the users filesystem.  However, this has two issues:
In the past it was common practice to %ghost .pyo files in order to save a small amount of space on the users filesystem.  However, this has two issues:
1. With SELinux, if a user is running python -O [APP]  it will try to write the .pyos when they don't exist.  This leads to AVC denial records in the logs.
# With SELinux, if a user is running python -O [APP]  it will try to write the .pyos when they don't exist.  This leads to AVC denial records in the logs.
2. If the system administrator runs python -OO [APP]  the .pyos will get created with no docstrings.  Some programs require docstrings in order to function.  On subsequent runs with python -O [APP]  python will use the cached .pyos even though a different optimization level has been requested.  The only way to fix this is to find out where the .pyos are and delete them.
# If the system administrator runs python -OO [APP]  the .pyos will get created with no docstrings.  Some programs require docstrings in order to function.  On subsequent runs with python -O [APP]  python will use the cached .pyos even though a different optimization level has been requested.  The only way to fix this is to find out where the .pyos are and delete them.


The current method of dealing with pyo files is to '''include them as is, no %ghosting'''.
The current method of dealing with pyo files is to '''include them as is, no %ghosting'''.
Line 108: Line 107:


From FC4 to current development, the automatic byte compilation of python files that is performed by brp-python-bytecompile byte compiles all files that match *.py  This is undesirable for program files in %{_bindir} and %{_sbindir} because the user will probably never invoke these files, only the main program file and python won't use these files.  Until the bug is resolved, there are two workarounds:
From FC4 to current development, the automatic byte compilation of python files that is performed by brp-python-bytecompile byte compiles all files that match *.py  This is undesirable for program files in %{_bindir} and %{_sbindir} because the user will probably never invoke these files, only the main program file and python won't use these files.  Until the bug is resolved, there are two workarounds:
1. Rename scripts in %{_bindir} to not have a .py extension:  For instance, from /usr/bin/orient.py to /usr/bin/orient.
# Rename scripts in %{_bindir} to not have a .py extension:  For instance, from /usr/bin/orient.py to /usr/bin/orient.
2. Use %exclude to exclude the scripts from the file listing:
# Use %exclude to exclude the scripts from the file listing:
<pre>
<pre>
%files
%files

Revision as of 02:00, 3 June 2008

:Version: 0.2.2
:Last Revised: Aug 23, 2006
:ChangeLog:
Update the setuptools/egg section due to a new setuptools in Extras.

Hints on how to Package Python modules

Hints on how to Package Python modules

Python version

In the past (FC3 and earlier) it was mandatory to add the line

Requires:       python-abi = %(%{__python} -c "import sys ; print sys.version[[3]] ")

to the spec file to require a specific version of the python-abi. This is not needed anymore in FC4 and later because rpm adds a automatic dependency on python(abi) now on its own.

System Architecture

If you are installing anything into the global site_packages directory, use the following trick. First, define python_sitelib at the top of your specfile:

%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}

On an i386 python-2.4 system, for example, %{python_sitelib} will be /usr/lib/python2.4/site-packages. During %install, or when listing %files, you can use the %{python_sitelib} macro to specify the path. For example:

%files
%defattr(-,root,root,-)
%dir %{python_sitelib}/modulename
%{python_sitelib}/modulename/*.py
%{python_sitelib}/modulename/*.pyc
Note.png
For python modules that include any architecture-specific libraries (like those written in C), you should additionally use:
%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}

This will ensure the package is installed correctly on multilib architectures. By using these macros instead of hardcoding the directory in the specfile your spec remains compatible with the installed python version even if the diretory structure changes radically (for instance, if python_sitelib moves into %{_datadir})

Warning.png
You shouldn't rely on INSTALLED_FILES, as that will not list directories, which will need to be specified in the %files section as well. Using globs in the %files section is safer.

setuptools/eggs

Python packages that use setuptools need to add python-setuptools as a Build'Requires and must either add --single-version-externally-managed to the line invoking setup.py in %install, or must add a .pth file containing the path to the egg or egg directory to %{python_sitelib}.

  • As of setuptools-0.6a11 the setuptools homepage recommends using the --root switch instead of --single-version-externally-managed. This needs to be looked at further, but seems like it is okay to do this way.

Setuptools home page

Further egg information that needs to be distilled out here: http://permalink.gmane.org/gmane.comp.python.distutils.devel/2567 http://mail.python.org/pipermail/distutils-sig/2005-November/005399.html

Byte Compiled Files

Python will automatically try to byte compile files when it runs in order to speed up startup the next time it is run. These files are saved in files with the extension of .pyc (compiled python) or .pyo (optimized compiled python). These files are a byte code that is portable across OSes. If you do not include them in your packages, python will try to create them when the user runs the program. If the system administrator uses them, then the files will be successfully written. Later, when the package is removed, the .pyc and .pyo files will be left behind on the filesystem. To prevent that you need to byte compile the files when building your package and include the files in the %files section.

If you are only going to build for FC4+, rpm has a script that will create the files for you. All you have to do is remember to include the files in your spec file. The following are all acceptable ways to accomplish this:

%install
install -d %{python_sitelib}/foo
install -pm 0644 foo.py %{python_sitelib}/foo/

Either:

%files
%dir %{python_sitelib}/foo
%{python_sitelib}/foo/foo.py
%{python_sitelib}/foo/foo.pyc
%{python_sitelib}/foo/foo.pyo

Or:

%files
%dir %{python_sitelib}/foo
%{python_sitelib}/foo/foo.py*

Or even:

%files
%{python_sitelib}/foo/

For Core releases earlier than FC4, you need to generate the .pyc and .pyo files yourself.

If your module is using distutils, use the following commands during %install:

%{__python} setup.py install --skip-build --root $RPM_BUILD_ROOT
%{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT

And remember to add the .pyc and .pyo files to your %files section.

Including pyos

In the past it was common practice to %ghost .pyo files in order to save a small amount of space on the users filesystem. However, this has two issues:

  1. With SELinux, if a user is running python -O [APP] it will try to write the .pyos when they don't exist. This leads to AVC denial records in the logs.
  2. If the system administrator runs python -OO [APP] the .pyos will get created with no docstrings. Some programs require docstrings in order to function. On subsequent runs with python -O [APP] python will use the cached .pyos even though a different optimization level has been requested. The only way to fix this is to find out where the .pyos are and delete them.

The current method of dealing with pyo files is to include them as is, no %ghosting.

Unnecessary Byte compilation

From FC4 to current development, the automatic byte compilation of python files that is performed by brp-python-bytecompile byte compiles all files that match *.py This is undesirable for program files in %{_bindir} and %{_sbindir} because the user will probably never invoke these files, only the main program file and python won't use these files. Until the bug is resolved, there are two workarounds:

  1. Rename scripts in %{_bindir} to not have a .py extension: For instance, from /usr/bin/orient.py to /usr/bin/orient.
  2. Use %exclude to exclude the scripts from the file listing:
%files
%{_bindir}/orient.py
%exclude %{_bindir}/orient.pyc
%exclude %{_bindir}/orient.pyo

An open bug to address this issue is here: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=182498