On Sat, Feb 23, 2002 at 10:38:17AM +1100, Donovan Baarda wrote: > On Tue, Feb 12, 2002 at 12:05:22AM +0100, Bastian Kleineidam wrote: > > Hello. > > > > The first version of the python-central package is online at > > http://people.debian.org/~calvin/python-central/ > > > > It provides support for installing pure Python modules independent > > of the Python version (see Python Policy 2.2.3). [...] > Did you see my analysis and modified "register-python-package" script? I > posted it under a misleading subject by mistake (responded to another thread > that migrated onto it).
OK, I got creative and figured out a way the python-central could work without using an emac's style registry, instead just using the existing dpkg "Depends:" information. This new version of register-python-package has shrunk to under 180 lines, and is much simplified over the original. The usage has been reduced to; usage: ./register-python-package {configure|remove} <package name> It will determine if it is configure/removing a python version or python module from the package name. Any package that contains *.py files in /usr/lib/python/site-packages is assumed to be multi-version python module. The versions of python that a multi-version python module supports is determined by the "pythonX.Y" entries in the package's "Depends:". An example for a python-foo module that works for python version 1.5->2.1 would have the following dependancies; Depends: python1.5 | python1.6 | python2.0 | python2.1, python-central Any python package with python-central support, including pythonX.Y packages, would call in it's postinst; register-python-package configure <package-name> and in its prerm would call; register-python-package remove <package-name> For a pythonX.Y package, installing will symlink and compile all modules with files in /usr/lib/python/site-packages that have compable dependancies. For a python-foo package, installing will symlink and compile the module for all installed and compatible python versions. Removing will do the correct inverse. Comments welcome. This one is a bit more tested than the last. -- ---------------------------------------------------------------------- ABO: finger [EMAIL PROTECTED] for more info, including pgp key ----------------------------------------------------------------------
#!/bin/sh # the python registrar # directory with registered packages CENTRAL=/var/lib/python-central # python command to byte-compile a file BYTECOMP="import sys,py_compile;py_compile.compile(sys.argv[1],sys.argv[2])" # directory for installed .py files IN=/usr/lib/python/site-packages # get_modules <pythonX.Y package> # return installed multi-version python packages that work for the # specified python package get_modules() { PYTHONXY=$1 RET="" for p in `dpkg -S /usr/lib/python/site-packages 2>/dev/null | sed 's#,\|:.*$##g'`; do if dpkg -s $p | egrep "^Depends:.* $PYTHONXY([ ,]|$)" >/dev/null 2>&1; then RET="$RET $p" fi done } # get_versions <package name> # return installed versions of python supported by the python package get_versions () { DEPENDS=`dpkg -s $1 | grep "^Depends:" | cut -d: -f2` RET="" for PYTHONXY in `ls /usr/bin/python?.? | cut -c 10-`; do if echo "$DEPENDS" | egrep " $PYTHONXY([ ,]|$)" >/dev/null 2>&1; then RET="$RET $PYTHONXY" fi done } # module_compile <package name> <pythonX.Y package> # symlinks and compiles a package for the specified python version module_compile () { PACKAGE=$1 PYTHONXY=$2 PYTHON=/usr/bin/$PYTHONXY OUT=/usr/lib/$PYTHONXY/site-packages # look for .py files in the package for i in `dpkg --listfiles $PACKAGE | grep "^$IN/.*\.py$" | sed "s#^$IN/##"`; do # install potentially missing (sub)directories DIRNAME=`dirname $OUT/$i` install -d -o root -g root -m 0755 $DIRNAME # make relative link REL="../.." while [ $DIRNAME != $OUT ]; do REL=../$REL DIRNAME=`dirname $DIRNAME` # prevent infinite loops if [ "$DIRNAME" = "/" -o "$DIRNAME" = "." ]; then exit 1 fi done # REL points to /usr/lib now ln -sf $REL/python/site-packages/$i $OUT/$i # byte-compile package .py files $PYTHON -O -c "$BYTECOMP" $OUT/$i $OUT/${i}o $PYTHON -c "$BYTECOMP" $OUT/$i $OUT/${i}c # fix output file mode chmod 0644 $OUT/${i}[co] || true done } # module_clean <package name> <pythonX.Y package> # removes symlinks and bytecode of a package for the specified python version module_clean() { # remove symlink and byte-compiled files PACKAGE=$1 PYTHONXY=$2 OUT=/usr/lib/$PYTHONXY/site-packages for i in `dpkg --listfiles $PACKAGE | grep "^$IN/.*\.py$" | sed "s#^$IN/##"`; do rm -f $OUT/$i $OUT/${i}c $OUT/${i}o done # remove directories for i in `dpkg --listfiles $PACKAGE | grep "^$IN/" | sort -r | sed "s#^$IN/##"`; do if [ -d $OUT/$i ]; then rmdir $OUT/$i || true fi done } # module_configure <package name> # configure a module for all supported installed python versions module_configure () { PACKAGE=$1 get_versions $PACKAGE versions=$RET for pyver in $versions; do module_compile $PACKAGE $pyver done } # module_remove <package name> # remove a configured module for all supported installed python versions module_remove () { PACKAGE=$1 get_versions $PACKAGE versions=$RET for pyver in $versions; do module_clean $PACKAGE $pyver done } # python_configure <pythonX.Y package> # byte-compile this python version plus all supported packages python_configure () { PYTHONXY=$1 PYTHON=/usr/bin/$PYTHONXY PYLIBS=/usr/lib/$PYTHONXY # byte-compile all python files $PYTHON -O $PYLIBS/compileall.py -q $PYLIBS $PYTHON $PYLIBS/compileall.py -q $PYLIBS # byte-compile registered packages get_modules $PYTHONXY modules=$RET for p in $modules; do module_compile $p $PYTHONXY done } # python_remove <pythonX.Y package> # remove byte-compiled files for this python version and for all # supported python packages python_remove () { PYTHONXY=$1 PYTHON=/usr/bin/$PYTHONXY # remove byte-compiled files for this python version dpkg --listfiles $PYTHONXY | awk '$0~/\.py$/ {print $0"c\n" $0"o"}' | xargs rm -f >&2 # remove registered packages get_modules $PYTHONXY modules=$RET for p in $modules; do module_clean $p $PYTHONXY done } usage () { echo "usage: $0 {configure|remove} <package name>" exit 1 } ############################################################### ################ main ########################## ############################################################### action=$1 if echo $2 | egrep '^python[0-9]\.[0-9]$' >/dev/null 2>&1; then mode="python" else mode="module" fi if [ "$action" = "configure" ]; then ${mode}_configure $2 elif [ "$action" = "remove" ]; then ${mode}_remove $2 else usage fi