From 1374d5155a3fa8c1217203c59116d406ed4e4ce0 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Thu, 24 Jan 2019 12:10:26 +0100
Subject: [PATCH] python3: use __future__.print_function (#31140)

---
 merge-coverage.py                             |  4 +-
 merge-junit-results.py                        |  4 +-
 src/authentic2/auth2_auth/auth2_ssl/README    |  4 +-
 .../management/commands/changepassword.py     | 14 +++----
 .../commands/clean-unused-accounts.py         |  4 +-
 .../management/commands/slapd-shell.py        | 28 +++++++------
 .../saml/management/commands/sync-metadata.py | 40 ++++++++++---------
 src/authentic2/saml/saml11utils.py            |  4 +-
 src/authentic2/saml/saml2utils.py             |  4 +-
 src/authentic2/saml/shibboleth/afp_parser.py  |  6 ++-
 .../commands/oidc-register-issuer.py          | 12 +++---
 .../management/commands/provision.py          |  8 ++--
 .../management/commands/cleanup_rbac.py       |  6 ++-
 tests/test_api.py                             |  5 ++-
 tests/test_crypto.py                          |  8 ++--
 15 files changed, 89 insertions(+), 62 deletions(-)

diff --git a/merge-coverage.py b/merge-coverage.py
index 9e2f804d..33666664 100755
--- a/merge-coverage.py
+++ b/merge-coverage.py
@@ -1,4 +1,6 @@
 #!/usr/bin/python
+from __future__ import print_function
+
 import sys
 import os
 import xml.etree.ElementTree as ET
@@ -59,7 +61,7 @@ if not xmlfiles:
 	    xmlfiles.append (fullname)
 
 	if not xmlfiles:
-		print 'No xml files found!'
+		print('No xml files found!')
 		sys.exit (1)
 
 else:
diff --git a/merge-junit-results.py b/merge-junit-results.py
index fa8fe615..dfb3bb56 100755
--- a/merge-junit-results.py
+++ b/merge-junit-results.py
@@ -3,6 +3,8 @@
 #  Corey Goldberg, Dec 2012
 #
 
+from __future__ import print_function
+
 import os
 import sys
 import xml.etree.ElementTree as ET
@@ -55,7 +57,7 @@ def merge_results(xml_files):
 
 def usage():
     this_file = os.path.basename(__file__)
-    print 'Usage:  %s results1.xml results2.xml' % this_file
+    print('Usage:  %s results1.xml results2.xml' % this_file)
 
 
 if __name__ == '__main__':
diff --git a/src/authentic2/auth2_auth/auth2_ssl/README b/src/authentic2/auth2_auth/auth2_ssl/README
index 3d44ee9d..db2fb044 100644
--- a/src/authentic2/auth2_auth/auth2_ssl/README
+++ b/src/authentic2/auth2_auth/auth2_ssl/README
@@ -37,7 +37,7 @@ sys.path.append("/usr/local/lib/python2.6/site-packages/")
 try:
     import lasso
 except:
-    print >> sys.stderr, "Unable to import Lasso."
+    print("Unable to import Lasso.", file=sys.stderr)
 
 apache_configuration= os.path.dirname(__file__)
 project = os.path.dirname(apache_configuration)
@@ -46,7 +46,7 @@ try:
     import authentic2.settings
     os.environ['DJANGO_SETTINGS_MODULE'] = 'authentic2.settings'
 except:
-    print >> sys.stderr, "Unable to import settings."
+    print("Unable to import settings.", file=sys.stderr)
 
 import django.core.handlers.wsgi
 application = django.core.handlers.wsgi.WSGIHandler()
diff --git a/src/authentic2/custom_user/management/commands/changepassword.py b/src/authentic2/custom_user/management/commands/changepassword.py
index c083d8a5..dd538db9 100644
--- a/src/authentic2/custom_user/management/commands/changepassword.py
+++ b/src/authentic2/custom_user/management/commands/changepassword.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import unicode_literals, print_function
 
 import getpass
 
@@ -42,23 +42,23 @@ class Command(BaseCommand):
             raise CommandError("user '%s' does not exist" % username)
         except MultipleObjectsReturned:
             while True:
-                print 'Select an user:'
+                print('Select a user:')
                 for i, user in enumerate(qs):
-                    print '%d.' % (i+1), user
-                print '> ',
+                    print('%d.' % (i+1), user)
+                print('> ', end=' ')
                 try:
                     j = input()
                 except SyntaxError:
-                    print 'Please enter an integer'
+                    print('Please enter an integer')
                     continue
                 if not isinstance(uid, int):
-                    print 'Please enter an integer'
+                    print('Please enter an integer')
                     continue
                 try:
                     u = qs[j-1]
                     break
                 except IndexError:
-                    print 'Please enter an integer between 1 and %d' % qs.count()
+                    print('Please enter an integer between 1 and %d' % qs.count())
                     continue
 
         self.stdout.write("Changing password for user '%s'\n" % u)
diff --git a/src/authentic2/management/commands/clean-unused-accounts.py b/src/authentic2/management/commands/clean-unused-accounts.py
index ce83272b..0340b15a 100644
--- a/src/authentic2/management/commands/clean-unused-accounts.py
+++ b/src/authentic2/management/commands/clean-unused-accounts.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import logging
 import datetime
 
@@ -16,7 +18,7 @@ def print_table(table):
     for line in table:
         line = u"| " + u" | ".join(u"{0:>{1}}".format(x, col_width[i])
                                 for i, x in enumerate(line)) + u" |"
-        print line
+        print(line)
 
 class Command(BaseCommand):
     help = '''Clean unused accounts'''
diff --git a/src/authentic2/management/commands/slapd-shell.py b/src/authentic2/management/commands/slapd-shell.py
index 4e267530..388aa7e3 100644
--- a/src/authentic2/management/commands/slapd-shell.py
+++ b/src/authentic2/management/commands/slapd-shell.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import logging
 import sys
 from StringIO import StringIO
@@ -38,19 +40,19 @@ class Command(BaseCommand):
             if attrs['filter'] != '(objectClass=*)':
                 m = re.match(r'\((\w*)=(.*)\)', attrs['filter'])
                 if not m:
-                    print 'RESULT'
-                    print 'code: 1'
-                    print 'info: invalid filter'
-                    print
+                    print('RESULT')
+                    print('code: 1')
+                    print('info: invalid filter')
+                    print()
                     return
                 for user_attribute, ldap_attribute in MAPPING.iteritems():
                     if ldap_attribute == m.group(1):
                         break
                 else:
-                    print 'RESULT'
-                    print 'code: 1'
-                    print 'info: unknown attribute in filter'
-                    print
+                    print('RESULT')
+                    print('code: 1')
+                    print('info: unknown attribute in filter')
+                    print()
                     return
                 value = m.group(2)
                 if value.endswith('*') and value.startswith('*'):
@@ -74,12 +76,12 @@ class Command(BaseCommand):
                 dn = 'uid=%s,%s' % (escape_dn_chars(o['uid'][0]), attrs['suffix'])
                 self.logger.debug(u'sending entry %s %s', dn, o)
                 ldif_writer.unparse(dn, o)
-            print out.getvalue(),
+            print(out.getvalue())
             out.close()
-        print 'RESULT'
-        print 'code: 0'
-        print 'info: RockNRoll'
-        print
+        print('RESULT')
+        print('code: 0')
+        print('info: RockNRoll')
+        print()
 
     def handle(self, *args, **options):
         self.logger = logging.getLogger(__name__)
diff --git a/src/authentic2/saml/management/commands/sync-metadata.py b/src/authentic2/saml/management/commands/sync-metadata.py
index aac228ee..8897b2f0 100644
--- a/src/authentic2/saml/management/commands/sync-metadata.py
+++ b/src/authentic2/saml/management/commands/sync-metadata.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import sys
 import xml.etree.ElementTree as etree
 import os
@@ -127,8 +129,8 @@ def load_acs(tree, provider, pks, verbosity):
                 attribute, created = SAMLAttribute.objects.get_or_create(
                     defaults=defaults, **kwargs)
                 if created and verbosity > 1:
-                    print _('Created new attribute %(name)s for %(provider)s') % \
-                        {'name': oid, 'provider': provider}
+                    print(_('Created new attribute %(name)s for %(provider)s') % \
+                        {'name': oid, 'provider': provider})
                 pks.append(attribute.pk)
             except SAMLAttribute.MultipleObjectsReturned:
                 pks.extend(SAMLAttribute.objects.filter(**kwargs).values_list('pk', flat=True))
@@ -159,7 +161,7 @@ def load_one_entity(tree, options, sp_policy=None, afp=None):
     sp = check_support_saml2(tree.find(SP_SSO_DESCRIPTOR_TN))
     if options.get('delete'):
         LibertyProvider.objects.filter(entity_id=entity_id).delete()
-        print 'Deleted', entity_id
+        print('Deleted', entity_id)
         return
     if sp:
         # build an unique slug
@@ -177,8 +179,8 @@ def load_one_entity(tree, options, sp_policy=None, afp=None):
                 what = 'Creating'
             else:
                 what = 'Updating'
-            print '%(what)s %(name)s, %(id)s' % {
-                'what': what, 'name': name.encode('utf8'), 'id': entity_id}
+            print('%(what)s %(name)s, %(id)s' % {
+                'what': what, 'name': name.encode('utf8'), 'id': entity_id})
         provider.name = name[:128]
         provider.metadata = etree.tostring(tree, encoding='utf-8').decode('utf-8').strip()
         provider.protocol_conformance = 3
@@ -199,8 +201,8 @@ def load_one_entity(tree, options, sp_policy=None, afp=None):
                     kwargs, defaults = build_saml_attribute_kwargs(provider, name)
                     if not kwargs:
                         if verbosity > 1:
-                            print >>sys.stderr, _('Unable to find an LDAP definition for attribute %(name)s on %(provider)s') % \
-                                {'name': name, 'provider': provider}
+                            print(_('Unable to find an LDAP definition for attribute %(name)s on %(provider)s') % \
+                                {'name': name, 'provider': provider}, file=sys.stderr)
                         continue
                     # create object with default attribute mapping to the same name
                     # as the attribute if no SAMLAttribute model already exists,
@@ -209,7 +211,7 @@ def load_one_entity(tree, options, sp_policy=None, afp=None):
                         attribute, created = SAMLAttribute.objects.get_or_create(
                             defaults=defaults, **kwargs)
                         if created and verbosity > 1:
-                            print (_('Created new attribute %(name)s for %(provider)s')
+                            print(_('Created new attribute %(name)s for %(provider)s')
                                    % {'name': name, 'provider': provider})
                         pks.append(attribute.pk)
                     except SAMLAttribute.MultipleObjectsReturned:
@@ -331,16 +333,17 @@ Any other kind of attribute filter policy is unsupported.
                 try:
                     sp_policy = SPOptionsIdPPolicy.objects.get(name=sp_policy_name)
                     if verbosity > 1:
-                        print 'Service providers are set with the following SAML2 \
-                            options policy: %s' % sp_policy
+                        print('Service providers are set with the following SAML2 \
+                            options policy: %s' % sp_policy)
                 except:
                     if verbosity > 0:
-                        print >>sys.stderr, _('SAML2 service provider options '
-                                              'policy with name %s not found') % sp_policy_name
+                        print(_('SAML2 service provider options '
+                              'policy with name %s not found') % sp_policy_name,
+                              file=sys.stderr)
                         raise CommandError()
             else:
                 if verbosity > 1:
-                    print 'No SAML2 service provider options policy provided'
+                    print('No SAML2 service provider options policy provided')
             loaded = []
             if doc.getroot().tag == ENTITY_DESCRIPTOR_TN:
                 entity_descriptors = [doc.getroot()]
@@ -357,12 +360,13 @@ Any other kind of attribute filter policy is unsupported.
                     if not options['ignore-errors']:
                         raise
                     if verbosity > 0:
-                        print >>sys.stderr, (_('Failed to load entity descriptor for %s')
-                                             % entity_descriptor.get(ENTITY_ID))
+                        print((_('Failed to load entity descriptor for %s')
+                                 % entity_descriptor.get(ENTITY_ID)),
+                                 file=sys.stderr)
                     raise CommandError()
             if options['source']:
                 if options['delete']:
-                    print 'Finally delete all providers for source: %s...' % source
+                    print('Finally delete all providers for source: %s...' % source)
                     LibertyProvider.objects.filter(federation_source=source).delete()
                 else:
                     to_delete = []
@@ -371,10 +375,10 @@ Any other kind of attribute filter policy is unsupported.
                             to_delete.append(provider)
                     for provider in to_delete:
                         if verbosity > 1:
-                            print _('Deleted obsolete provider %s') % provider.entity_id
+                            print(_('Deleted obsolete provider %s') % provider.entity_id)
                         provider.delete()
         else:
             raise CommandError('%s is not a SAMLv2 metadata file' % metadata_file)
         if not options.get('delete'):
             if verbosity > 1:
-                print 'Loaded', options.get('count', 0), 'providers'
+                print('Loaded', options.get('count', 0), 'providers')
diff --git a/src/authentic2/saml/saml11utils.py b/src/authentic2/saml/saml11utils.py
index 63c04c55..fd05c160 100644
--- a/src/authentic2/saml/saml11utils.py
+++ b/src/authentic2/saml/saml11utils.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import xml.etree.ElementTree as etree
 from authentic2.compat_lasso import lasso
 from authentic2.saml import x509utils
@@ -205,4 +207,4 @@ if __name__ == '__main__':
             'SingleSignOn': (('sso',), sso_protocol_profiles),
         }, options)
     root = meta.root_element()
