Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Made createsuperuser more robust when getting current OS username.

Under some versions of OS X, failure in getting the default system
locale during the syncdb operation of the auth app were causing hard to
diagnose problems afterwards.

No solution based on getpreferredencoding() was chosen because it has
its own problems with certain combinations of Python and OS X versions
(e.g. http://bugs.python.org/issue6202).

Thanks prestonsimmons for the report and prestonsimmons and willhardy
for the initial patch.

Fixes #16017.
  • Loading branch information...
commit 4c934f3921a59c7b3e088f6472b6f6da40848567 1 parent 6e4c984
@ramiro ramiro authored
View
19 django/contrib/auth/management/__init__.py
@@ -84,14 +84,17 @@ def get_system_username():
:returns: The username as a unicode string, or an empty string if the
username could not be determined.
"""
- try:
- return getpass.getuser().decode(locale.getdefaultlocale()[1])
- except (ImportError, KeyError, UnicodeDecodeError):
- # KeyError will be raised by os.getpwuid() (called by getuser())
- # if there is no corresponding entry in the /etc/passwd file
- # (a very restricted chroot environment, for example).
- # UnicodeDecodeError - preventive treatment for non-latin Windows.
- return ''
+ default_locale = locale.getdefaultlocale()[1]
+ if default_locale:
+ try:
+ return getpass.getuser().decode(default_locale)
+ except (ImportError, KeyError, UnicodeDecodeError):
+ # KeyError will be raised by os.getpwuid() (called by getuser())
+ # if there is no corresponding entry in the /etc/passwd file
+ # (a very restricted chroot environment, for example).
+ # UnicodeDecodeError - preventive treatment for non-latin Windows.
+ pass
+ return ''
def get_default_username(check_db=True):
View
44 django/contrib/auth/tests/basic.py
@@ -1,13 +1,11 @@
+import locale
+import traceback
+
+from django.contrib.auth.management.commands import createsuperuser
from django.contrib.auth.models import User, AnonymousUser
from django.core.management import call_command
from django.test import TestCase
from django.utils.six import StringIO
-from django.utils.unittest import skipUnless
-
-try:
- import crypt as crypt_module
-except ImportError:
- crypt_module = None
class BasicTestCase(TestCase):
@@ -111,3 +109,37 @@ def test_createsuperuser_management_command(self):
u = User.objects.get(username="joe+admin@somewhere.org")
self.assertEqual(u.email, 'joe@somewhere.org')
self.assertFalse(u.has_usable_password())
+
+ def test_createsuperuser_nolocale(self):
+ """
+ Check that createsuperuser does not break when no locale is set. See
+ ticket #16017.
+ """
+
+ old_getdefaultlocale = locale.getdefaultlocale
+ old_getpass = createsuperuser.getpass
+ try:
+ # Temporarily remove locale information
+ locale.getdefaultlocale = lambda: (None, None)
+
+ # Temporarily replace getpass to allow interactive code to be used
+ # non-interactively
+ class mock_getpass: pass
+ mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
+ createsuperuser.getpass = mock_getpass
+
+ # Call the command in this new environment
+ new_io = StringIO()
+ call_command("createsuperuser", interactive=True, username="nolocale@somewhere.org", email="nolocale@somewhere.org", stdout=new_io)
+
+ except TypeError as e:
+ self.fail("createsuperuser fails if the OS provides no information about the current locale")
+
+ finally:
+ # Re-apply locale and getpass information
+ createsuperuser.getpass = old_getpass
+ locale.getdefaultlocale = old_getdefaultlocale
+
+ # If we were successful, a user should have been created
+ u = User.objects.get(username="nolocale@somewhere.org")
+ self.assertEqual(u.email, 'nolocale@somewhere.org')
Please sign in to comment.
Something went wrong with that request. Please try again.