Hello,
Here are some more Python3 patches. Most are pretty routine, but pay
special attention to the first and last patch.


With these patches, running the in-tree test suite gives me the same
errors in Python 2 and Python 3, except:
- test_install – failures in the updater that I haven't investigated yet
- test_ipaserver – test bug (relying on order of values in an LDAP
attribute) and a text/bytes issue in certificate parsing


In the next few months, I'll need to focus less on IPA and more on
Samba, which is a prerequisite for porting the IPA server. So I'll
quickly summarize the current state of the porting effort:

All of FreeIPA's dependencies except Samba are ported to Python 3 (and
packaged in Fedora).
A recent change switched the IPA client to running on Python 3. With the
patches I'm sending now, most of the "single machine" tests are passing.
The install scripts will still need some work, as will the server parts
that aren't shared with the client.


I'd like to ask the IPA team to sometimes take a look at the Python 3
tests, and try to avoid too many regressions.


-- 
Petr Viktorin
From 3a645b39f2ab80e60dd2dbcd5f6f4e39946d4450 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 29 Apr 2016 17:13:08 +0200
Subject: [PATCH] ipaldap: Keep attribute names as text, not bytes

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipapython/ipaldap.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 7e920e1003d84b729547d75d8e1324d2f73c120c..74add512adb6af092e9220c0ca2164c95caae262 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -813,7 +813,7 @@ class LDAPClient(object):
         If there is a problem loading the schema or the attribute is
         not in the schema return None
         """
-        if isinstance(name_or_oid, unicode):
+        if six.PY2 and isinstance(name_or_oid, unicode):
             name_or_oid = name_or_oid.encode('utf-8')
 
         if name_or_oid in self._SINGLE_VALUE_OVERRIDE:
@@ -1516,7 +1516,7 @@ class LDAPClient(object):
 
         # pass arguments to python-ldap
         with self.error_handler():
-            modlist = [(a, self.encode(b), self.encode(c))
+            modlist = [(a, str(b), self.encode(c))
                        for a, b, c in modlist]
             self.conn.modify_s(str(entry.dn), modlist)
 
-- 
2.5.5

From 85a4c73ca57e1f3ba64bdb76c386b6a9c32f9d36 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 17:08:18 +0200
Subject: [PATCH] ipapython.secrets.kem: Use ConfigParser from six.moves

In Python 3, the module name changed from 'ConfigParser' to
'configparser'. Use the appropriate location from six.

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipapython/secrets/kem.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ipapython/secrets/kem.py b/ipapython/secrets/kem.py
index 1025ed7980f055c82c602634e8845fa490cf0514..0abf28ae4403a7b6225404df361d12cb07ccc70b 100644
--- a/ipapython/secrets/kem.py
+++ b/ipapython/secrets/kem.py
@@ -2,7 +2,7 @@
 
 from __future__ import print_function
 from ipaplatform.paths import paths
-import ConfigParser
+from six.moves.configparser import ConfigParser
 from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives import serialization
 from cryptography.hazmat.primitives.asymmetric import rsa, ec
@@ -154,7 +154,7 @@ class IPAKEMKeys(KEMKeysStore):
 
     def __init__(self, config=None, ipaconf=paths.IPA_DEFAULT_CONF):
         super(IPAKEMKeys, self).__init__(config)
-        conf = ConfigParser.ConfigParser()
+        conf = ConfigParser()
         conf.read(ipaconf)
         self.host = conf.get('global', 'host')
         self.realm = conf.get('global', 'realm')
-- 
2.5.5

From f5d3da6a63a41b626bc9c1b4ac7f6603e220d6ff Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 17:35:26 +0200
Subject: [PATCH] test_topology_plugin: Don't rely on order of an attribute's
 values

Order of Python dicts/sets was always unreliable, but in Python 3
it's usually different every time. This affects the order in which
values of a LDAP attribute appear.
LDAP values are also specified to be unordered.

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipatests/test_ipaserver/test_topology_plugin.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipatests/test_ipaserver/test_topology_plugin.py b/ipatests/test_ipaserver/test_topology_plugin.py
index 6407f3e6f4ef4ff0fe12de721749dd41a667885c..eaa7b01cb977e885a731e83d0a31597cf7a05168 100644
--- a/ipatests/test_ipaserver/test_topology_plugin.py
+++ b/ipatests/test_ipaserver/test_topology_plugin.py
@@ -72,4 +72,4 @@ class TestTopologyPlugin(object):
         entry = self.conn.get_entry(topoplugindn)
         assert(set(entry.keys()) == set(pluginattrs.keys()))
         for i in checkvalues:
-            assert(pluginattrs[i] == entry[i])
+            assert(set(pluginattrs[i]) == set(entry[i]))
-- 
2.5.5

From 84bab5807473e05adad5721a9ad423e2952797c0 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 17:43:06 +0200
Subject: [PATCH] test_rpcserver: Expect updated error message under Python 3

Python 3's JSON module provides line number information in
its parsing error. Update the test to expect this.

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipatests/test_ipaserver/test_rpcserver.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/ipatests/test_ipaserver/test_rpcserver.py b/ipatests/test_ipaserver/test_rpcserver.py
index 03a4cebb2dc9e68638309a8f79b31cfd257babe0..94ebd062c91aece0558bac4c8bdf1fb01448f605 100644
--- a/ipatests/test_ipaserver/test_rpcserver.py
+++ b/ipatests/test_ipaserver/test_rpcserver.py
@@ -213,7 +213,10 @@ class test_jsonserver(PluginTester):
         # Test with invalid JSON-data:
         e = raises(errors.JSONError, o.unmarshal, 'this wont work')
         assert isinstance(e.error, ValueError)
-        assert unicode(e.error) == 'No JSON object could be decoded'
+        if six.PY2:
+            assert unicode(e.error) == 'No JSON object could be decoded'
+        else:
+            assert str(e.error).startswith('Expecting value: ')
 
         # Test with non-dict type:
         e = raises(errors.JSONError, o.unmarshal, json.dumps([1, 2, 3]))
-- 
2.5.5

From 86a8567abbfe05c72d77e2da8a58d355a6034af3 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 17:54:10 +0200
Subject: [PATCH] ipaplatform.redhat: Use bytestrings when calling rpm.so for
 version comparison

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipaplatform/redhat/tasks.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index ace29bd1c8bd471e4e2ddb20de34cc1c485b6743..294a9fe1abe48423495cf6207288c78bbd00b02e 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -84,13 +84,17 @@ class IPAVersion(object):
     def __init__(self, version):
         self.version = version
 
+    @property
+    def _bytes(self):
+        return self.version.encode('utf-8')
+
     def __eq__(self, other):
         assert isinstance(other, IPAVersion)
-        return _librpm.rpmvercmp(self.version, other.version) == 0
+        return _librpm.rpmvercmp(self._bytes, other._bytes) == 0
 
     def __lt__(self, other):
         assert isinstance(other, IPAVersion)
-        return _librpm.rpmvercmp(self.version, other.version) < 0
+        return _librpm.rpmvercmp(self._bytes, other._bytes) < 0
 
 
 class RedHatTaskNamespace(BaseTaskNamespace):
-- 
2.5.5

From e96d944affded180a0fe7c29c595848ae0145c40 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 18:08:05 +0200
Subject: [PATCH] test_ipaserver.test_ldap: Use bytestrings for raw LDAP values

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipatests/test_ipaserver/test_ldap.py | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/ipatests/test_ipaserver/test_ldap.py b/ipatests/test_ipaserver/test_ldap.py
index 3488ae66ae3207a0137f38ee4683933f6b3004f7..ff1a7c1a55edca060278158a6e59b0f84e60c3d3 100644
--- a/ipatests/test_ipaserver/test_ldap.py
+++ b/ipatests/test_ipaserver/test_ldap.py
@@ -281,33 +281,33 @@ class test_LDAPEntry(object):
         assert e['test'] is nice
 
         raw = e.raw['test']
-        assert raw == ['1', '2', '3']
+        assert raw == [b'1', b'2', b'3']
 
         nice.remove(1)
         assert e.raw['test'] is raw
-        assert raw == ['2', '3']
+        assert raw == [b'2', b'3']
 
-        raw.append('4')
+        raw.append(b'4')
         assert e['test'] is nice
         assert nice == [2, 3, u'4']
 
         nice.remove(2)
-        raw.append('5')
+        raw.append(b'5')
         assert nice == [3, u'4']
-        assert raw == ['2', '3', '4', '5']
+        assert raw == [b'2', b'3', b'4', b'5']
         assert e['test'] is nice
         assert e.raw['test'] is raw
         assert nice == [3, u'4', u'5']
-        assert raw == ['3', '4', '5']
+        assert raw == [b'3', b'4', b'5']
 
         nice.insert(0, 2)
-        raw.remove('4')
+        raw.remove(b'4')
         assert nice == [2, 3, u'4', u'5']
-        assert raw == ['3', '5']
+        assert raw == [b'3', b'5']
         assert e.raw['test'] is raw
         assert e['test'] is nice
         assert nice == [2, 3, u'5']
-        assert raw == ['3', '5', '2']
+        assert raw == [b'3', b'5', b'2']
 
         raw = [b'a', b'b']
         e.raw['test'] = raw
@@ -319,5 +319,5 @@ class test_LDAPEntry(object):
         assert e['test'] is nice
         assert e.raw['test'] == [b'not list']
 
-        e.raw['test'].append('second')
+        e.raw['test'].append(b'second')
         assert e['test'] == ['not list', u'second']
-- 
2.5.5

From 2473f0f29790cb3621a84dd8fd9e93b19a9e5a60 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 18:12:02 +0200
Subject: [PATCH] ipaldap: Convert dict items to list before iterating

In Python 3, dict.items() returns a view.
When such a view is iterated over, the dict cannot change size.

Part of the work for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipapython/ipaldap.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 74add512adb6af092e9220c0ca2164c95caae262..9fb7fd3f5a49dec0fd855c05f0e64004593e1306 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -456,7 +456,7 @@ class LDAPEntry(collections.MutableMapping):
     def __delitem__(self, name):
         name = self._get_attr_name(name)
 
-        for (altname, keyname) in self._names.items():
+        for (altname, keyname) in list(self._names.items()):
             if keyname == name:
                 del self._names[altname]
 
-- 
2.5.5

From 71327656efb393ee068e3cfc82f8535b619a4468 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Fri, 6 May 2016 18:27:24 +0200
Subject: [PATCH] test_ipaserver.test_ldap: Adjust tests to Python 3's KeyView

In Python 3, the keys() method of mappings returns a KeyView object
that reflects the mapping's state. In LDAPEntry, this means that
the collection returned by keys() is case-insensitive and supports
aliases.

Part of the fix for: https://fedorahosted.org/freeipa/ticket/4985
---
 ipatests/test_ipaserver/test_ldap.py | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/ipatests/test_ipaserver/test_ldap.py b/ipatests/test_ipaserver/test_ldap.py
index ff1a7c1a55edca060278158a6e59b0f84e60c3d3..42245a087cfbcd6476ce40648263fb1ac980ab3d 100644
--- a/ipatests/test_ipaserver/test_ldap.py
+++ b/ipatests/test_ipaserver/test_ldap.py
@@ -184,9 +184,15 @@ class test_LDAPEntry(object):
         assert u'cn' in e
         assert u'cn' in e.keys()
         assert 'CN' in e
-        assert 'CN' not in e.keys()
+        if six.PY2:
+            assert 'CN' not in e.keys()
+        else:
+            assert 'CN' in e.keys()
         assert 'commonName' in e
-        assert 'commonName' not in e.keys()
+        if six.PY2:
+            assert 'commonName' not in e.keys()
+        else:
+            assert 'commonName' in e.keys()
         assert e['CN'] is self.cn1
         assert e['CN'] is e[u'cn']
 
@@ -199,9 +205,15 @@ class test_LDAPEntry(object):
         assert u'cn' in e
         assert u'cn' in e.keys()
         assert 'CN' in e
-        assert 'CN' not in e.keys()
+        if six.PY2:
+            assert 'CN' not in e.keys()
+        else:
+            assert 'CN' in e.keys()
         assert 'commonName' in e
-        assert 'commonName' not in e.keys()
+        if six.PY2:
+            assert 'commonName' not in e.keys()
+        else:
+            assert 'commonName' in e.keys()
         assert e['CN'] is self.cn2
         assert e['CN'] is e[u'cn']
 
-- 
2.5.5

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to