-    print etree.tostring(root)
+    print(etree.tostring(root))
diff --git a/src/authentic2/saml/saml2utils.py b/src/authentic2/saml/saml2utils.py
index 0197eaf2..e444c019 100644
--- a/src/authentic2/saml/saml2utils.py
+++ b/src/authentic2/saml/saml2utils.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import xml.etree.ElementTree as etree
 import collections
 from authentic2.compat_lasso import lasso
@@ -435,4 +437,4 @@ if __name__ == '__main__':
             [ lasso.SAML2_METADATA_BINDING_POST ], 'acs'),),
         options)
     root = meta.root_element()
-    print etree.tostring(root)
+    print(etree.tostring(root))
diff --git a/src/authentic2/saml/shibboleth/afp_parser.py b/src/authentic2/saml/shibboleth/afp_parser.py
index 3fa031e5..59d5dc83 100644
--- a/src/authentic2/saml/shibboleth/afp_parser.py
+++ b/src/authentic2/saml/shibboleth/afp_parser.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import xml.etree.ElementTree as ET
 
 from utils import FancyTreeBuilder
@@ -65,6 +67,6 @@ if __name__ == '__main__':
     import sys
 
     for key, values in parse_attribute_filters_file(sys.argv[1]).iteritems():
-        print '-', key, ':'
+        print('-', key, ':')
         for value in values:
