[Image-SIG] [Patch] PIL / setuptools compatibility

Laurence Rowe l at lrowe.co.uk
Mon Aug 23 17:12:41 CEST 2010


Hi,

Following the thread on Pillow and Zope / PIL compatibility, I think I've
found a solution that I hope will be acceptable for PIL.

Problem
=======

It's not really a Zope / PIL issue, but rather an easy_install / PIL one which
I think exposes a minor problem with PIL's setup.py which only shows up when
installing with easy_install::

    $ tmp/bin/easy_install http://effbot.org/downloads/Imaging-1.1.7.tar.gz
    ...
    Installed /data/devel/pil/tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg
    Processing dependencies for PIL==1.1.7
    Finished processing dependencies for PIL==1.1.7

We're unable to ``import PIL``::

    $ tmp/bin/python
    Python 2.6.4 (r264:75706, Jan 26 2010, 20:09:19)
    >>> import PIL
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: No module named PIL
    >>> import Image
    >>>

When the egg is created by easy_install the contents are not within a PIL
subdirectory::

    $ ls tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg
    ArgImagePlugin.py	ImageEnhance.py		PalmImagePlugin.pyc
    ArgImagePlugin.pyc	ImageEnhance.pyc	PcdImagePlugin.py
    BdfFontFile.py		ImageFile.py		PcdImagePlugin.pyc
    ...

However, if we install without easy_install we get instead::

    $ tar -zxf ~/Downloads/Imaging-1.1.7.tar.gz
    $ tmp/bin/python Imaging-1.1.7/setup.py install
    ...
    running install_lib
    creating /data/devel/pil/tmp/lib/python2.6/site-packages/PIL
    ...
    running install_egg_info
    Writing /data/devel/pil/tmp/lib/python2.6/site-packages/PIL/PIL-1.1.7-py2.6.egg-info
    creating /data/devel/pil/tmp/lib/python2.6/site-packages/PIL.pth

And don't see a problem:

    $ tmp/bin/python
    Python 2.6.4 (r264:75706, Jan 26 2010, 20:09:19)
    >>> import PIL
    >>> import Image
    >>>

Why does this happen?
=====================

To enable ``import Image`` to work, PIL's setup.py installs `Image.py` and
with the following options::

    extra_path = "PIL",
    package_dir = {"": "PIL"},
    packages = [""],

As the `PIL` directory contains an `__init__.py`, ``from PIL import Image``
also works. This is a neat distutils hack, it just doesn't work for eggs.

How can this be fixed?
======================

Instead of making a subdirectory importable by magic, we can use a trick to
install PIL.pth::

    package_data = {"PIL": ["../PIL.pth"]},

This means the PIL package can be installed normally::

    ext_package = "PIL",
    packages = ["PIL"],

Everything still ends up in the same place when you install with setup.py::

    $ tmp/bin/python pil-setuptools-compat/setup.py install
    ...
    running build_py
    ...
    creating build/lib.macosx-10.6-i386-2.6/PIL
    ...
    copying PIL/../PIL.pth -> build/lib.macosx-10.6-i386-2.6/PIL/..
    running build_ext
    ...
    running install_lib
    creating /data/devel/pil/tmp/lib/python2.6/site-packages/PIL
    ...
    copying build/lib.macosx-10.6-i386-2.6/PIL.pth ->
/data/devel/pil/tmp/lib/python2.6/site-packages

    $ tmp/bin/python
    Python 2.6.4 (r264:75706, Jan 26 2010, 20:09:19)
    >>> import PIL
    >>> import Image
    >>>

But now when we install with easy_install::

    $ tmp/bin/easy_install pil-setuptools-compat/
    ...
    Installed /data/devel/pil/tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg
    Processing dependencies for PIL==1.1.7
    Finished processing dependencies for PIL==1.1.7

The egg gets created with a PIL package::

    $ ls tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg
    EGG-INFO	PIL		PIL.pth

And we can now import PIL::

    $ tmp/bin/python
    Python 2.6.4 (r264:75706, Jan 26 2010, 20:09:19)
    >>> import PIL
    >>> import Image
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: No module named Image
    >>>

The ``import Image`` fails, because the PIL.pth is not directly in
`site-packages`. This doesn't seem to be a concern for PIL users who install
with easy_install / buildout :)

To run the tests, I copied the test script and images to another folder for
the imports to work correctly::

    $ cd pil-setuptools-compat/
    $ cp -R selftest.py Images ../tmp/
    $ cd ../tmp/
    $ bin/python selftest.py
    --------------------------------------------------------------------
    PIL 1.1.7 TEST SUMMARY
    --------------------------------------------------------------------
    Python modules loaded from
/data/devel/pil/tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg/PIL
    Binary modules loaded from
/data/devel/pil/tmp/lib/python2.6/site-packages/PIL-1.1.7-py2.6-macosx-10.6-i386.egg/PIL
    --------------------------------------------------------------------
    --- PIL CORE support ok
    --- TKINTER support ok
    --- JPEG support ok
    --- ZLIB (PNG/ZIP) support ok
    --- FREETYPE2 support ok
    *** LITTLECMS support not installed
    --------------------------------------------------------------------
    Running selftest:
    --- 57 tests passed.


Code
====

Branch and test package at http://bitbucket.org/lrowe/pil-setuptools-compat


Sorry this has got so long! I wanted to avoid misunderstandings.

Laurence
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pil-setuptools-compat.diff
Type: application/octet-stream
Size: 995 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/image-sig/attachments/20100823/6c5c017e/attachment.obj>


More information about the Image-SIG mailing list