From c635decb00ac957daf81c08541cdc9cf46f6d86d Mon Sep 17 00:00:00 2001 From: Tommy Allen Date: Tue, 26 Nov 2024 15:15:00 -0500 Subject: [PATCH] Fixed #35942 -- Fixed createsuperuser crash on Python 3.13+ when username is unavailable. Thanks Mariusz Felisiak and Jacob Tyler Walls for reviews. --- django/contrib/auth/management/__init__.py | 10 ++++++---- docs/releases/5.1.4.txt | 3 ++- tests/auth_tests/test_management.py | 7 +++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index c40f2aa69d..a8639cb258 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -115,10 +115,12 @@ def get_system_username(): """ try: result = getpass.getuser() - except (ImportError, KeyError): - # 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). + except (ImportError, KeyError, OSError): + # TODO: Drop ImportError and KeyError when dropping support for PY312. + # KeyError (Python <3.13) or OSError (Python 3.13+) will be raised by + # os.getpwuid() (called by getuser()) if there is no corresponding + # entry in the /etc/passwd file (for example, in a very restricted + # chroot environment). return "" return result diff --git a/docs/releases/5.1.4.txt b/docs/releases/5.1.4.txt index bee40f243e..468bd46381 100644 --- a/docs/releases/5.1.4.txt +++ b/docs/releases/5.1.4.txt @@ -9,4 +9,5 @@ Django 5.1.4 fixes several bugs in 5.1.3. Bugfixes ======== -* ... +* Fixed a crash in ``createsuperuser`` on Python 3.13+ caused by an unhandled + ``OSError`` when the username could not be determined (:ticket:`35942`). diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 8dd91cf6ed..9f12e631cc 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -126,6 +126,13 @@ class GetDefaultUsernameTestCase(TestCase): def test_actual_implementation(self): self.assertIsInstance(management.get_system_username(), str) + def test_getuser_raises_exception(self): + # TODO: Drop ImportError and KeyError when dropping support for PY312. + for exc in (ImportError, KeyError, OSError): + with self.subTest(exc=str(exc)): + with mock.patch("getpass.getuser", side_effect=exc): + self.assertEqual(management.get_system_username(), "") + def test_simple(self): management.get_system_username = lambda: "joe" self.assertEqual(management.get_default_username(), "joe")