Handling 'NotifyingList' tag type and pickling ?

Asked by Ingo Breßler

Hello everyone,

I like the python bindings for exiv2 and I'm on the way writing a small GUI for copying individual tags between files. That's when a problem arose: How to serialize a tag, e.g. pyexiv2.exif.ExifTag ?

The simplest way would be to stuff a pyexiv2.exif.ExifTag into a QTreeWidgetItem as QVariant data payload. But it doesn't seem to support pickling:
"RuntimeError: Pickling of "libexiv2python._ExifTag" instances is not enabled (http://www.boost.org/libs/python/doc/v2/pickle.html)"
I'm not a python expert, so I don't know if I can 'enable' this easily somehow.

My next thought was: Ok, the ExifTag constructor allows me to reconstruct a tag just from its value which is a regular python object. This works well for most tags (pyexiv2.utils.Rational can be converted from and to string via the API) except for 'NotifyingList' tag types. The GPS tags of my Samsung WB650 are of this type ...

This type is not in the API docs ( http://tilloy.net/dev/pyexiv2/api.html#module-pyexiv2.utils ) and after looking into the code I wondered what its listeners are used for ? Just because, as I thought until now, tags are some static text snippets within an image file. Additionally, in my GPS tags there is just one listener which seems to be a reference to this tag itself.

Therefore, one part of my question is also: What do I break if I reconstruct the NotifyingList without listeners afterwards ?

Thanks and best regards,
[ I'm using pyexiv2-0.2.2 with python-2.6.5, pyqt-4.7.2 and qt-4.6 on ubuntu 10.04. ]

Question information

English Edit question
pyexiv2 Edit question
No assignee Edit question
Solved by:
Olivier Tilloy
Last query:
Last reply:
Revision history for this message
Best Olivier Tilloy (osomon) said :

Hi Ingo,

As you found out, your best option to serialize a tag is to pickle a tuple (key, value), which will allow to reconstruct the tag later. Pickling an {Exif,Iptc,Xmp}Tag itself is not directly possible at the moment, but it would be a nice enhancement. Could you please file a bug report to track this request?

As for the NotifyingList class, it’s not documented because it’s meant to be completely transparent to the application developer: it’s a list that can notify any listener connected to it of changes to its values (which standard python lists can’t do). The benefit of such a mechanism is that it allows application developers to write something like this:

    tag.value[1] = Rational(10, 3)

(supposing that tag.value is a list of Rationals)
With a standard python list the change wouldn’t be propagated to the tag itself, and the new value wouldn’t be written.

Now, since the purpose is to be completely transparent to application developers, constructing a tag from a standard list of values will automatically turn it into a NotifyingList, so the answer to your last question is: you’re not breaking anything by reconstructing a tag from a standard list of values.

However I’m not sure I understand what you’re trying to achieve: a NotifyingList can be pickled just like a normal list, so you shouldn’t be worrying about conversions in the first place. Or did I misunderstand your question?

Revision history for this message
Olivier Tilloy (osomon) said :

Another (more reliable) way of serializing tags is to pickle their raw value (it’s guaranteed to always be a string, it’s the value of the tag as stored in the image file). Here’s how to do that:

Serialize a tag:

    s = pickle.dumps((tag.key, tag.raw_value))


    (key, raw_value) = pickle.loads(s)
    tag = pyexiv2.ExifTag(key)
    tag.raw_value = raw_value

Is that what you were looking for?

Revision history for this message
Ingo Breßler (ibressler) said :

Thanks Olivier Tilloy, that solved my question.