Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.5.x] Fixed #19725 -- Made createsuperuser handle non-ascii prompts

Thanks Michisu for the report.
Backport of 55c585f from master.
  • Loading branch information...
commit f5232597ea31bf274b02983f32ba89be4f7bf02b 1 parent 6155b66
Claude Paroz authored February 04, 2013
8  django/contrib/auth/management/commands/createsuperuser.py
@@ -11,6 +11,7 @@
11 11
 from django.core import exceptions
12 12
 from django.core.management.base import BaseCommand, CommandError
13 13
 from django.db import DEFAULT_DB_ALIAS
  14
+from django.utils.encoding import force_str
14 15
 from django.utils.six.moves import input
15 16
 from django.utils.text import capfirst
16 17
 
@@ -83,8 +84,9 @@ def handle(self, *args, **options):
83 84
                     if not username:
84 85
                         input_msg = capfirst(self.username_field.verbose_name)
85 86
                         if default_username:
86  
-                            input_msg += " (leave blank to use '%s')" % default_username
87  
-                        raw_value = input(input_msg + ': ')
  87
+                            input_msg = "%s (leave blank to use '%s')" % (
  88
+                                input_msg, default_username)
  89
+                        raw_value = input(force_str('%s: ' % input_msg))
88 90
 
89 91
                     if default_username and raw_value == '':
90 92
                         raw_value = default_username
@@ -107,7 +109,7 @@ def handle(self, *args, **options):
107 109
                     field = self.UserModel._meta.get_field(field_name)
108 110
                     user_data[field_name] = options.get(field_name)
109 111
                     while user_data[field_name] is None:
110  
-                        raw_value = input(capfirst(field.verbose_name + ': '))
  112
+                        raw_value = input(force_str('%s: ' % capfirst(field.verbose_name)))
111 113
                         try:
112 114
                             user_data[field_name] = field.clean(raw_value, None)
113 115
                         except exceptions.ValidationError as e:
70  django/contrib/auth/tests/basic.py
... ...
@@ -1,3 +1,6 @@
  1
+# -*- encoding: utf-8 -*-
  2
+from __future__ import unicode_literals
  3
+
1 4
 import locale
2 5
 
3 6
 from django.contrib.auth import get_user_model
@@ -12,6 +15,37 @@
12 15
 from django.utils.six import StringIO
13 16
 
14 17
 
  18
+def mock_inputs(inputs):
  19
+    """
  20
+    Decorator to temporarily replace input/getpass to allow interactive
  21
+    createsuperuser.
  22
+    """
  23
+    def inner(test_func):
  24
+        def wrapped(*args):
  25
+            class mock_getpass:
  26
+                pass
  27
+            mock_getpass.getpass = staticmethod(lambda p=None: inputs['password'])
  28
+
  29
+            def mock_input(prompt):
  30
+                # prompt should be encoded in Python 2. This line will raise an
  31
+                # Exception if prompt contains unencoded non-ascii on Python 2.
  32
+                prompt = str(prompt)
  33
+                if str('leave blank to use') in prompt:
  34
+                    return inputs['username']
  35
+
  36
+            old_getpass = createsuperuser.getpass
  37
+            old_input = createsuperuser.input
  38
+            createsuperuser.getpass = mock_getpass
  39
+            createsuperuser.input = mock_input
  40
+            try:
  41
+                test_func(*args)
  42
+            finally:
  43
+                createsuperuser.getpass = old_getpass
  44
+                createsuperuser.input = old_input
  45
+        return wrapped
  46
+    return inner
  47
+
  48
+
15 49
 @skipIfCustomUser
16 50
 class BasicTestCase(TestCase):
17 51
     def test_user(self):
@@ -103,17 +137,17 @@ def test_createsuperuser_management_command(self):
103 137
         self.assertEqual(u.email, 'joe2@somewhere.org')
104 138
         self.assertFalse(u.has_usable_password())
105 139
 
106  
-        new_io = StringIO()
107 140
         call_command("createsuperuser",
108 141
             interactive=False,
109 142
             username="joe+admin@somewhere.org",
110 143
             email="joe@somewhere.org",
111  
-            stdout=new_io
  144
+            verbosity=0
112 145
         )
113 146
         u = User.objects.get(username="joe+admin@somewhere.org")
114 147
         self.assertEqual(u.email, 'joe@somewhere.org')
115 148
         self.assertFalse(u.has_usable_password())
116 149
 
  150
+    @mock_inputs({'password': "nopasswd"})
117 151
     def test_createsuperuser_nolocale(self):
118 152
         """
119 153
         Check that createsuperuser does not break when no locale is set. See
@@ -121,39 +155,47 @@ def test_createsuperuser_nolocale(self):
121 155
         """
122 156
 
123 157
         old_getdefaultlocale = locale.getdefaultlocale
124  
-        old_getpass = createsuperuser.getpass
125 158
         try:
126 159
             # Temporarily remove locale information
127 160
             locale.getdefaultlocale = lambda: (None, None)
128 161
 
129  
-            # Temporarily replace getpass to allow interactive code to be used
130  
-            # non-interactively
131  
-            class mock_getpass:
132  
-                pass
133  
-            mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
134  
-            createsuperuser.getpass = mock_getpass
135  
-
136 162
             # Call the command in this new environment
137  
-            new_io = StringIO()
138 163
             call_command("createsuperuser",
139 164
                 interactive=True,
140 165
                 username="nolocale@somewhere.org",
141 166
                 email="nolocale@somewhere.org",
142  
-                stdout=new_io
  167
+                verbosity=0
143 168
             )
144 169
 
145 170
         except TypeError:
146 171
             self.fail("createsuperuser fails if the OS provides no information about the current locale")
147 172
 
148 173
         finally:
149  
-            # Re-apply locale and getpass information
150  
-            createsuperuser.getpass = old_getpass
  174
+            # Re-apply locale information
151 175
             locale.getdefaultlocale = old_getdefaultlocale
152 176
 
153 177
         # If we were successful, a user should have been created
154 178
         u = User.objects.get(username="nolocale@somewhere.org")
155 179
         self.assertEqual(u.email, 'nolocale@somewhere.org')
156 180
 
  181
+    @mock_inputs({'password': "nopasswd", 'username': 'foo'})
  182
+    def test_createsuperuser_non_ascii_verbose_name(self):
  183
+        username_field = User._meta.get_field('username')
  184
+        old_verbose_name = username_field.verbose_name
  185
+        username_field.verbose_name = 'uživatel'
  186
+        new_io = StringIO()
  187
+        try:
  188
+            call_command("createsuperuser",
  189
+                interactive=True,
  190
+                email="nolocale@somewhere.org",
  191
+                stdout=new_io
  192
+            )
  193
+        finally:
  194
+            username_field.verbose_name = old_verbose_name
  195
+
  196
+        command_output = new_io.getvalue().strip()
  197
+        self.assertEqual(command_output, 'Superuser created successfully.')
  198
+
157 199
     def test_get_user_model(self):
158 200
         "The current user model can be retrieved"
159 201
         self.assertEqual(get_user_model(), User)

0 notes on commit f523259

Please sign in to comment.
Something went wrong with that request. Please try again.