I know this is a
very old post, but... since there will be a lot of
Python-converting happening in the coming years, it's worth documenting these kinds of issues and the reasons behind them. (Fair warning, up front: This is going to get a bit into the
Python weeds. I'll drop a TL;DR at the end for those who don't care about the hows and whys.)
The problem with the auto-conversion Herbie was provided is that it assumes the object being accessed (in this case,
shelf) is an instance of a standard
Python collection datatype (a
dict), with all of the appropriate methods defined for an object of that type.
Unfortunately, in this case,
shelf is an instance of
Gimpshelf (which can be found at the gimp repository in the file
gimp/plugins/pygimp/gimpshelf.py), and
Gimpshelf is NOT a complete implementation of the
Python dict interface.
In particular,
Gimpshelf implements
has_key() (a
Python 2 method used to determine whether a key is present in a
dict), and it implements the
Python standard
__getitem__,
__setitem__, and
__delitem__ methods for manipulating the contents of the collection. But that's ALL — it's not a subclass of any standard
Python type, so it doesn't have any of the other standard methods.
The
in operator, in particular, has several methods for determining whether an item is a member of a collection. As each preferred method fails, it falls back on less efficient/compatible alternatives.
•
in looks first for a
__contains__ method, which it can call to request a direct answer to the question "do you contain this item?"
Gimpshelf doesn't provide
__contains__.
•
in then falls back to trying an
__iter__ method, which will produce each of the member items in sequence so it can compare them to its target item. If any of them match, the result is
True.
Gimpshelf doesn't provide
__iter__.
• As a last resort,
in falls back to trying
__getitem__,
which it calls using increasing numerical indices, attempting to find an index i for which shelf[i] == target. Since
Gimpshelf provides
__getitem__ and
only __getitem__, of the methods
in supports, it's using it to attempt to access the keys of
shelf via numerical indices — something
shelf does not support. That's why you're seeing
__getitem__ calling
gimp.get_data() with numerical arguments.
TL;DR: Because
shelf is not a
Python standard data type, but rather a Gimp class which itself hasn't been upgraded for
Python 3, you should continue to use
shelf.has_key() to examine its contents. Attempting to switch to the unsupported (for that class, regardless of
Python version)
in operator will lead to unsupported uses of the class's interface.
The interface provided by any datatypes implemented by Gimp code (rather than in
Python itself) won't change simply by running them in
Python 3. Until such changes are made, the code to access them shouldn't be "upgraded".
This would be a correct
Python 3 version of the OP's snippet, when accessing an unmodified pygimp
Gimpshelf instance:
def pluginGestartet():
if (shelf.has_key(pluginName) and shelf[pluginName]):
return True
return False
(Yes, it's unchanged from the original. The original code was already
Python 3 compatible.)
Or, as ofnuts suggested, it could be streamlined as
def pluginGestartet():
return shelf.has_key(pluginName) and shelf[pluginName]
But you need to keep using
shelf.has_key() until such time as the
Gimpshelf code itself is upgraded.