Search code examples
pythonpython-imaging-libraryintrospection

How can I use introspection to get Python to tell me more about PIL ImagingCore objects?


Something I'm doing in PIL is giving me back an object of a class I don't recognize. It may be a fairly thin wrapper around a C data structure or something. How can I get Python to tell me where to look for more information?

Here are some failed attempts to use introspection to learn more:

>>> import os, PIL
>>> obj = PIL.Image.open(os.path.expanduser("~/Desktop/foo.png")).getdata()
>>> type(obj)
<type 'ImagingCore'>
>>> ImagingCore
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ImagingCore' is not defined
>>> PIL.ImagingCore
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ImagingCore'
>>> obj.__class__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __class__
>>> obj.__module__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __module__
>>> import inspect
>>> inspect.getsource(obj)
...
TypeError: <ImagingCore object at 0x105e64b50> is not a module, class, method, function, traceback, frame, or code object
>>> inspect.getsource(type(obj))
...TypeError: <module '__builtin__' (built-in)> is a built-in class
>>>

Solution

  • PIL's core functionality is implemented in module _imaging, written, as you guessed, in the C language -- see _imaging.c (3281 lines...:-) in the top level source directory, Imaging-1.1.7. That code doesn't pay any attention to introspection -- rather, it's 100% focused on performance. I believe it doesn't even bother to expose anything but functions (it does implement several types, including ImagingCore, but doesn't even expose those types' names to Python -- only generates and uses them internally).

    So Python won't tell you where to look for more info because the library, in turn, doensn't tell Python:-). As the docs for getdata at http://effbot.org/imagingbook/image.htm says:

    Note that the sequence object returned by this method is an internal PIL data type, which only supports certain sequence operations, including iteration and basic sequence access. To convert it to an ordinary sequence (e.g. for printing), use list(im.getdata())

    ...and "that's all she wrote" -- nothing but that small subset of sequence operations gets exposed.