URL: https://github.com/freeipa/freeipa/pull/1584
Author: tiran
 Title: #1584: [Backport][ipa-4-6] Generate same API.txt under Python 2 and 3
Action: opened

PR body:
"""
This PR was opened automatically because PR #1580 was pushed to master and 
backport to ipa-4-6 is required.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1584/head:pr1584
git checkout pr1584
From b62729e37b7c7b3f16ca04c130a64758e2d06151 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Wed, 14 Feb 2018 16:59:50 +0100
Subject: [PATCH 1/2] 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        | 19 ++++++-------
 ipaserver/plugins/migration.py      | 32 +++++++++++-----------
 ipaserver/plugins/trust.py          | 54 ++++++++++++++++++++-----------------
 ipatests/test_ipalib/test_output.py |  8 ++++--
 8 files changed, 111 insertions(+), 60 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 f154c0b10d..ebf6eb3faf 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
 
@@ -1206,3 +1211,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..6b37d9d708 100644
--- a/ipaserver/plugins/idrange.py
+++ b/ipaserver/plugins/idrange.py
@@ -239,18 +239,19 @@ class idrange(LDAPObject):
             cli_name='dom_name',
             flags=('no_search', 'virtual_attribute', 'no_update'),
             label=_('Name of the trusted domain'),
-        ),
+            ),
         StrEnum('iparangetype?',
-            label=_('Range type'),
-            cli_name='type',
-            doc=(_('ID range type, one of {vals}'
-                 .format(vals=', '.join(range_types.keys())))),
-            values=tuple(range_types.keys()),
-            flags=['no_update'],
-        )
+                label=_('Range type'),
+                cli_name='type',
+                doc=(_('ID range type, one of {vals}'
+                     .format(vals=', '.join(sorted(range_types))))),
+                values=sorted(range_types),
+                flags=['no_update'],
+                )
     )
 
-    def handle_iparangetype(self, entry_attrs, options, keep_objectclass=False):
+    def handle_iparangetype(self, entry_attrs, options,
+                            keep_objectclass=False):
         if not any((options.get('pkey_only', False),
                     options.get('raw', False))):
             range_type = entry_attrs['iparangetype'][0]
diff --git a/ipaserver/plugins/migration.py b/ipaserver/plugins/migration.py
index b89fba0d76..724c704ca5 100644
--- a/ipaserver/plugins/migration.py
+++ b/ipaserver/plugins/migration.py
@@ -632,24 +632,24 @@ class migrate_ds(Command):
             doc=_('Load CA certificate of LDAP server from FILE'),
             default=None,
             noextrawhitespace=False,
-        ),
+            ),
         Bool('use_def_group?',
-            cli_name='use_default_group',
-            label=_('Add to default group'),
-            doc=_('Add migrated users without a group to a default group '
-                  '(default: true)'),
-            default=True,
-            autofill=True,
-        ),
+             cli_name='use_default_group',
+             label=_('Add to default group'),
+             doc=_('Add migrated users without a group to a default group '
+                   '(default: true)'),
+             default=True,
+             autofill=True,
+             ),
         StrEnum('scope',
-            cli_name='scope',
-            label=_('Search scope'),
-            doc=_('LDAP search scope for users and groups: base, onelevel, or '
-                  'subtree. Defaults to onelevel'),
-            values=tuple(_supported_scopes.keys()),
-            default=_default_scope,
-            autofill=True,
-        ),
+                cli_name='scope',
+                label=_('Search scope'),
+                doc=_('LDAP search scope for users and groups: base, '
+                      'onelevel, or subtree. Defaults to onelevel'),
+                values=sorted(_supported_scopes),
+                default=_default_scope,
+                autofill=True,
+                ),
     )
 
     has_output = (
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index 978738e20a..91cd1387ce 100644
--- a/ipaserver/plugins/trust.py
+++ b/ipaserver/plugins/trust.py
@@ -657,48 +657,52 @@ class trust_add(LDAPCreate):
         Str('realm_admin?',
             cli_name='admin',
             label=_("Active Directory domain administrator"),
-        ),
+            ),
         Password('realm_passwd?',
-            cli_name='password',
-            label=_("Active Directory domain administrator's password"),
-            confirm=False,
-        ),
+                 cli_name='password',
+                 label=_("Active Directory domain administrator's password"),
+                 confirm=False,
+                 ),
         Str('realm_server?',
             cli_name='server',
-            label=_('Domain controller for the Active Directory domain (optional)'),
-        ),
+            label=_('Domain controller for the Active Directory domain '
+                    '(optional)'),
+            ),
         Password('trust_secret?',
-            cli_name='trust_secret',
-            label=_('Shared secret for the trust'),
-            confirm=False,
-        ),
+                 cli_name='trust_secret',
+                 label=_('Shared secret for the trust'),
+                 confirm=False,
+                 ),
         Int('base_id?',
             cli_name='base_id',
-            label=_('First Posix ID of the range reserved for the trusted domain'),
-        ),
+            label=_('First Posix ID of the range reserved for the '
+                    'trusted domain'),
+            ),
         Int('range_size?',
             cli_name='range_size',
-            label=_('Size of the ID range reserved for the trusted domain'),
-        ),
+            label=_('Size of the ID range reserved for the trusted domain')
+            ),
         StrEnum('range_type?',
-            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()),
-        ),
+                label=_('Range type'),
+                cli_name='range_type',
+                doc=(_('Type of trusted domain ID range, one of {vals}'
+                     .format(vals=', '.join(sorted(range_types))))),
+                values=sorted(range_types),
+                ),
         Bool('bidirectional?',
              label=_('Two-way trust'),
              cli_name='two_way',
-             doc=(_('Establish bi-directional trust. By default trust is inbound one-way only.')),
+             doc=(_('Establish bi-directional trust. By default trust is '
+                    'inbound one-way only.')),
              default=False,
-        ),
+             ),
         Bool('external?',
              label=_('External trust'),
              cli_name='external',
-             doc=(_('Establish external trust to a domain in another forest. The trust is not transitive beyond the domain.')),
+             doc=_('Establish external trust to a domain in another forest. '
+                   'The trust is not transitive beyond the domain.'),
              default=False,
-        ),
+             ),
     )
 
     msg_summary = _('Added Active Directory trust for realm "%(value)s"')
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):

From e318101893ff45d776e8eee5a2d544c37d930006 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Wed, 14 Feb 2018 17:00:44 +0100
Subject: [PATCH 2/2] Run API and ACI under Python 2 and 3

Make it possible to run API, ACI, and potests under Python 3.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 Makefile.am         | 17 ++++++++++-------
 po/Makefile.hack.in |  7 ++++---
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 1e200f117d..9bb1a94e9e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -174,10 +174,10 @@ endif
 	$(MAKE) $(AM_MAKEFLAGS) acilint apilint polint jslint check
 	$(MAKE) $(AM_MAKEFLAGS) PYTHON=$(PYTHON2) pylint
 if WITH_PYTHON3
-	@ # just tests and pylint on Python 3
+	@ # just tests, aci, api and pylint on Python 3
 	PYTHONPATH=$(abspath $(top_srcdir)) $(PYTHON3) ipatests/ipa-run-tests \
 	    --ipaclient-unittests
-	$(MAKE) $(AM_MAKEFLAGS) PYTHON=$(PYTHON3) pylint
+	$(MAKE) $(AM_MAKEFLAGS) PYTHON=$(PYTHON3) acilint apilint pylint
 else
 	@echo "WARNING: python3 not available"
 endif
@@ -186,10 +186,12 @@ endif
 .PHONY: fastcheck fasttest fastlint
 fastcheck:
 if WITH_PYTHON2
-	@$(MAKE) -j1 $(AM_MAKEFLAGS) PYTHON=$(PYTHON2) fastlint fasttest
+	@$(MAKE) -j1 $(AM_MAKEFLAGS) PYTHON=$(PYTHON2) \
+	    fastlint fasttest apilint acilint
 endif
 if WITH_PYTHON3
-	@$(MAKE) -j1 $(AM_MAKEFLAGS) PYTHON=$(PYTHON3) fastlint fasttest
+	@$(MAKE) -j1 $(AM_MAKEFLAGS) PYTHON=$(PYTHON3) \
+	     fastlint fasttest apilint acilint
 endif
 
 fasttest: $(GENERATED_PYTHON_FILES) ipasetup.py
@@ -236,15 +238,16 @@ $(top_builddir)/ipapython/version.py:
 
 .PHONY: acilint
 acilint: $(GENERATED_PYTHON_FILES)
-	cd $(srcdir); ./makeaci --validate
+	cd $(srcdir); $(PYTHON) ./makeaci --validate
 
 .PHONY: apilint
 apilint: $(GENERATED_PYTHON_FILES)
-	cd $(srcdir); ./makeapi --validate
+	cd $(srcdir); $(PYTHON) ./makeapi --validate
 
 .PHONY: polint
 polint:
-	$(MAKE) -C $(srcdir)/po validate-src-strings validate-po test-gettext
+	$(MAKE) -C $(srcdir)/po PYTHON=$(PYTHON) \
+	    validate-src-strings validate-po test-gettext
 
 # Run pylint for all python files. Finds all python files/packages, skips
 # folders rpmbuild, freeipa-* and dist. Skip (match, but don't print) .*,
diff --git a/po/Makefile.hack.in b/po/Makefile.hack.in
index 90727c460c..c57f1e1506 100644
--- a/po/Makefile.hack.in
+++ b/po/Makefile.hack.in
@@ -6,6 +6,7 @@ DISTFILES.common.extra3 = Makefile.hack.in
 
 IPA_TEST_I18N = @top_srcdir@/ipatests/i18n.py
 MSGATTRIB = @MSGATTRIB@
+PYTHON = @PYTHON@
 
 .PHONY: strip-po
 strip-po:
@@ -24,13 +25,13 @@ clean: mostlyclean
 
 # linters
 test-gettext: $(DOMAIN).pot
-	$(IPA_TEST_I18N) --test-gettext
+	$(PYTHON) $(IPA_TEST_I18N) --test-gettext
 
 validate-pot: $(DOMAIN).pot
-	$(IPA_TEST_I18N) --show-strings --validate-pot $(DOMAIN).pot
+	$(PYTHON) $(IPA_TEST_I18N) --show-strings --validate-pot $(DOMAIN).pot
 
 validate-po: $(DOMAIN).pot
-	$(IPA_TEST_I18N) --show-strings --validate-po $(POFILES)
+	$(PYTHON) $(IPA_TEST_I18N) --show-strings --validate-po $(POFILES)
 
 # forcefully re-generate .pot file and test it
 validate-src-strings: $(DOMAIN).pot-update
_______________________________________________
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