1

I want to pickle and unpickle a GdkPixbuf.Pixbuf in Python3. To be more specific the multiprocessing package of Python3 need to do it because I share such objects between process via a Queue.

The problem is that the object changes from

<GdkPixbuf.Pixbuf object at 0x7f8b9e9cfb88 (GdkPixbuf at 0x563b61725c60)>

to

<GdkPixbuf.Pixbuf object at 0x7f8b9e9eaea0 (uninitialized at 0x(nil))>

That is the minimal working example.

>>> import gi
>>> from gi.repository import GdkPixbuf
__main__:1: PyGIWarning: GdkPixbuf was imported without specifying a version first. Use gi.require_version('GdkPixbuf', '2.0') before import to ensure that the right version gets loaded.

>>> pf = GdkPixbuf.Pixbuf.new_from_file('_icon.png')
>>> pf
<GdkPixbuf.Pixbuf object at 0x7f8b9e9cfb88 (GdkPixbuf at 0x563b61725c60)>

>>> import pickle
>>> pickle.dump(pf, open('p', 'wb'))

>>> pb2 = pickle.load(open('p', 'rb'))
>>> pb2
<GdkPixbuf.Pixbuf object at 0x7f8b9e9eaea0 (uninitialized at 0x(nil))>

I see no other way to pickle. The icon need to be loaded in a separate process (on a different CPU core then the applications main/first process) and then should be transfered to the main process. This is done via a Queue which pickles all data.

buhtz
  • 10,774
  • 18
  • 76
  • 149
  • Relevant [cant-pickle-type-instancemethod-when-using-multiprocessing](https://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when-using-multiprocessing-pool-map) – stovfl May 19 '19 at 14:30

1 Answers1

0

My solution is holding the "icon" not as a Pixbuf object in memory but as raw bytes I read from the file.

After unpickling this bytes I convert them to a Pixbuf.

>>> import gi
>>> from gi.repository import GdkPixbuf, Gio, GLib
__main__:1: PyGIWarning: GdkPixbuf was imported without specifying a version first. Use gi.require_version('GdkPixbuf', '2.0') before import to ensure that the right version gets loaded.
>>> with open('_icon.png', 'rb') as f:
...     icon_bytes = f.read()
... 
>>> 
>>> import pickle
>>> pickle.dump(icon_bytes, open('p', 'wb'))
>>> 
>>> pb = pickle.load(open('p', 'rb'))
>>> pb = GLib.Bytes(pb)
>>> pb = GdkPixbuf.Pixbuf.new_from_stream(Gio.MemoryInputStream.new_from_bytes(pb))
>>> pb
<GdkPixbuf.Pixbuf object at 0x7fc0858ac5e8 (GdkPixbuf at 0x55e0d8d08b60)>
buhtz
  • 10,774
  • 18
  • 76
  • 149