Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Look in child dirs when discovering django project #586

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

Features
^^^^^^^^
* pytest-django now searches the immediate subdirectories of the current
working directory when trying to find the Django project.

3.1.2
-----

Expand Down
8 changes: 4 additions & 4 deletions docs/managing_python_path.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ By default, pytest-django tries to find Django projects by automatically
looking for the project's ``manage.py`` file and adding its directory to the
Python path.

Looking for the ``manage.py`` file uses the same algorithm as pytest uses to
find ``pytest.ini``, ``tox.ini`` and ``setup.cfg``: Each test root directories
parents will be searched for ``manage.py`` files, and it will stop when the
first file is found.
Looking for the ``manage.py`` file uses the following algorithm:
Beginning at each directory given on the command line (or the current working
directory if none is given), the directory itself, its immediate children and
its parents are searched, and it will stop when the first file is found.

If you have a custom project setup, have none or multiple ``manage.py`` files
in your project, the automatic detection may not be correct. See
Expand Down
50 changes: 27 additions & 23 deletions pytest_django/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import sys
import types

import py
import pathlib
import pytest

from .django_compat import is_django_unittest # noqa
Expand Down Expand Up @@ -88,13 +88,6 @@ def pytest_addoption(parser):
type='bool', default=False)


def _exists(path, ignore=EnvironmentError):
try:
return path.check()
except ignore:
return False


PROJECT_FOUND = ('pytest-django found a Django project in %s '
'(it contains manage.py) and added it to the Python path.\n'
'If this is wrong, add "django_find_project = false" to '
Expand All @@ -121,22 +114,33 @@ def _handle_import_error(extra_message):


def _add_django_project_to_path(args):
args = [x for x in args if not str(x).startswith("-")]

if not args:
args = [py.path.local()]

for arg in args:
arg = py.path.local(arg)

for base in arg.parts(reverse=True):
manage_py_try = base.join('manage.py')

if _exists(manage_py_try):
sys.path.insert(0, str(base))
return PROJECT_FOUND % base
def is_django_project(path):
return path.is_dir() and (path / 'manage.py').exists()

def find_django_path(args):
args = [pathlib.Path(x) for x in args if not str(x).startswith("-")]
args = [p for p in args if p.is_dir()]

if not args:
args = [pathlib.Path.cwd()]

for arg in args:
if is_django_project(arg):
return arg
for child in arg.iterdir():
if is_django_project(child):
return child
for parent in arg.parents:
if is_django_project(parent):
return parent
return None

return PROJECT_NOT_FOUND
project_dir = find_django_path(args)
if project_dir:
sys.path.insert(0, str(project_dir))
return PROJECT_FOUND % project_dir
else:
return PROJECT_NOT_FOUND


def _setup_django():
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ def read(fname):
long_description=read('README.rst'),
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
setup_requires=['setuptools_scm>=1.11.1'],
install_requires=['pytest>=2.9'],
install_requires=[
'pytest>=2.9',
'pathlib;python_version<"3.4"',
'six',
],
classifiers=['Development Status :: 5 - Production/Stable',
'Framework :: Django',
'Framework :: Django :: 1.8',
Expand Down
11 changes: 6 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
import shutil
from textwrap import dedent

import py
import pathlib
import pytest
import six
from django.conf import settings

from pytest_django_test.db_helpers import DB_NAME, TEST_DB_NAME

pytest_plugins = 'pytester'

REPOSITORY_ROOT = py.path.local(__file__).join('..')
REPOSITORY_ROOT = pathlib.Path(__file__).parent


def pytest_configure(config):
Expand Down Expand Up @@ -99,12 +100,12 @@ def django_testdir(request, testdir, monkeypatch):

tpkg_path.ensure('__init__.py')

app_source = REPOSITORY_ROOT.dirpath('pytest_django_test/app')
app_source = REPOSITORY_ROOT / '../pytest_django_test/app'
test_app_path = tpkg_path.join('app')

# Copy the test app to make it available in the new test run
shutil.copytree(py.builtin._totext(app_source),
py.builtin._totext(test_app_path))
shutil.copytree(six.text_type(app_source),
six.text_type(test_app_path))
tpkg_path.join("the_settings.py").write(test_settings)

monkeypatch.setenv('DJANGO_SETTINGS_MODULE', 'tpkg.the_settings')
Expand Down