-            print ' *', value
+            print(' *', value)
diff --git a/src/authentic2_auth_oidc/management/commands/oidc-register-issuer.py b/src/authentic2_auth_oidc/management/commands/oidc-register-issuer.py
index 1fbb1db3..12f104e1 100644
--- a/src/authentic2_auth_oidc/management/commands/oidc-register-issuer.py
+++ b/src/authentic2_auth_oidc/management/commands/oidc-register-issuer.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import json
 import pprint
 
@@ -117,16 +119,16 @@ class Command(BaseCommand):
             OIDCClaimMapping.objects.filter(provider=provider, claim__in=delete_claims)
         if options.get('show'):
             for field in OIDCProvider._meta.fields:
-                print unicode(field.verbose_name), ':',
+                print(field.verbose_name, ':')
                 value = getattr(provider, field.name)
                 if isinstance(value, dict):
                     print
                     pprint.pprint(value)
                 elif hasattr(provider, str('get_' + field.attname + '_display')):
-                    print getattr(provider, 'get_' + field.attname + '_display')(), '(%s)' % value
+                    print(getattr(provider, 'get_' + field.attname + '_display')(), '(%s)' % value)
                 else:
-                    print value
-            print 'Mappings:'
+                    print(value)
+            print('Mappings:')
             for claim_mapping in provider.claim_mappings.all():
