I have a project which uses SafeConfigParser
and I want it to be Python2 and 3 compatible. Now, SafeConfigParser
is deprecated since Python 3.2 and I find the deprecation warning annoying. So I went about my business to remedy that.
First (and much older, already solved problem): SafeConfigParser
is an old-style class in Python2 so I cannot call super
in my descendant class. To have a more consistent behaviour, I wrote the following:
try:
# Python 2
class ConfigResolverBase(object, SafeConfigParser):
"""
A default "base" object simplifying Python 2 and Python 3
compatibility.
"""
pass
except TypeError:
# Python 3
class ConfigResolverBase(SafeConfigParser):
"""
A default "base" object simplifying Python 2 and Python 3
compatibility.
"""
pass
This worked fine to make the class new-style if necessary. To get rid of the DeprecationWarning
I changed the code into this:
if sys.hexversion < 0x030000F0:
# Python 2
class ConfigResolverBase(object, SafeConfigParser):
"""
A default "base" object simplifying Python 2 and Python 3
compatibility.
"""
pass
else:
# Python 3
class ConfigResolverBase(ConfigParser):
"""
A default "base" object simplifying Python 2 and Python 3
compatibility.
"""
pass
Along the way I also fixed a line I missed to change earlier:
@@ -275,7 +276,7 @@ class Config(ConfigResolverBase):
have_default = False
try:
- value = SafeConfigParser.get(self, section, option, **kwargs)
+ value = super(Config, self).get(section, option, **kwargs)
return value
except (NoSectionError, NoOptionError) as exc:
if have_default:
And that change caused an interesting error:
AttributeError: 'Config' object has no attribute '_sections'
Which let me to believe that __init__
of ConfigParser
was not called. And indeed making the following change fixed that:
- class ConfigResolverBase(object, SafeConfigParser):
+ class ConfigResolverBase(SafeConfigParser, object):
My code is now working fine for both Python 2 and 3, but whant I am unsure about is: Is the proxy returned by super
always the same?" In my case I inherit from both object
and SafeConfigParser
. Swapping the two bases in my class definition made super
return the right one. But is this guaranteed to be stable across all Python implementations on all platforms? Or should I explicitly call SafeConfigParser.get(self, ...)
? Which is after-all the "old way" of calling the base...