diff --git a/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py b/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py
index d3a9fa140f15733a973e5cc06c3c0a3f31ed4ae1..0e80c4a405965a2b67539d0e85b4b7105add68aa 100644
--- a/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py
+++ b/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py
@@ -782,15 +782,16 @@ class BuilderMixin(XMLObject, Amount, Predicate):
     for i in self.getPortalObject().portal_categories.collect_order_group.contentValues():
       category_index_dict[i.getId()] = i.getIntIndex()
 
-    def sort_movement_group(a, b):
-      return cmp(category_index_dict.get(a.getCollectOrderGroup()),
-                 category_index_dict.get(b.getCollectOrderGroup())) or \
-             cmp(a.getIntIndex(), b.getIntIndex())
+    def sort_movement_group_key(a):
+      return (
+        category_index_dict.get(a.getCollectOrderGroup()),
+        a.getIntIndex(),
+      )
     if portal_type is None:
       portal_type = self.getPortalMovementGroupTypeList()
     movement_group_list = [x for x in self.contentValues(filter={'portal_type': portal_type}) \
                            if collect_order_group is None or collect_order_group == x.getCollectOrderGroup()]
-    return sorted(movement_group_list, sort_movement_group)
+    return sorted(movement_group_list, key=sort_movement_group_key)
 
   # XXX category name is hardcoded.
   def getDeliveryMovementGroupList(self, **kw):
diff --git a/product/CMFCategory/Category.py b/product/CMFCategory/Category.py
index da7df912a7cbd469e8a875591a7e72a7105cda47..7c62803132cf37493d2a3de291c2700fd91d8867 100644
--- a/product/CMFCategory/Category.py
+++ b/product/CMFCategory/Category.py
@@ -42,12 +42,20 @@ from Products.ERP5Type.Core.Folder import Folder
 from Products.CMFCategory.Renderer import Renderer
 from Products.ERP5Type.Utils import sortValueList
 from Products.ERP5Type.Cache import CachingMethod
+import six
+if six.PY3:
+  from functools import cmp_to_key
+  def cmp(a, b):
+      return (a > b) - (a < b)
 
 DEFAULT_CACHE_FACTORY = 'erp5_ui_long'
 
 from zLOG import LOG
 
-NBSP_UTF8 = u'\xA0'.encode('utf-8')
+if six.PY2:
+  NBSP_UTF8 = u'\xA0'.encode('utf-8')
+else:
+  NBSP_UTF8 = '\xA0'
 
 manage_addCategoryForm=DTMLFile('dtml/category_add', globals())
 
@@ -331,8 +339,10 @@ class Category(Folder):
       if local_sort_method:
         # sort objects at the current level
         child_value_list = list(child_value_list)
-        child_value_list.sort(local_sort_method)
-
+        if six.PY2:
+          child_value_list.sort(local_sort_method)
+        else:
+          child_value_list.sort(key=cmp_to_key(local_sort_method))
       if recursive:
         for c in child_value_list:
           # Do not pass sort_on / sort_order parameters intentionally, because
@@ -883,7 +893,10 @@ class BaseCategory(Category):
       if local_sort_method:
         # sort objects at the current level
         child_value_list = list(child_value_list)
-        child_value_list.sort(local_sort_method)
+        if six.PY2:
+          child_value_list.sort(local_sort_method)
+        else:
+          child_value_list.sort(key=cmp_to_key(local_sort_method))
 
       if recursive:
         for c in child_value_list:
diff --git a/product/CMFCategory/tests/testCMFCategory.py b/product/CMFCategory/tests/testCMFCategory.py
index 06c1d898cb18d4ca6dc6c9ab0f6c8b1051d62586..b3e7fb2359edcec6d29817d0d9f8b5d23e81966e 100644
--- a/product/CMFCategory/tests/testCMFCategory.py
+++ b/product/CMFCategory/tests/testCMFCategory.py
@@ -38,6 +38,9 @@ from Testing.ZopeTestCase.PortalTestCase import PortalTestCase
 from AccessControl.SecurityManagement import newSecurityManager
 from AccessControl.SecurityManagement import noSecurityManager
 import six