-                print '-', claim_mapping
+                print('-', claim_mapping)
 
diff --git a/src/authentic2_provisionning_ldap/management/commands/provision.py b/src/authentic2_provisionning_ldap/management/commands/provision.py
index 070e8ee5..241e3a39 100644
--- a/src/authentic2_provisionning_ldap/management/commands/provision.py
+++ b/src/authentic2_provisionning_ldap/management/commands/provision.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 try:
     import ldap
     from ldap.dn import str2dn, dn2str
@@ -154,12 +156,12 @@ class Command(BaseCommand):
                     if not fake:
                         conn.modify(dn, modlist)
                     if verbosity > 1:
-                        print '- Replace %s values for %s' % (dn, ', '.join(ldap_attributes.keys()))
+                        print('- Replace %s values for %s' % (dn, ', '.join(ldap_attributes.keys())))
                 else:
                     if not fake:
                         conn.add(dn, ldap.modlist.addModlist(ldap_attributes))
                     if verbosity > 1:
-                        print '- Add %s with values for %s' % (dn, ', '.join(ldap_attributes.keys()))
+                        print('- Add %s with values for %s' % (dn, ', '.join(ldap_attributes.keys())))
             # wait for results
             if not fake:
                 for x in ldap_users:
@@ -174,7 +176,7 @@ class Command(BaseCommand):
                     todelete.add(dn)
         if delete:
             if verbosity > 1:
