[SSSD] [PATCHES] SSSDConfig: Port missing parts to python3

Lukas Slebodnik lslebodn at redhat.com
Thu Jan 29 10:58:52 UTC 2015


ehlo,

some parts of sssd was not properly ported to python3.
I know there were changes related to unicode, string and bytes.
I am not sure whether my patches for read and open are correct,
especially patch "SSSDConfig: os.write".

SSSDConfig (python-sssdconfig is used by authconfig and ipa-client-install?
So I don't want to break it.

Please review patches or propose better version.

LS
-------------- next part --------------
>From 675a038cf6369efde2a32f3cb0d70cf38e6c1e67 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Thu, 29 Jan 2015 09:46:27 +0100
Subject: [PATCH 1/5] SSSDConfig: Port missing parts to python3

* fix incompatible imports
* fix translation.[u]?gettext
* fix dict method has_key
* fix catching multiple exception classes
* fix octal literals PEP 3127

Resolves:
https://fedorahosted.org/sssd/ticket/2017
---
 src/config/SSSDConfig/__init__.py.in | 45 ++++++++++++++++++++----------------
 src/config/SSSDConfigTest.py         | 24 +++++++++----------
 2 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index ae00a2b7f9130725a6a766a4cbbba0a53f86dd7a..3f1597dbf5baa86bc3835c7f28edbf526f0cb4c8 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -6,9 +6,11 @@ Created on Sep 18, 2009
 
 import os
 import gettext
-import exceptions
+import sys
+if sys.version_info[0] == 2:
+    import exceptions
 import re
-from ipachangeconf import SSSDChangeConf
+from .ipachangeconf import SSSDChangeConf
 
 # Exceptions
 class SSSDConfigException(Exception): pass
@@ -32,7 +34,10 @@ PACKAGE = 'sss_daemon'
 LOCALEDIR = '/usr/share/locale'
 
 translation = gettext.translation(PACKAGE, LOCALEDIR, fallback=True)
-_ = translation.ugettext
+if sys.version_info[0] > 2:
+    _ = translation.gettext
+else:
+    _ = translation.ugettext
 
 # TODO: This needs to be made external
 option_strings = {
@@ -481,7 +486,7 @@ class SSSDConfigSchema(SSSDChangeConf):
             subtype = self.type_lookup[split_option[SUBTYPE]]
             mandatory = self.bool_lookup[split_option[MANDATORY]]
 
-            if option_strings.has_key(option['name']):
+            if option['name'] in option_strings:
                 desc = option_strings[option['name']]
             else:
                 desc = None
@@ -527,7 +532,7 @@ class SSSDConfigSchema(SSSDChangeConf):
                                      mandatory,
                                      desc,
                                      [subtype(split_option[DEFAULT])])
-                        except ValueError, KeyError:
+                        except (ValueError, KeyError):
                             raise ParsingError
                 else:
                     try:
@@ -546,7 +551,7 @@ class SSSDConfigSchema(SSSDChangeConf):
                                  mandatory,
                                  desc,
                                  primarytype(split_option[DEFAULT]))
-                    except ValueError, KeyError:
+                    except (ValueError, KeyError):
                         raise ParsingError
 
             elif optionlen > 4:
@@ -561,7 +566,7 @@ class SSSDConfigSchema(SSSDChangeConf):
                             else:
                                 newvalue = subtype(x)
                             fixed_options.extend([newvalue])
-                        except ValueError, KeyError:
+                        except (ValueError, KeyError):
                             raise ParsingError
                     else:
                         fixed_options.extend([x])
@@ -610,7 +615,7 @@ class SSSDConfigSchema(SSSDChangeConf):
             splitsection = section['name'].split('/')
             if (splitsection[0] == 'provider'):
                 if(len(splitsection) == 3):
-                    if not providers.has_key(splitsection[1]):
+                    if splitsection[1] not in providers:
                         providers[splitsection[1]] = []
                     providers[splitsection[1]].extend([splitsection[2]])
         for key in providers.keys():