+if six.PY3:
+  def cmp(a, b):
+      return (a > b) - (a < b)
 
 class TestCMFCategory(ERP5TypeTestCase):
 
@@ -785,31 +788,31 @@ class TestCMFCategory(ERP5TypeTestCase):
         base_cat.getCategoryChildIndentedTitleItemList(),
           [['', ''],
             ['The Title', 'the_id'],
-            ['\xc2\xa0\xc2\xa0The Sub Title', 'the_id/the_sub_id']],
+            [NBSP_UTF8 * 2 + 'The Sub Title', 'the_id/the_sub_id']],
       )
       self.assertEqual(
         base_cat.getCategoryChildTranslatedIndentedTitleItemList(),
           [['', ''],
             ['The Title', 'the_id'],
-            ['\xc2\xa0\xc2\xa0The S\xc3\xbcb T\xc3\xaftle', 'the_id/the_sub_id']],
+            [NBSP_UTF8 * 2 + 'The Süb Tïtle', 'the_id/the_sub_id']],
       )
       self.assertEqual(
         base_cat.getCategoryChildTranslatedCompactTitleItemList(),
           [['', ''],
             ['The Title', 'the_id'],
-            ['The S\xc3\xbcb T\xc3\xaftle', 'the_id/the_sub_id']],
+            ['The Süb Tïtle', 'the_id/the_sub_id']],
       )
       self.assertEqual(
         base_cat.getCategoryChildTranslatedLogicalPathItemList(),
           [['', ''],
             ['The Title', 'the_id'],
-            ['The Title/The S\xc3\xbcb T\xc3\xaftle', 'the_id/the_sub_id']],
+            ['The Title/The Süb Tïtle', 'the_id/the_sub_id']],
       )
       self.assertEqual(
         base_cat.getCategoryChildTranslatedCompactLogicalPathItemList(),
           [['', ''],
             ['The Title', 'the_id'],
-            ['The Title/The S\xc3\xbcb T\xc3\xaftle', 'the_id/the_sub_id']],
+            ['The Title/The Süb Tïtle', 'the_id/the_sub_id']],
       )
 
   def test_CategoryChildTitleItemListFilterNodeFilterLeave(self):
@@ -1363,9 +1366,9 @@ class TestCMFCategory(ERP5TypeTestCase):
     self.assertEqual(get(bc.id), list('aa'))
     _set(bc.id, list('baa'))
     self.assertEqual(get(bc.id), list('aba'))
-    _set(bc.id, map(base, 'bb'), 1)
+    _set(bc.id, [base(e) for e in 'bb'], 1)
     self.assertEqual(get(bc.id), list('bb'))
-    _set(bc.id, map(base, 'abb'), 1)
+    _set(bc.id, [base(e) for e in 'abb'], 1)
     self.assertEqual(get(bc.id), list('bab'))
     _set(bc.id, ())
 
diff --git a/product/ERP5Type/Utils.py b/product/ERP5Type/Utils.py
index 82a3a239a8cd7c3633c5b2cc856cde6b445b779a..a78bd0553233b8791fe41c56244fe3a92a0ad525 100644
--- a/product/ERP5Type/Utils.py
+++ b/product/ERP5Type/Utils.py
@@ -34,6 +34,8 @@ from six import int2byte as chr
 from six import string_types as basestring
 from six.moves import xrange
 import six
+if six.PY3:
+  from functools import cmp_to_key
 import os
 import re
 import string
@@ -206,7 +208,10 @@ def sortValueList(value_list, sort_on=None, sort_order=None, **kw):
             if result != 0:
               break
           return result
-        sort_kw = {'cmp':sortValues}
+        if six.PY2:
+          sort_kw = {'cmp':sortValues}
+        else:
+          sort_kw = {'key': cmp_to_key(sortValues)}
         sort_kw_cache[(sort_on, sort_order)] = sort_kw
 
     if isinstance(value_list, LazyMap):