Code

Ticket #9751: 9751-with-tests.diff

File 9751-with-tests.diff, 7.5 KB (added by ericholscher, 5 years ago)

Basic patch, removed the sys.modules import, and it seems to work without all that split() stuff, but if there's a reason that was there, feel free to add it back.

Line 
1diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
2index f1192fe..026e426 100644
3--- a/django/core/management/__init__.py
4+++ b/django/core/management/__init__.py
5@@ -105,10 +105,9 @@ def get_commands():
6         # Find the project directory
7         try:
8             from django.conf import settings
9-            module = import_module(settings.SETTINGS_MODULE.split('.', 1)[0])
10-            project_directory = setup_environ(module,
11-                                                settings.SETTINGS_MODULE)
12-        except (AttributeError, EnvironmentError, ImportError):
13+            module = import_module(settings.SETTINGS_MODULE)
14+            project_directory = setup_environ(module, settings.SETTINGS_MODULE)
15+        except (AttributeError, EnvironmentError, ImportError, KeyError):
16             project_directory = None
17 
18         # Find and load the management module for each installed app.
19@@ -156,11 +155,11 @@ def call_command(name, *args, **options):
20         raise CommandError, "Unknown command: %r" % name
21 
22     # Grab out a list of defaults from the options. optparse does this for us
23-    # when the script runs from the command line, but since call_command can
24+    # when the script runs from the command line, but since call_command can
25     # be called programatically, we need to simulate the loading and handling
26     # of defaults (see #10080 for details).
27     defaults = dict([(o.dest, o.default)
28-                     for o in klass.option_list
29+                     for o in klass.option_list
30                      if o.default is not NO_DEFAULT])
31     defaults.update(options)
32 
33@@ -316,7 +315,11 @@ def setup_environ(settings_mod, original_settings_path=None):
34     # Add this project to sys.path so that it's importable in the conventional
35     # way. For example, if this file (manage.py) lives in a directory
36     # "myproject", this code would add "/path/to/myproject" to sys.path.
37-    project_directory, settings_filename = os.path.split(settings_mod.__file__)
38+    if '__init__.py' in settings_mod.__file__:
39+        p = os.path.dirname(settings_mod.__file__)
40+    else:
41+        p = settings_mod.__file__
42+    project_directory, settings_filename = os.path.split(p)
43     if project_directory == os.curdir or not project_directory:
44         project_directory = os.getcwd()
45     project_name = os.path.basename(project_directory)
46diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
47index dd2f515..1e15f97 100644
48--- a/tests/regressiontests/admin_scripts/tests.py
49+++ b/tests/regressiontests/admin_scripts/tests.py
50@@ -13,9 +13,14 @@ from django import conf, bin, get_version
51 from django.conf import settings
52 
53 class AdminScriptTestCase(unittest.TestCase):
54-    def write_settings(self, filename, apps=None):
55+    def write_settings(self, filename, apps=None, is_dir=False):
56         test_dir = os.path.dirname(os.path.dirname(__file__))
57-        settings_file = open(os.path.join(test_dir,filename), 'w')
58+        if is_dir:
59+            settings_dir = os.path.join(test_dir,filename)
60+            os.mkdir(settings_dir)
61+            settings_file = open(os.path.join(settings_dir,'__init__.py'), 'w')
62+        else:
63+            settings_file = open(os.path.join(test_dir, filename), 'w')
64         settings_file.write('# Settings file automatically generated by regressiontests.admin_scripts test case\n')
65         exports = [
66             'DATABASE_ENGINE',
67@@ -38,10 +43,13 @@ class AdminScriptTestCase(unittest.TestCase):
68 
69         settings_file.close()
70 
71-    def remove_settings(self, filename):
72+    def remove_settings(self, filename, is_dir=False):
73         test_dir = os.path.dirname(os.path.dirname(__file__))
74         full_name = os.path.join(test_dir, filename)
75-        os.remove(full_name)
76+        if is_dir:
77+            shutil.rmtree(full_name)
78+        else:
79+            os.remove(full_name)
80 
81         # Also try to remove the compiled file; if it exists, it could
82         # mess up later tests that depend upon the .py file not existing
83@@ -509,6 +517,69 @@ class DjangoAdminMultipleSettings(AdminScriptTestCase):
84         self.assertNoOutput(err)
85         self.assertOutput(out, "EXECUTE:NoArgsCommand")
86 
87+
88+class DjangoAdminSettingsDirectory(AdminScriptTestCase):
89+    """A series of tests for django-admin.py when the settings file
90+    is in a directory.
91+    """
92+    def setUp(self):
93+        self.write_settings('settings', is_dir=True)
94+
95+    def tearDown(self):
96+        self.remove_settings('settings', is_dir=True)
97+
98+    #Regression test for 9751
99+    def test_setup_environ(self):
100+        "directory: startapp creates the correct directory"
101+        test_dir = os.path.dirname(os.path.dirname(__file__))
102+        args = ['startapp','settings_test']
103+        out, err = self.run_django_admin(args,'settings')
104+        self.assertNoOutput(err)
105+        self.assertTrue(os.path.exists(os.path.join(test_dir, 'settings_test')))
106+        shutil.rmtree(os.path.join(test_dir, 'settings_test'))
107+
108+    def test_builtin_command(self):
109+        "directory: django-admin builtin commands fail with an import error when no settings provided"
110+        args = ['sqlall','admin_scripts']
111+        out, err = self.run_django_admin(args)
112+        self.assertNoOutput(out)
113+        self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is undefined')
114+
115+    def test_builtin_with_bad_settings(self):
116+        "directory: django-admin builtin commands fail if settings file (from argument) doesn't exist"
117+        args = ['sqlall','--settings=bad_settings', 'admin_scripts']
118+        out, err = self.run_django_admin(args)
119+        self.assertOutput(err, "Could not import settings 'bad_settings'")
120+
121+    def test_builtin_with_bad_environment(self):
122+        "directory: django-admin builtin commands fail if settings file (from environment) doesn't exist"
123+        args = ['sqlall','admin_scripts']
124+        out, err = self.run_django_admin(args,'bad_settings')
125+        self.assertNoOutput(out)
126+        self.assertOutput(err, "Could not import settings 'bad_settings'")
127+
128+    def test_custom_command(self):
129+        "directory: django-admin can't execute user commands unless settings are provided"
130+        args = ['noargs_command']
131+        out, err = self.run_django_admin(args)
132+        self.assertNoOutput(out)
133+        self.assertOutput(err, "Unknown command: 'noargs_command'")
134+
135+    def test_builtin_with_settings(self):
136+        "directory: django-admin builtin commands succeed if settings are provided as argument"
137+        args = ['sqlall','--settings=settings', 'admin_scripts']
138+        out, err = self.run_django_admin(args)
139+        self.assertNoOutput(err)
140+        self.assertOutput(out, 'CREATE TABLE')
141+
142+    def test_builtin_with_environment(self):
143+        "directory: django-admin builtin commands succeed if settings are provided in the environment"
144+        args = ['sqlall','admin_scripts']
145+        out, err = self.run_django_admin(args,'settings')
146+        self.assertNoOutput(err)
147+        self.assertOutput(out, 'CREATE TABLE')
148+
149+
150 ##########################################################################
151 # MANAGE.PY TESTS
152 # This next series of test classes checks the environment processing
153@@ -1075,4 +1146,3 @@ class ArgumentOrder(AdminScriptTestCase):
154         out, err = self.run_manage(args)
155         self.assertNoOutput(err)
156         self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
157-