@@ -674,7 +679,7 @@ class SSSDConfigObject(object):
         === Errors ===
         No errors
         """
-        if self.options.has_key(optionname):
+        if optionname in self.options:
             del self.options[optionname]
 
 class SSSDService(SSSDConfigObject):
@@ -1309,12 +1314,12 @@ class SSSDDomain(SSSDConfigObject):
         # We should now have a list of options used only by this
         # provider. So we remove them.
         for option in options:
-            if self.options.has_key(option):
+            if option in self.options:
                 del self.options[option]
 
         # Remove this provider from the option list
         option = '%s_provider' % provider_type
-        if self.options.has_key(option):
+        if option in self.options:
             del self.options[option]
 
         self.providers.remove((provider, provider_type))
@@ -1452,7 +1457,7 @@ class SSSDConfig(SSSDChangeConf):
             outputfile = self.configfile
 
         # open() will raise IOError if it fails
-        old_umask = os.umask(0177)
+        old_umask = os.umask(0o177)
         of = open(outputfile, "wb")
         output = self.dump(self.opts)
         of.write(output)
@@ -1477,7 +1482,7 @@ class SSSDConfig(SSSDChangeConf):
         if (self.has_option('sssd', 'services')):
             active_services = striplist(self.get('sssd', 'services').split(','))
             service_dict = dict.fromkeys(active_services)
-            if service_dict.has_key(''):
+            if '' in service_dict:
                 del service_dict['']
 
             # Remove any entries in this list that don't
@@ -1633,7 +1638,7 @@ class SSSDConfig(SSSDChangeConf):
         # This guarantees uniqueness and makes it easy
         # to add a new value
         service_dict = dict.fromkeys(striplist(item['value'].split(',')))
-        if service_dict.has_key(''):
+        if '' in service_dict:
             del service_dict['']
 
         # Add a new key for the service being activated
@@ -1674,11 +1679,11 @@ class SSSDConfig(SSSDChangeConf):
         # This guarantees uniqueness and makes it easy
         # to remove the one unwanted value.
         service_dict = dict.fromkeys(striplist(item['value'].split(',')))
-        if service_dict.has_key(''):
+        if '' in service_dict:
             del service_dict['']
 
         # Remove the unwanted service from the lest
-        if service_dict.has_key(name):
+        if name in service_dict:
             del service_dict[name]
 
         # Write out the joined keys
@@ -1760,7 +1765,7 @@ class SSSDConfig(SSSDChangeConf):
         if (self.has_option('sssd', 'domains')):
             active_domains = striplist(self.get('sssd', 'domains').split(','))
             domain_dict = dict.fromkeys(active_domains)
-            if domain_dict.has_key(''):
+            if '' in domain_dict:
                 del domain_dict['']
 
             # Remove any entries in this list that don't
@@ -1955,7 +1960,7 @@ class SSSDConfig(SSSDChangeConf):
         # This guarantees uniqueness and makes it easy
         # to add a new value
         domain_dict = dict.fromkeys(striplist(item['value'].split(',')))
-        if domain_dict.has_key(''):
+        if '' in domain_dict:
             del domain_dict['']
 
         # Add a new key for the domain being activated
@@ -1996,11 +2001,11 @@ class SSSDConfig(SSSDChangeConf):
         # This guarantees uniqueness and makes it easy
         # to remove the one unwanted value.
         domain_dict = dict.fromkeys(striplist(item['value'].split(',')))
-        if domain_dict.has_key(''):
+        if '' in domain_dict:
             del domain_dict['']
 
         # Remove the unwanted domain from the lest
-        if domain_dict.has_key(name):
+        if name in domain_dict:
             del domain_dict[name]
 
         # Write out the joined keys
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 5d6662a9ad5d27280bb3f48e94cc0fb071665fd6..4c4af18d35232362d664480912a9cece01ec8a63 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -748,12 +748,12 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         # Ensure that all of the expected defaults are there
         for provider in control_provider_dict.keys():
             for ptype in control_provider_dict[provider]:
-                self.assertTrue(providers.has_key(provider))
+                self.assertTrue(provider in providers)
                 self.assertTrue(ptype in providers[provider])
 
         for provider in providers.keys():
             for ptype in providers[provider]:
-                self.assertTrue(control_provider_dict.has_key(provider))
+                self.assertTrue(provider in control_provider_dict)
                 self.assertTrue(ptype in control_provider_dict[provider])
 
     def testListProviderOptions(self):
@@ -1003,7 +1003,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         # Remove the local ID provider and add an LDAP one
         # LDAP ID providers can also use the krb5_realm
         domain.remove_provider('id')
-        self.assertFalse(domain.options.has_key('id_provider'))
+        self.assertFalse('id_provider' in domain.options)
 
         domain.add_provider('ldap', 'id')
 
@@ -1020,7 +1020,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         domain.remove_provider('id')
         self.assertEquals(domain.get_option('krb5_realm'),
                   'EXAMPLE.COM')
-        self.assertFalse(domain.options.has_key('ldap_uri'))
+        self.assertFalse('ldap_uri' in domain.options)
 
         # Put the LOCAL provider back
         domain.add_provider('local', 'id')
@@ -1028,7 +1028,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
         # Remove the auth domain and verify that the options
         # revert to the backup_list
         domain.remove_provider('auth')
-        self.assertFalse(domain.options.has_key('auth_provider'))
+        self.assertFalse('auth_provider' in domain.options)
         options = domain.list_options()
 
         self.assertTrue(type(options) == dict,
@@ -1047,21 +1047,21 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
                             option)
 
         # Ensure that the krb5_realm option is now gone
-        self.assertFalse(domain.options.has_key('krb5_realm'))
+        self.assertFalse('krb5_realm' in domain.options)
 
         # Test removing nonexistent provider - Real
         domain.remove_provider('id')
-        self.assertFalse(domain.options.has_key('id_provider'))
+        self.assertFalse('id_provider' in domain.options)
 
         # Test removing nonexistent provider - Bad backend type
         # Should pass without complaint
         domain.remove_provider('id')
-        self.assertFalse(domain.options.has_key('id_provider'))
+        self.assertFalse('id_provider' in domain.options)
 
         # Test removing nonexistent provider - Bad provider type
         # Should pass without complaint
         domain.remove_provider('nosuchprovider')
-        self.assertFalse(domain.options.has_key('nosuchprovider_provider'))
+        self.assertFalse('nosuchprovider_provider' in domain.options)
 
     def testGetOption(self):
         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
@@ -1367,7 +1367,7 @@ class SSSDConfigTestSSSDConfig(unittest.TestCase):
         # Positive test - Service with invalid option loads
         # but ignores the invalid option
         service = sssdconfig.get_service('pam')
-        self.assertFalse(service.options.has_key('nosuchoption'))
+        self.assertFalse('nosuchoption' in service.options)
 
     def testNewService(self):
         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
@@ -1598,13 +1598,13 @@ class SSSDConfigTestSSSDConfig(unittest.TestCase):
         # Expected result: Domain is imported, but does not contain the
         # unknown provider entry
         domain = sssdconfig.get_domain('INVALIDPROVIDER')
-        self.assertFalse(domain.options.has_key('chpass_provider'))
+        self.assertFalse('chpass_provider' in domain.options)
 
         # Positive Test - Domain with unknown option
         # Expected result: Domain is imported, but does not contain the
         # unknown option entry
         domain = sssdconfig.get_domain('INVALIDOPTION')
-        self.assertFalse(domain.options.has_key('nosuchoption'))
+        self.assertFalse('nosuchoption' in domain.options)
 
     def testNewDomain(self):
         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
-- 
2.1.0

-------------- next part --------------
>From 317701400d1b5f0491eb4417180b6b09c3e1e9b6 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Thu, 29 Jan 2015 09:48:28 +0100
Subject: [PATCH 2/5] SSSDConfig: long is not defined in python3

---
 src/config/SSSDConfig/__init__.py.in | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 3f1597dbf5baa86bc3835c7f28edbf526f0cb4c8..ae9dd92cdeaa6dd5706c1e185552f7aade80fa3e 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -451,12 +451,16 @@ class SSSDConfigSchema(SSSDChangeConf):
         self.type_lookup = {
             'bool' : bool,
             'int'  : int,
-            'long' : long,
+            'long' : None,
             'float': float,
             'str'  : str,
             'list' : list,
             'None' : None
             }
+        if sys.version_info[0] > 2:
+            self.type_lookup['long'] = int
+        else:
+            self.type_lookup['long'] = long
 
         # Lookup table for acceptable boolean values
         self.bool_lookup = {
-- 
2.1.0

-------------- next part --------------
>From c92eb286f569373aa43b945720ddffed2a33ae34 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Wed, 28 Jan 2015 18:42:35 +0100
Subject: [PATCH 3/5] SSSDConfig: os.write

Traceback (most recent call last):
  File "../src/config/SSSDConfigTest.py", line 1763, in testSaveDomain
    sssdconfig.write(of)
  File "./src/config/SSSDConfig/__init__.py", line 1467, in write
    of.write(output)
TypeError: 'str' does not support the buffer interface
---
 src/config/SSSDConfig/__init__.py.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index ae9dd92cdeaa6dd5706c1e185552f7aade80fa3e..fa861495e027f6726bde051cbae4da5c24481640 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -1462,7 +1462,7 @@ class SSSDConfig(SSSDChangeConf):
 
         # open() will raise IOError if it fails
         old_umask = os.umask(0o177)
-        of = open(outputfile, "wb")
+        of = open(outputfile, "w")
         output = self.dump(self.opts)
         of.write(output)
         of.close()
-- 
2.1.0

-------------- next part --------------
>From 1406720107ef807aed764b47feba8e023e085daf Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Thu, 29 Jan 2015 10:32:23 +0100
Subject: [PATCH 4/5] sbus_codegen: Port to python3

Resolves:
https://fedorahosted.org/sssd/ticket/2017
---
 src/sbus/sbus_codegen | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index d2de58552b8de5bc6178e7a895d3494515680112..a51b323eb4684bf80c424712c5ea19a8d341483c 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -60,14 +60,19 @@
 #    to generate for a given interface or method. By default the codegen will
 #    build up a symbol name from the DBus name.
 #
+from __future__ import print_function
 
 import optparse
 import os
 import re
-import StringIO
 import sys
 import xml.parsers.expat
 
+if sys.version_info[0] > 2:
+    import io
+else:
+    import StringIO as io
+
 # -----------------------------------------------------------------------------
 # Objects
 
@@ -767,11 +772,11 @@ class DBusXMLParser:
         try:
             with open(filename, "r") as f:
                 parser.ParseFile(f)
-        except DBusXmlException, ex:
+        except DBusXmlException as ex:
             ex.line = parser.CurrentLineNumber
             ex.file = filename
             raise
-        except xml.parsers.expat.ExpatError, ex:
+        except xml.parsers.expat.ExpatError as ex:
             exc = DBusXmlException(str(ex))
             exc.line = ex.lineno
             exc.file = filename
@@ -895,11 +900,11 @@ def parse_options():
     (options, args) = parser.parse_args()
 
     if not args:
-        print >> sys.stderr, "sbus_codegen: no input file specified"
+        print("sbus_codegen: no input file specified", file=sys.stderr)
         sys.exit(2)
 
     if options.mode not in ["header", "source"]:
-        print >> sys.stderr, "sbus_codegen: specify --mode=header or --mode=source"
+        print("sbus_codegen: specify --mode=header or --mode=source", file=sys.stderr)
 
     return options, args
 
@@ -907,7 +912,7 @@ def main():
     options, args = parse_options()
 
     if options.output:
-        sys.stdout = buf = StringIO.StringIO()
+        sys.stdout = buf = io.StringIO()
 
     for filename in args:
         parser = DBusXMLParser(filename)
@@ -928,6 +933,6 @@ def main():
 if __name__ == "__main__":
     try:
         main()
-    except DBusXmlException, ex:
-        print >> sys.stderr, str(ex)
+    except DBusXmlException as ex:
+        print(str(ex), file=sys.stderr)
         sys.exit(1)
-- 
2.1.0

-------------- next part --------------
>From 316cdd9322ed64ea2b3b4477800b1ecf5adf5b16 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Thu, 29 Jan 2015 11:16:13 +0100
Subject: [PATCH 5/5] sbus_codegen: open

Traceback (most recent call last):
  File "../src/sbus/sbus_codegen", line 935, in <module>
    main()
  File "../src/sbus/sbus_codegen", line 918, in main
    parser = DBusXMLParser(filename)
  File "../src/sbus/sbus_codegen", line 774, in __init__
    parser.ParseFile(f)
TypeError: read() did not return a bytes object (type=str)
---
 src/sbus/sbus_codegen | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index a51b323eb4684bf80c424712c5ea19a8d341483c..ceaf26c82515ad2741d308e8a7769e09a367ac6e 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -770,7 +770,7 @@ class DBusXMLParser:
         self.arg_count = 0
 
         try:
-            with open(filename, "r") as f:
+            with open(filename, "rb") as f:
                 parser.ParseFile(f)
         except DBusXmlException as ex:
             ex.line = parser.CurrentLineNumber
-- 
2.1.0



More information about the sssd-devel mailing list