Commits

russ...@bcc190cf-cafb-0310-a4f2-bffc1f526a37  committed 400088f

Fixed #5825 -- Modified the custom command loader to allow for explicit specification of the project name, even if the project directory isn't in the python path. This brings custom command loading into alignment with application loading. Thanks to jdetaeye@frepple.com for the original report, and to abozanich for the patch.

  • Participants
  • Parent commits 6d8aefa

Comments (0)

Files changed (2)

File django/core/management/__init__.py

     parts = app_name.split('.')
     parts.append('management')
     parts.reverse()
+    part = parts.pop()
     path = None
+    
+    # When using manage.py, the project module is added to the path,
+    # loaded, then removed from the path. This means that 
+    # testproject.testapp.models can be loaded in future, even if
+    # testproject isn't in the path. When looking for the management
+    # module, we need look for the case where the project name is part
+    # of the app_name but the project directory itself isn't on the path.
+    try:
+        f, path, descr = find_module(part,path) 
+    except ImportError,e:
+        if os.path.basename(os.getcwd()) != part:
+            raise e
+        
     while parts:
         part = parts.pop()
         f, path, descr = find_module(part, path and [path] or None)

File tests/regressiontests/admin_scripts/tests.py

         self.assertNoOutput(out)
         self.assertOutput(err, "Unknown command: 'noargs_command'")
 
+class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
+    """A series of tests for django-admin.py when using a settings.py file that
+    contains the test application specified using a full path.
+    """
+    def setUp(self):
+        self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'regressiontests.admin_scripts'])
+
+    def tearDown(self):
+        self.remove_settings('settings.py')
+
+    def test_builtin_command(self):
+        "fulldefault: 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_settings(self):
+        "fulldefault: django-admin builtin commands fail if user app isn't on path"
+        args = ['sqlall','--settings=settings', 'admin_scripts']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, 'ImportError: No module named regressiontests')
+
+    def test_builtin_with_environment(self):
+        "fulldefault: django-admin builtin commands fail if user app isn't on path"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_django_admin(args,'settings')
+        self.assertNoOutput(out)
+        self.assertOutput(err, 'ImportError: No module named regressiontests')
+
+    def test_builtin_with_bad_settings(self):
+        "fulldefault: 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.assertNoOutput(out)
+        self.assertOutput(err, "Could not import settings 'bad_settings'")
+
+    def test_builtin_with_bad_environment(self):
+        "fulldefault: 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):
+        "fulldefault: django-admin can't execute user commands"
+        args = ['noargs_command']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Unknown command: 'noargs_command'")
+
+    def test_custom_command_with_settings(self):
+        "fulldefault: django-admin can't execute user commands, even if settings are provided as argument"
+        args = ['noargs_command', '--settings=settings']
+        out, err = self.run_django_admin(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Unknown command: 'noargs_command'")
+
+    def test_custom_command_with_environment(self):
+        "fulldefault: django-admin can't execute user commands, even if settings are provided in environment"
+        args = ['noargs_command']
+        out, err = self.run_django_admin(args,'settings')
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Unknown command: 'noargs_command'")
+
 class DjangoAdminMinimalSettings(AdminScriptTestCase):
     """A series of tests for django-admin.py when using a settings.py file that
     doesn't contain the test application.
         self.assertNoOutput(err)
         self.assertOutput(out, "EXECUTE:NoArgsCommand")
 
+
+class ManageFullPathDefaultSettings(AdminScriptTestCase):
+    """A series of tests for manage.py when using a settings.py file that
+    contains the test application specified using a full path.
+    """
+    def setUp(self):
+        self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'regressiontests.admin_scripts'])
+
+    def tearDown(self):
+        self.remove_settings('settings.py')
+
+    def test_builtin_command(self):
+        "fulldefault: manage.py builtin commands succeed when default settings are appropriate"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+    def test_builtin_with_settings(self):
+        "fulldefault: manage.py builtin commands succeed if settings are provided as argument"
+        args = ['sqlall','--settings=settings', 'admin_scripts']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+    def test_builtin_with_environment(self):
+        "fulldefault: manage.py builtin commands succeed if settings are provided in the environment"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_manage(args,'settings')
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+    def test_builtin_with_bad_settings(self):
+        "fulldefault: manage.py builtin commands succeed if settings file (from argument) doesn't exist"
+        args = ['sqlall','--settings=bad_settings', 'admin_scripts']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(out)
+        self.assertOutput(err, "Could not import settings 'bad_settings'")
+
+    def test_builtin_with_bad_environment(self):
+        "fulldefault: manage.py builtin commands fail if settings file (from environment) doesn't exist"
+        args = ['sqlall','admin_scripts']
+        out, err = self.run_manage(args,'bad_settings')
+        self.assertNoOutput(err)
+        self.assertOutput(out, 'CREATE TABLE')
+
+    def test_custom_command(self):
+        "fulldefault: manage.py can execute user commands when default settings are appropriate"
+        args = ['noargs_command']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
+
+    def test_custom_command_with_settings(self):
+        "fulldefault: manage.py can execute user commands when settings are provided as argument"
+        args = ['noargs_command', '--settings=settings']
+        out, err = self.run_manage(args)
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
+
+    def test_custom_command_with_environment(self):
+        "fulldefault: manage.py can execute user commands when settings are provided in environment"
+        args = ['noargs_command']
+        out, err = self.run_manage(args,'settings')
+        self.assertNoOutput(err)
+        self.assertOutput(out, "EXECUTE:NoArgsCommand")
+
 class ManageMinimalSettings(AdminScriptTestCase):
     """A series of tests for manage.py when using a settings.py file that
     doesn't contain the test application.