GIMP2.99: How to use image.attach_parasite in a python3 plugin?

Unstable Development Version commit a0811ff, for Windows.
I’m still working on my Python3 plug-in for GIMP 2.99. I create a Parasite with some uuid-based strings, and then try to attach it to an image object. The parasite data is unimportant. I just want to tag “some” open images with some data, so that I can tell which open images my plug-in is working on.
But attempts to attach parasites to images fail with an error. The error seems to be some kind of out-of-range issue.
Here is a snipit:

        # See ...gimp_world/gimp/libgimpbase/gimpparasite.h
        #  and https://developer.gimp.org/api/3.0/libgimp/struct.Parasite.html
        iterator_parasite_out = Gimp.Parasite(name=PatientIterator.PARASITE_ITERATION_NAME+"_"+str(uuid.uuid4()),
                                              flags=Gimp.PARASITE_UNDOABLE,
                                              data=self.job_uuid)
        """
        I can't find parameter docs for image.attach_parasite(), I am guessing at the args.
         See .../gimp/devel-docs/GIMP3-plug-in-porting-guide/removed_functions.md        
        """
        """
            GIMP-Error: Calling error for procedure 'gimp-image-attach-parasite':
            Procedure 'gimp-image-attach-parasite' has been called with value '<not transformable to string>' for 
            argument 'parasite' (#2, type GimpParasite). This value is out of range.        
        """
        image.attach_parasite(parasite=iterator_parasite_out)  # Works on first image, then fails.

Tweaking the arguments to the Parasite constructor has not helped so far. I have tried making the names unique, the data unique, omitting the flag, etc. Am I doing something wrong, or might this be a bug?

In modern GObject code, it is not recommended to use non-default constructors anymore, but in libgimp, it is not only recommended, but very often you must absolute use our custom constructors and not the default ones. It may or may not change before GIMP 3.0 release (it is not so easy because we also have several objects linked to core objects which make matters a bit more complicated to handle). Anyway, bottom line: don’t use Gimp.Parasite() but Gimp.Parasite.new().

Also the parasite structure is still a part I want to further review, but so far here is how it works: one of the point of parasite is that it’s not a string. Though you can set a string in parasite, and it’s undoubtedly the most common use case, it’s actually binary data. It’s just bytes of a given size (up to you to give it meaning).

With this in mind, how I create parasite in one of my own scripts:

iterator_parasite_out = Gimp.Parasite.new(PatientIterator.PARASITE_ITERATION_NAME+"_"+str(uuid.uuid4()),
                                          Gimp.PARASITE_UNDOABLE,
                                          list(self.job_uuid.encode('utf-8')))

Here I am assuming that self.job_uuid was a string. Obviously if it’s already bytes, don’t bother encoding.

Obviously it means that when you’ll want to grab data out of your parasite, you’ll do the opposite:

parasite = image.get_parasite(PatientIterator.PARASITE_ITERATION_NAME+"_"+str(uuid.uuid4()))
uuid = bytes(parasite.get_data()).decode('utf-8')

Please try this and tell us if it’s better.

Yes, that helped! No apparent errors on addition.
Thanks!

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.