diff options
author | Claude Paroz <claude@2xlibre.net> | 2013-10-17 18:57:44 +0200 |
---|---|---|
committer | Claude Paroz <claude@2xlibre.net> | 2013-10-18 14:05:26 +0200 |
commit | 621fc1f1d74df2d9240dea88b5f7ebdf472bca38 (patch) | |
tree | 8ba1f170d54e42deb94a6157d3938ec1d0e3efe5 | |
parent | 37afcbeb92cd556ff1081c9db5a4a320efd5b7a3 (diff) | |
download | django-621fc1f1d74df2d9240dea88b5f7ebdf472bca38.tar.gz |
[1.6.x] Fixed #21284 -- Prevented KeyError swallowing in fetch_command
Thanks wildfire for the report.
Backport of 3514bcb251 from master.
-rw-r--r-- | django/core/management/__init__.py | 4 | ||||
-rw-r--r-- | tests/admin_scripts/tests.py | 32 |
2 files changed, 21 insertions, 15 deletions
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 8fd46aa759..5b0ad6c4b9 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -257,8 +257,10 @@ class ManagementUtility(object): appropriate command called from the command line (usually "django-admin.py" or "manage.py") if it can't be found. """ + # Get commands outside of try block to prevent swallowing exceptions + commands = get_commands() try: - app_name = get_commands()[subcommand] + app_name = commands[subcommand] except KeyError: sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \ (subcommand, self.prog_name)) diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index a6f7845b20..9a6cf06a60 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -1004,28 +1004,24 @@ class ManageMultipleSettings(AdminScriptTestCase): self.assertOutput(out, "EXECUTE:NoArgsCommand") -class ManageSettingsWithImportError(AdminScriptTestCase): - """Tests for manage.py when using the default settings.py file - with an import error. Ticket #14130. +class ManageSettingsWithSettingsErrors(AdminScriptTestCase): + """ + Tests for manage.py when using the default settings.py file containing + runtime errors. """ def tearDown(self): self.remove_settings('settings.py') - def write_settings_with_import_error(self, filename, apps=None, is_dir=False, sdict=None): - if is_dir: - settings_dir = os.path.join(test_dir, filename) - os.mkdir(settings_dir) - settings_file_path = os.path.join(settings_dir, '__init__.py') - else: - settings_file_path = os.path.join(test_dir, filename) + def write_settings_with_import_error(self, filename): + settings_file_path = os.path.join(test_dir, filename) with open(settings_file_path, 'w') as settings_file: settings_file.write('# Settings file automatically generated by admin_scripts test case\n') settings_file.write('# The next line will cause an import error:\nimport foo42bar\n') - def test_builtin_command(self): + def test_import_error(self): """ import error: manage.py builtin commands shows useful diagnostic info - when settings with import errors is provided + when settings with import errors is provided (#14130). """ self.write_settings_with_import_error('settings.py') args = ['sqlall', 'admin_scripts'] @@ -1034,9 +1030,10 @@ class ManageSettingsWithImportError(AdminScriptTestCase): self.assertOutput(err, "No module named") self.assertOutput(err, "foo42bar") - def test_builtin_command_with_attribute_error(self): + def test_attribute_error(self): """ - manage.py builtin commands does not swallow attribute errors from bad settings (#18845) + manage.py builtin commands does not swallow attribute error due to bad + settings (#18845). """ self.write_settings('settings.py', sdict={'BAD_VAR': 'INSTALLED_APPS.crash'}) args = ['collectstatic', 'admin_scripts'] @@ -1044,6 +1041,13 @@ class ManageSettingsWithImportError(AdminScriptTestCase): self.assertNoOutput(out) self.assertOutput(err, "AttributeError: 'list' object has no attribute 'crash'") + def test_key_error(self): + self.write_settings('settings.py', sdict={'BAD_VAR': 'DATABASES["blah"]'}) + args = ['collectstatic', 'admin_scripts'] + out, err = self.run_manage(args) + self.assertNoOutput(out) + self.assertOutput(err, "KeyError: 'blah'") + class ManageValidate(AdminScriptTestCase): def tearDown(self): |