Kodi Community Forum

Full Version: Anyone else finding the new settings class unreliable?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
There's no consistency in these types of errors, their occurrence is random. No issues manifest with the old getSetting/getSettingInt methods.

Code:

EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
- NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
Error Type: <class 'TypeError'>
Error Contents: Invalid setting type "integer" for "registration_server_port"
Traceback (most recent call last):
 File "C:\Users\Jay\AppData\Roaming\Kodi\addons\plugin.dbmc\service.py", line 15, in <module>
   server = ThreadedHTTPServer(("", port), RequestHandler)
 File "C:\Users\Jay\AppData\Roaming\Kodi\addons\plugin.dbmc\resources\lib\oauth\register.py", line 28, in __init__
   while ADDON_SETTINGS.getInt("registration_server_port") != self.server_port and not monitor.abortRequested():
TypeError: Invalid setting type "integer" for "registration_server_port"

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
 File "C:\Users\Jay\AppData\Roaming\Kodi\addons\plugin.dbmc\service.py", line 17, in <module>
   server = ThreadedHTTPServer(("", 0), RequestHandler)
 File "C:\Users\Jay\AppData\Roaming\Kodi\addons\plugin.dbmc\resources\lib\oauth\register.py", line 28, in __init__
   while ADDON_SETTINGS.getInt("registration_server_port") != self.server_port and not monitor.abortRequested():
TypeError: Invalid setting type "integer" for "registration_server_port"
-->End of Python script error report<--

I get the above error inconsistently when the data in my settings.xml file looks like this.

Code:

<settings version="2">
    <setting id="file_filter" default="true">true</setting>
    <setting id="cache_path">C:\Users\Jay\Documents\DBMC\</setting>
    <setting id="stream_media" default="true">true</setting>
    <setting id="files_per_batch" default="true">5</setting>
    <setting id="registration_server_port">49875</setting>
    <setting id="notify_server_port">52828</setting>
</settings>


This is how I initialize the settings object and how I call its methods:

Code:

ADDON = xbmcaddon.Addon("plugin.dbmc")
ADDON_SETTINGS = ADDON.getSettings()
ADDON_SETTINGS.getInt("registration_server_port")
is it more consistent if you put the type in your setting?

Code:
<setting id="registration_server_port" type="number">49875</setting>
I concur with setting the type.  I have a number of addons with over a hundred settings and have not experienced this but I set the type for each one. 

I also use the getSetting method in a single function across my addons, whether from the service.py or main addon file:

Settings function:
def settings(setting, value = None):
    # Get or add addon setting
    if value:
        xbmcaddon.Addon().setSetting(setting, value)
    else:
        return xbmcaddon.Addon().getSetting(setting)  

getSetting has worked  for all setting types I have tried.


Thanks,

Jeff
(2023-11-14, 17:22)jbinkley60 Wrote: [ -> ]getSetting has worked  for all setting types I have tried.

i do agree it would be better to handle type conversions within python instead of asking getInt to do it, at minimum i like the control that affords

ex:

python:
setting = getSetting(...)
try:
    setting = int(setting)
except:
    setting = 0
I always set type and also localized label attributes.  Haven't had any problems.  Help attribute is optional but I add it with empty string.

scott s.
.
Sorry, I should have been clearer. The setting.xml is the file created by Kodi - what the addon reads from.The one I created is this: https://github.com/JDRIVO/DBMC/blob/main...ttings.xml

The error isn't confined to getInt, it happens with getString too.

Code:

2023-11-14 06:13:07.683 T:8992    error <general>: self._cache = DropboxCache(account_name)
2023-11-14 06:13:07.683 T:8992    error <general>:   File "C:\Kodi\portable_data\addons\plugin.dbmc\resources\lib\dropbox_cache.py", line 29, in __init__
2023-11-14 06:13:07.699 T:8992    error <general>: cache_path = get_cache_path(account_name)
2023-11-14 06:13:07.699 T:8992    error <general>:   File "C:\Kodi\portable_data\addons\plugin.dbmc\resources\lib\utils.py", line 55, in get_cache_path
2023-11-14 06:13:07.705 T:8992    error <general>: data_path = ADDON_SETTINGS.getString("cache_path")
2023-11-14 06:13:07.705 T:8992    error <general>: TypeError
2023-11-14 06:13:07.705 T:8992    error <general>: Invalid setting type "string" for "cache_path"
same answer, use getsetting and do type conversions in your own code
(2023-11-15, 16:53)izprtxqkft Wrote: [ -> ]same answer, use getsetting and do type conversions in your own code

Yep, that's the path I'll have to take if I'm not doing anything incorrect to cause these issues. And in that case, it would still be ideal to have these issues addressed as the old methods are due to be phased out in the next release.
(2023-11-15, 17:11)SEIKT Wrote: [ -> ]
(2023-11-15, 16:53)izprtxqkft Wrote: [ -> ]same answer, use getsetting and do type conversions in your own code

Yep, that's the path I'll have to take if I'm not doing anything incorrect to cause these issues. And in that case, it would still be ideal to have these issues addressed as the old methods are due to be phased out in the next release.

That will need tog et sorted out.  The big advantage of the getSetting approach is leveraging a single function to get all settings vs. individual calls, which the sate isn't shared across instances.  See this thread.


Thanks,

Jeff
Cheers for the feedback gents. This is the approach I took. I only had to change one line of code.

Code:

class Settings:

    def __init__(self, addon):
        self._addon = addon

    def _getSetting(self, id):
        return self._addon.getSetting(id)

    def getString(self, id, default=None):
        value = self._getSetting(id)

        if value:
            return value
        else:
            return default

    def getBool(self, id, default=None):
        value = self._getSetting(id)

        if value:
            return value == "true"
        else:
            return default

    def getInt(self, id, default=None):

        try:
            return int(self._getSetting(id))
        except ValueError:
            return default