Python Interpreter Bug
#1
I've discovered a bug in Kodi Python. If a function has kwargs but you call the function with some positional values followed by kwargs, the interpreter declares an error stating that too many arguments were given.

The class definition:

class RowItem(xbmcgui.ControlGroup):

def init(self, X=0, Y=0, width=380 , height=280, bgdSegmented=False, textColor='0xFFFFFF00',

bgdColor='0xFFFF0000', alignment=JUSTIFY_CENTER, font='font12'):

Code instantiating the class:

item = RowItem(X,rowY,width,height,bgdSegmented=False,bgdColor='0xFFFF00FF',

alignment=0)

Error message in the log:

"/storage/.kodi/addons/service.ltvpl/addon.py", line 198, in PlaylistConstructor

alignment=0)

TypeError: function takes at most 4 arguments (7 given)

Clearly, all of the arguments defined in init are kwargs except the first. Why did Kodi Python think that there are 4 positional parameters and why did it reject the kw parameters as being excessive? In order to get the code to run, I had to eliminate the kwargs when instantiating the class. Obviously, doing that is not a proper solution.

By the way I specified xbmc.python version 2.24.0 in my addon.xml file.

In the for what it's worth department, I ran a modified version of the above code under Linux (Python 2.7.13) on the same system Kodi is running on and did not get any errors at all.

Has

Has anyone else experienced this bug?
Reply
#2
Please properly format your code because now it's unreadable. And please provide the full code.
Reply
#3
I apologize for not providing a properly formatted code snippet.
I am providing a link to pastebin for the code snippet:
https://pastebin.com/CFe7DZiN

When I ran the code snippet under Linux, the only modification done was the elimination of inheriting from xbmcgui.ControlGroup.
Reply
#4
I didn't mean copy-pasting your original post to another site. Please use forum capabilities to properly format your code and please provide more extended snippet. And if the code:
python:

import xbmcgui

USTIFY_CENTER = 2

class RowItem(xbmcgui.ControlGroup):  
    def __init__(self, X=0, Y=0, width=380 , height=280, bgdSegmented=False, textColor='0xFFFFFF00', bgdColor='0xFFAA0000', alignment=JUSTIFY_CENTER, font='font12'):
        pass

is indeed your full code then you need to call your parent class constructor and probably override __new__ method as well. Instantiating Python classes derived from C-based classes is not that simple.

BTW, what you are trying to accomplish with CongrolGroup? I'm not even sure that it works at all.
Reply
#5
I did more extensive testing with this code: https://pastebin.com/4fWNFADY

I imported the file into an existing addon and called each of the three tests one at a time.
Please note that you can only run test at a time.

The tests I created are as follows:
  test1: uses a version of RowItem that inherits from xbmcgui.ControlGroup
  I did not initialize the base class
  I got the error stating that RowItem only takes at most 4 arguments (7 given)

  test2: uses a version of RowItem that does not inherit from a base class.
  I did not get an error

  test3: uses a version of RowItem that inherits from xbmcgui.ControlGroup
  I initialized the base class per your suggestion.
  I got the error stating that RowItem only takes at most 4 arguments (7 given)

As you can see, even calling the base class' __inti__ function as you suggested did not alter the outcome.
You have to run the above tests from within an existing addon one at a time to replicate my results.
I also noted that the base class, xmbcgui.ControlGroup, has only positional parameters.

It is clear to me that Kodi Python falsely assumes that the parameters of a subclass are identical to the base class parameters, which is the source of the problem I've experienced. This bug has the potential to reek havoc if one utilizes multiple inheritance since it would be confusing as to which class' parameters should be used to evaluate subclass parameters.

I hope this is enough information to verify this anomaly.
Reply
#6
This is not an anomaly. As I said, instantiating Python classes that inherit from C-based classes is not that simple, because the latter need to be constructed and initialized explicitly. However, for the "new" Python classes construction and initialization are separated, and calling __init__ alone is not enough. There's also __new__ class method that is a constructor proper, and Python calls both with the same set of parameters, that is why you are getting this error.

So in your case you need to implement both methods like that:

python:
import xbmcgui


class Foo(xbmcgui.ControlGroup):
    def __new__(cls, x=0, y=0, width=380 , height=280, bgdSegmented=False,
            textColor='0xFFFFFF00', bgdColor='0xFFAA0000',
            alignment=JUSTIFY_CENTER, font='font12'):
        return super(xbmcgui.ControlGroup, cls).__new__(x, y, width, height)

    def __init__(self, x=0, y=0, width=380 , height=280, bgdSegmented=False,
            textColor='0xFFFFFF00', bgdColor='0xFFAA0000',
            alignment=JUSTIFY_CENTER, font='font12'):
        super(xbmcgui.ControlGroup, self).__init__(x, y, width, height)

However, as I said, I don't understand what you are trying to do with ControlGroup. This class is obviously broken because it does not provide any useful methods of its own.
Reply
#7
Thank you for the explanation.
I wondered why my own base classes worked but this particular case did not.
My intent with this code was to extend the controlGroup class to contain a list of controls since the base class had no methods for doing so.
Reply

Logout Mark Read Team Forum Stats Members Help
Python Interpreter Bug0