Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Patch for ticket #18685 #240

Closed
wants to merge 3 commits into from

1 participant

@cberner

Change the way that management modules are found to use pkgutil instead of imp, so that multiple modules in the same heirarchy can be installed from different setuptools packages. Addresses ticket #18685

cberner added some commits
@cberner cberner Change the way that management modules are found to use pkgutil instead
of imp, so that multiple modules in the same heirarchy can be installed
from different setuptools packages. Addresses ticket #18685
be5eb95
@cberner cberner Add regression test for ticket #18685, which tests that loading
management commands from two different setuptools packages, that are in
the same parent module works correctly.
4ad9b20
@cberner

Added a regression test for this issue. Let me know if there's anything else that's needed, before it can be merged!

@cberner

Closing this pull request, since ptone pointed out the unit test didn't work

@cberner cberner closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 30, 2012
  1. @cberner

    Change the way that management modules are found to use pkgutil instead

    cberner authored
    of imp, so that multiple modules in the same heirarchy can be installed
    from different setuptools packages. Addresses ticket #18685
Commits on Jul 31, 2012
  1. @cberner

    Add regression test for ticket #18685, which tests that loading

    cberner authored
    management commands from two different setuptools packages, that are in
    the same parent module works correctly.
  2. @cberner
This page is out of date. Refresh to see the latest.
View
26 django/core/management/__init__.py
@@ -2,7 +2,7 @@
import os
import sys
from optparse import OptionParser, NO_DEFAULT
-import imp
+import pkgutil
import warnings
from django.core.management.base import BaseCommand, CommandError, handle_default_options
@@ -37,11 +37,8 @@ def find_management_module(app_name):
Raises ImportError if the management module cannot be found for any reason.
"""
- parts = app_name.split('.')
- parts.append('management')
- parts.reverse()
- part = parts.pop()
- path = None
+ module_name = app_name + ".management"
+ loader = pkgutil.find_loader(module_name)
# When using manage.py, the project module is added to the path,
# loaded, then removed from the path. This means that
@@ -49,16 +46,13 @@ def find_management_module(app_name):
# 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 = imp.find_module(part,path)
- except ImportError as e:
- if os.path.basename(os.getcwd()) != part:
- raise e
-
- while parts:
- part = parts.pop()
- f, path, descr = imp.find_module(part, path and [path] or None)
- return path
+ if not loader and os.path.basename(os.getcwd()) == module_name.split('.')[0]:
+ loader = pkgutil.find_loader(".".join(module_name.split(".")[1:]))
+
+ if loader:
+ return loader.filename
+ else:
+ return ''
def load_command_class(app_name, name):
"""
View
0  tests/regressiontests/admin_scripts/project-A/mypackage/A/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/project-A/mypackage/A/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/project-A/mypackage/A/management/commands/__init__.py
No changes.
View
5 tests/regressiontests/admin_scripts/project-A/mypackage/A/management/commands/command_A.py
@@ -0,0 +1,5 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ print "Command A"
View
0  tests/regressiontests/admin_scripts/project-A/mypackage/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/project-B/mypackage/B/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/project-B/mypackage/B/management/__init__.py
No changes.
View
0  tests/regressiontests/admin_scripts/project-B/mypackage/B/management/commands/__init__.py
No changes.
View
5 tests/regressiontests/admin_scripts/project-B/mypackage/B/management/commands/command_B.py
@@ -0,0 +1,5 @@
+from django.core.management.base import BaseCommand
+
+class Command(BaseCommand):
+ def handle(self, *args, **options):
+ print "Command B"
View
1  tests/regressiontests/admin_scripts/project-B/mypackage/__init__.py
@@ -0,0 +1 @@
+
View
17 tests/regressiontests/admin_scripts/tests.py
@@ -17,6 +17,7 @@
from django.test.simple import DjangoTestSuiteRunner
from django.utils import unittest
from django.test import LiveServerTestCase
+from django.core.management import find_management_module
test_dir = os.path.dirname(os.path.dirname(__file__))
@@ -1093,6 +1094,22 @@ def test_liveserver(self):
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = old_address
else:
del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
+
+ def test_modules_from_different_setuptools_packages(self):
+ """Test for ticket 18685. Check that multiple modules in the same package,
+ installed from different setuptools packages, load their management commands
+ correctly.
+ """
+
+ #Add the package directories to the sys path, like setuptools would do,
+ #when running the 'develop' command via an egg-link
+ sys.path.append(os.path.join(os.path.dirname(__file__), "project-A"))
+ sys.path.append(os.path.join(os.path.dirname(__file__), "project-B"))
+
+ module_A_path = find_management_module("mypackage.A")
+ self.assertTrue(module_A_path.endswith("project-A/mypackage/A/management"), module_A_path)
+ module_B_path = find_management_module("mypackage.B")
+ self.assertTrue(module_B_path.endswith("project-B/mypackage/B/management"), module_B_path)
class ManageRunserver(AdminScriptTestCase):
Something went wrong with that request. Please try again.