URL: https://github.com/freeipa/freeipa/pull/1580
Author: tiran
 Title: #1580: Generate same API.txt under Python 2 and 3
Action: opened

PR body:
"""
Use Python 3's reprlib with customizations to create same API.txt under
Python 2 and 3. Some plugins have been slightly altered to use stable
sorting for dynamically created parameter lists.

Signed-off-by: Christian Heimes <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1580/head:pr1580
git checkout pr1580
From 52ee20d72f663e7a0e98e62f9a2d893d504e69db Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Wed, 14 Feb 2018 12:03:02 +0100
Subject: [PATCH] Generate same API.txt under Python 2 and 3

Use Python 3's reprlib with customizations to create same API.txt under
Python 2 and 3. Some plugins have been slightly altered to use stable
sorting for dynamically created parameter lists.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 API.txt                             |  8 ++++----
 ipalib/output.py                    |  3 ++-
 ipalib/parameters.py                |  9 ++++++---
 ipalib/util.py                      | 38 +++++++++++++++++++++++++++++++++++++
 ipaserver/plugins/idrange.py        |  4 ++--
 ipaserver/plugins/migration.py      |  2 +-
 ipaserver/plugins/trust.py          |  4 ++--
 ipatests/test_ipalib/test_output.py |  8 ++++++--
 8 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/API.txt b/API.txt
index 0526d5a902..05dec4475c 100644
--- a/API.txt
+++ b/API.txt
@@ -2973,7 +2973,7 @@ option: Int('ipabaserid?', cli_name='rid_base')
 option: Int('ipaidrangesize', cli_name='range_size')
 option: Str('ipanttrusteddomainname?', cli_name='dom_name')
 option: Str('ipanttrusteddomainsid?', cli_name='dom_sid')
-option: StrEnum('iparangetype?', cli_name='type', values=[u'ipa-ad-trust-posix', u'ipa-ad-trust', u'ipa-local'])
+option: StrEnum('iparangetype?', cli_name='type', values=[u'ipa-ad-trust', u'ipa-ad-trust-posix', u'ipa-local'])
 option: Int('ipasecondarybaserid?', cli_name='secondary_rid_base')
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Str('setattr*', cli_name='setattr')
@@ -2998,7 +2998,7 @@ option: Int('ipabaseid?', autofill=False, cli_name='base_id')
 option: Int('ipabaserid?', autofill=False, cli_name='rid_base')
 option: Int('ipaidrangesize?', autofill=False, cli_name='range_size')
 option: Str('ipanttrusteddomainsid?', autofill=False, cli_name='dom_sid')
-option: StrEnum('iparangetype?', autofill=False, cli_name='type', values=[u'ipa-ad-trust-posix', u'ipa-ad-trust', u'ipa-local'])
+option: StrEnum('iparangetype?', autofill=False, cli_name='type', values=[u'ipa-ad-trust', u'ipa-ad-trust-posix', u'ipa-local'])
 option: Int('ipasecondarybaserid?', autofill=False, cli_name='secondary_rid_base')
 option: Flag('pkey_only?', autofill=True, default=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
@@ -3255,7 +3255,7 @@ option: Str('groupignoreobjectclass*', autofill=True, cli_name='group_ignore_obj
 option: Str('groupobjectclass+', autofill=True, cli_name='group_objectclass', default=[u'groupOfUniqueNames', u'groupOfNames'])
 option: Flag('groupoverwritegid', autofill=True, cli_name='group_overwrite_gid', default=False)
 option: StrEnum('schema?', autofill=True, cli_name='schema', default=u'RFC2307bis', values=[u'RFC2307bis', u'RFC2307'])
-option: StrEnum('scope', autofill=True, cli_name='scope', default=u'onelevel', values=[u'base', u'subtree', u'onelevel'])
+option: StrEnum('scope', autofill=True, cli_name='scope', default=u'onelevel', values=[u'base', u'onelevel', u'subtree'])
 option: Bool('use_def_group?', autofill=True, cli_name='use_default_group', default=True)
 option: DNParam('usercontainer', autofill=True, cli_name='user_container', default=ipapython.dn.DN('ou=people'))
 option: Str('userignoreattribute*', autofill=True, cli_name='user_ignore_attribute', default=[])
@@ -5721,7 +5721,7 @@ option: Int('base_id?', cli_name='base_id')
 option: Bool('bidirectional?', cli_name='two_way', default=False)
 option: Bool('external?', cli_name='external', default=False)
 option: Int('range_size?', cli_name='range_size')
-option: StrEnum('range_type?', cli_name='range_type', values=[u'ipa-ad-trust-posix', u'ipa-ad-trust'])
+option: StrEnum('range_type?', cli_name='range_type', values=[u'ipa-ad-trust', u'ipa-ad-trust-posix'])
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Str('realm_admin?', cli_name='admin')
 option: Password('realm_passwd?', cli_name='password', confirm=False)
diff --git a/ipalib/output.py b/ipalib/output.py
index b104584631..afcbefa110 100644
--- a/ipalib/output.py
+++ b/ipalib/output.py
@@ -25,6 +25,7 @@
 from ipalib.plugable import ReadOnly, lock
 from ipalib.capabilities import client_has_capability
 from ipalib.text import _
+from ipalib.util import apirepr
 
 if six.PY3:
     unicode = str
@@ -98,7 +99,7 @@ def __repr_iter(self):
             if not value:
                 continue
             if isinstance(value, tuple):
-                value = repr(list(value))
+                value = apirepr(list(value))
             else:
                 value = repr(value)
             yield '%s=%s' % (key, value)
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index ead56c018e..902ae3401b 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -123,7 +123,7 @@
 from ipalib.util import json_serialize, validate_idna_domain
 from ipalib.x509 import (
     load_der_x509_certificate, IPACertificate, default_backend)
-from ipalib.util import strip_csr_header
+from ipalib.util import strip_csr_header, apirepr
 from ipapython import kerberos
 from ipapython.dn import DN
 from ipapython.dnsutil import DNSName
@@ -600,9 +600,12 @@ def __repr_iter(self):
             elif isinstance(value, six.integer_types):
                 value = str(value)
             elif isinstance(value, (tuple, set, frozenset)):
-                value = repr(list(value))
-            else:
+                value = apirepr(list(value))
+            elif key == 'cli_name':
+                # always represented as native string
                 value = repr(value)
+            else:
+                value = apirepr(value)
             yield '%s=%s' % (key, value)
 
     def __call__(self, value, **kw):
diff --git a/ipalib/util.py b/ipalib/util.py
index 96fcb33eaa..16754a36e8 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -66,6 +66,11 @@
 from ipapython.dnsutil import resolve_ip_addresses
 from ipapython.admintool import ScriptError
 
+if sys.version_info >= (3, 2):
+    import reprlib  # pylint: disable=import-error
+else:
+    reprlib = None
+
 if six.PY3:
     unicode = str
 
@@ -1213,3 +1218,36 @@ def open_in_pager(data):
         pager_process.communicate()
     except IOError:
         pass
+
+
+if reprlib is not None:
+    class APIRepr(reprlib.Repr):
+        builtin_types = {
+            bool, int, float,
+            str, bytes,
+            dict, tuple, list, set, frozenset,
+            type(None),
+        }
+
+        def __init__(self):
+            super(APIRepr, self).__init__()
+            # no limitation
+            for k, v in self.__dict__.items():
+                if isinstance(v, int):
+                    setattr(self, k, sys.maxsize)
+
+        def repr_str(self, x, level):
+            """Output with u'' prefix"""
+            return 'u' + repr(x)
+
+        def repr_type(self, x, level):
+            if x is str:
+                return "<type 'unicode'>"
+            if x in self.builtin_types:
+                return "<type '{}'>".format(x.__name__)
+            else:
+                return repr(x)
+
+    apirepr = APIRepr().repr
+else:
+    apirepr = repr
diff --git a/ipaserver/plugins/idrange.py b/ipaserver/plugins/idrange.py
index b67ed31082..bdcadb1f7c 100644
--- a/ipaserver/plugins/idrange.py
+++ b/ipaserver/plugins/idrange.py
@@ -244,8 +244,8 @@ class idrange(LDAPObject):
             label=_('Range type'),
             cli_name='type',
             doc=(_('ID range type, one of {vals}'
-                 .format(vals=', '.join(range_types.keys())))),
-            values=tuple(range_types.keys()),
+                 .format(vals=', '.join(sorted(range_types))))),
+            values=sorted(range_types),
             flags=['no_update'],
         )
     )
diff --git a/ipaserver/plugins/migration.py b/ipaserver/plugins/migration.py
index b89fba0d76..67e64544b2 100644
--- a/ipaserver/plugins/migration.py
+++ b/ipaserver/plugins/migration.py
@@ -646,7 +646,7 @@ class migrate_ds(Command):
             label=_('Search scope'),
             doc=_('LDAP search scope for users and groups: base, onelevel, or '
                   'subtree. Defaults to onelevel'),
-            values=tuple(_supported_scopes.keys()),
+            values=sorted(_supported_scopes),
             default=_default_scope,
             autofill=True,
         ),
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index 978738e20a..a2b4c4aacd 100644
--- a/ipaserver/plugins/trust.py
+++ b/ipaserver/plugins/trust.py
@@ -684,8 +684,8 @@ class trust_add(LDAPCreate):
             label=_('Range type'),
             cli_name='range_type',
             doc=(_('Type of trusted domain ID range, one of {vals}'
-                 .format(vals=', '.join(range_types.keys())))),
-            values=tuple(range_types.keys()),
+                 .format(vals=', '.join(sorted(range_types))))),
+            values=sorted(range_types),
         ),
         Bool('bidirectional?',
              label=_('Two-way trust'),
diff --git a/ipatests/test_ipalib/test_output.py b/ipatests/test_ipalib/test_output.py
index ed734ffd4b..954b2a34f5 100644
--- a/ipatests/test_ipalib/test_output.py
+++ b/ipatests/test_ipalib/test_output.py
@@ -53,14 +53,18 @@ def test_repr(self):
         o = self.cls('aye')
         assert repr(o) == "Output('aye')"
         o = self.cls('aye', type=int, doc='An A, aye?')
-        assert repr(o) == "Output('aye', type=[%r], doc='An A, aye?')" % int
+        assert repr(o) == (
+            "Output('aye', type=[<type 'int'>], doc='An A, aye?')"
+        )
 
         class Entry(self.cls):
             pass
         o = Entry('aye')
         assert repr(o) == "Entry('aye')"
         o = Entry('aye', type=int, doc='An A, aye?')
-        assert repr(o) == "Entry('aye', type=[%r], doc='An A, aye?')" % int
+        assert repr(o) == (
+            "Entry('aye', type=[<type 'int'>], doc='An A, aye?')"
+        )
 
 
 class test_ListOfEntries(ClassChecker):
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to