diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 7dcbfe47463..83e15183877 100644 --- a/django/contrib/auth/management/__init__.py +++ b/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): diff --git a/django/contrib/auth/tests/basic.py b/django/contrib/auth/tests/basic.py index 21acb2004f6..710754b8f1e 100644 --- a/django/contrib/auth/tests/basic.py +++ b/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 @@ class BasicTestCase(TestCase): 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')