Author: jacob
Date: 2009-05-12 16:45:03 -0500 (Tue, 12 May 2009)
New Revision: 10751

Modified:
   django/trunk/django/core/management/__init__.py
   django/trunk/tests/regressiontests/admin_scripts/tests.py
Log:
Fixed #9751: admin scripts now calculate the project directory correctly when 
the settings module is a directory with an ``__init__.py``. Thanks to Eric 
Holscher.

Modified: django/trunk/django/core/management/__init__.py
===================================================================
--- django/trunk/django/core/management/__init__.py     2009-05-12 20:32:03 UTC 
(rev 10750)
+++ django/trunk/django/core/management/__init__.py     2009-05-12 21:45:03 UTC 
(rev 10751)
@@ -105,10 +105,9 @@
         # Find the project directory
         try:
             from django.conf import settings
-            module = import_module(settings.SETTINGS_MODULE.split('.', 1)[0])
-            project_directory = setup_environ(module,
-                                                settings.SETTINGS_MODULE)
-        except (AttributeError, EnvironmentError, ImportError):
+            module = import_module(settings.SETTINGS_MODULE)
+            project_directory = setup_environ(module, settings.SETTINGS_MODULE)
+        except (AttributeError, EnvironmentError, ImportError, KeyError):
             project_directory = None
 
         # Find and load the management module for each installed app.
@@ -156,11 +155,11 @@
         raise CommandError, "Unknown command: %r" % name
 
     # Grab out a list of defaults from the options. optparse does this for us
-    # when the script runs from the command line, but since call_command can 
+    # when the script runs from the command line, but since call_command can
     # be called programatically, we need to simulate the loading and handling
     # of defaults (see #10080 for details).
     defaults = dict([(o.dest, o.default)
-                     for o in klass.option_list 
+                     for o in klass.option_list
                      if o.default is not NO_DEFAULT])
     defaults.update(options)
 
@@ -316,7 +315,11 @@
     # Add this project to sys.path so that it's importable in the conventional
     # way. For example, if this file (manage.py) lives in a directory
     # "myproject", this code would add "/path/to/myproject" to sys.path.
-    project_directory, settings_filename = os.path.split(settings_mod.__file__)
+    if '__init__.py' in settings_mod.__file__:
+        p = os.path.dirname(settings_mod.__file__)
+    else:
+        p = settings_mod.__file__
+    project_directory, settings_filename = os.path.split(p)
     if project_directory == os.curdir or not project_directory:
         project_directory = os.getcwd()
     project_name = os.path.basename(project_directory)

Modified: django/trunk/tests/regressiontests/admin_scripts/tests.py
===================================================================
--- django/trunk/tests/regressiontests/admin_scripts/tests.py   2009-05-12 
20:32:03 UTC (rev 10750)
+++ django/trunk/tests/regressiontests/admin_scripts/tests.py   2009-05-12 
21:45:03 UTC (rev 10751)
@@ -13,9 +13,14 @@
 from django.conf import settings
 
 class AdminScriptTestCase(unittest.TestCase):
-    def write_settings(self, filename, apps=None):
+    def write_settings(self, filename, apps=None, is_dir=False):
         test_dir = os.path.dirname(os.path.dirname(__file__))
-        settings_file = open(os.path.join(test_dir,filename), 'w')
+        if is_dir:
+            settings_dir = os.path.join(test_dir,filename)
+            os.mkdir(settings_dir)
+            settings_file = open(os.path.join(settings_dir,'__init__.py'), 'w')
+        else:
+            settings_file = open(os.path.join(test_dir, filename), 'w')
         settings_file.write('# Settings file automatically generated by 
regressiontests.admin_scripts test case\n')
         exports = [
             'DATABASE_ENGINE',
@@ -38,10 +43,13 @@
 
         settings_file.close()
 
-    def remove_settings(self, filename):
+    def remove_settings(self, filename, is_dir=False):
         test_dir = os.path.dirname(os.path.dirname(__file__))
         full_name = os.path.join(test_dir, filename)
-        os.remove(full_name)
+        if is_dir:
+            shutil.rmtree(full_name)
+        else:
+            os.remove(full_name)
 
         # Also try to remove the compiled file; if it exists, it could
         # mess up later tests that depend upon the .py file not existing
@@ -509,6 +517,70 @@
         self.assertNoOutput(err)
         self.assertOutput(out, "EXECUTE:NoArgsCommand")
 
+
+class DjangoAdminSettingsDirectory(AdminScriptTestCase):
+    """
+    A series of tests for django-admin.py when the settings file is in a
+    directory. (see #9751).
+    """
+    
+    def setUp(self):
+        self.write_settings('settings', is_dir=True)
+
+    def tearDown(self):
+        self.remove_settings('settings', is_dir=True)
+
+    def test_setup_environ(self):
+        "directory: startapp creates the correct directory"
+        test_dir = os.path.dirname(os.path.dirname(__file__))
+        args = ['startapp','settings_test']
+        out, err = self.run_django_admin(args,'settings')
+        self.assertNoOutput(err)
+        self.assertTrue(os.path.exists(os.path.join(test_dir, 
'settings_test')))
+        shutil.rmtree(os.path.join(test_dir, 'settings_test'))
+
+    def test_builtin_command(self):
+        "directory: django-admin builtin commands fail with an import error 
when no settings provided"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, 'environment variable DJANGO_SETTINGS_MODULE is 
undefined')
+
+    def test_builtin_with_bad_settings(self):
+        "directory: django-admin builtin commands fail if settings file (from 
argument) doesn't exist"
+        args = ['sqlall','--settings=bad_settings', 'admin_scripts']
+        out, err = self.run_django_admin(args)
+        self.assertOutput(err, "Could not import settings 'bad_settings'")
+
+    def test_builtin_with_bad_environment(self):
+        "directory: django-admin builtin commands fail if settings file (from 
environment) doesn't exist"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_django_admin(args,'bad_settings')
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Could not import settings 'bad_settings'")
+
+    def test_custom_command(self):
+        "directory: django-admin can't execute user commands unless settings 
are provided"
+        args = ['noargs_command']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Unknown command: 'noargs_command'")
+
+    def test_builtin_with_settings(self):
+        "directory: django-admin builtin commands succeed if settings are 
provided as argument"
+        args = ['sqlall','--settings=settings', 'admin_scripts']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+    def test_builtin_with_environment(self):
+        "directory: django-admin builtin commands succeed if settings are 
provided in the environment"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_django_admin(args,'settings')
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+
 ##########################################################################
 # MANAGE.PY TESTS
 # This next series of test classes checks the environment processing
@@ -1075,4 +1147,3 @@
         out, err = self.run_manage(args)
         self.assertNoOutput(err)
         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')]")
-


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to