-                print '- Deleting:', ', '.join(todelete)
+                print('- Deleting:', ', '.join(todelete))
             if not fake:
                 for dn in todelete:
                     conn.delete(dn)
diff --git a/src/django_rbac/management/commands/cleanup_rbac.py b/src/django_rbac/management/commands/cleanup_rbac.py
index d4717975..7b98a601 100644
--- a/src/django_rbac/management/commands/cleanup_rbac.py
+++ b/src/django_rbac/management/commands/cleanup_rbac.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 from django.core.management.base import BaseCommand
 
 
@@ -11,11 +13,11 @@ class Command(BaseCommand):
         Permission = get_permission_model()
         count = Permission.objects.cleanup()
         if count:
-            print 'Deleted %d permissions.' % count
+            print('Deleted %d permissions.' % count)
 
         Role = get_role_model()
 
         count = 0
         count = Role.objects.cleanup()
         if count:
-            print 'Deleted %d roles.' % count
+            print('Deleted %d roles.' % count)
diff --git a/tests/test_api.py b/tests/test_api.py
index 527bbad8..f22b0586 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+from __future__ import print_function
 
 import json
 import pytest
@@ -775,8 +776,8 @@ def test_users_email(app, ou1, admin, user_ou1, mailoutbox):
 
     assert len(mailoutbox) == 1
     mail = mailoutbox[0]
-    print mail.to
-    print mail.body
+    print(mail.to)
+    print(mail.body)
 
     assert mail.to[0] == new_email
     assert 'http://testserver/accounts/change-email/verify/' in mail.body
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index b1d76517..001e86d5 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import random
 import uuid
 import time
@@ -43,17 +45,17 @@ def test_deterministic_encryption():
             crypted2 = crypto.aes_base64url_deterministic_encrypt(key, raw, salt,
                                                                   hash_name=hash_name, count=count)
             assert crypted1 == crypted2
-            print 'Crypted', hash_name, count, len(crypted1), crypted1
+            print('Crypted', hash_name, count, len(crypted1), crypted1)
 
             t = time.time()
             for i in range(100):
                 crypted1 = crypto.aes_base64url_deterministic_encrypt(key, raw, salt,
                                                                       hash_name=hash_name,
                                                                       count=count)
-            print 'Encryption time:', hash_name, count, (time.time() - t) / 100.0
+            print('Encryption time:', hash_name, count, (time.time() - t) / 100.0)
 
             t = time.time()
             for i in range(1000):
                 assert crypto.aes_base64url_deterministic_decrypt(key, crypted1, salt,
                                                                   max_count=count) == raw
-            print 'Decryption time:', hash_name, count, (time.time() - t) / 1000.0
+            print('Decryption time:', hash_name, count, (time.time() - t) / 1000.0)
-- 
2.20.1

