diff --git a/.circleci/config.yml b/.circleci/config.yml index 366c67d..fef109c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: name: run coverage command: | . venv/bin/activate - pip install -e . + pip install -e ".[tests]" py.test --cov=. --cov-fail-under=100 - run: name: upload coverage report diff --git a/.gitignore b/.gitignore index 894a44c..4b5cfcd 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ venv.bak/ # mypy .mypy_cache/ + +# IntelliJ +.idea diff --git a/README.md b/README.md index bf9da53..613208e 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ $ pytest --cov=. | `DJ06` | ModelForm should not set exclude, instead it should use fields, which is an explicit list of all the fields that should be included in the form | | `DJ07` | ModelForm.Meta should not set fields to `__all__`| | `DJ08` | Models that inherits from django db models should set `__str__`| +| `DJ09` | New applications should avoid default_app_config| ## Licence diff --git a/flake8_django/checker.py b/flake8_django/checker.py index db318c9..936ebd7 100644 --- a/flake8_django/checker.py +++ b/flake8_django/checker.py @@ -1,6 +1,7 @@ import ast -from flake8_django.checkers import ModelDunderStrMissingChecker, ModelFieldChecker, ModelFormChecker, URLChecker, RenderChecker +from flake8_django.checkers import DefaultAppConfigChecker, ModelDunderStrMissingChecker, ModelFieldChecker, \ + ModelFormChecker, URLChecker, RenderChecker __version__ = '0.0.3' @@ -18,7 +19,10 @@ class DjangoStyleFinder(ast.NodeVisitor): 'ClassDef': [ ModelFormChecker(), ModelDunderStrMissingChecker(), - ] + ], + 'Module': [ + DefaultAppConfigChecker(), + ], } def __init__(self, *args, **kwargs): @@ -38,6 +42,9 @@ def visit_Call(self, node): def visit_ClassDef(self, node): self.capture_issues_visitor('ClassDef', node) + def visit_Module(self, node): + self.capture_issues_visitor('Module', node) + class DjangoStyleChecker(object): """ diff --git a/flake8_django/checkers/__init__.py b/flake8_django/checkers/__init__.py index 19f2841..2de7786 100644 --- a/flake8_django/checkers/__init__.py +++ b/flake8_django/checkers/__init__.py @@ -1,3 +1,4 @@ +from .default_app_config import DefaultAppConfigChecker from .model_dunder_str import ModelDunderStrMissingChecker from .model_fields import ModelFieldChecker from .model_form import ModelFormChecker @@ -5,4 +6,4 @@ from .urls import URLChecker -__all__ = ['ModelDunderStrMissingChecker', 'ModelFieldChecker', 'ModelFormChecker', 'RenderChecker', 'URLChecker'] +__all__ = ['DefaultAppConfigChecker', 'ModelDunderStrMissingChecker', 'ModelFieldChecker', 'ModelFormChecker', 'RenderChecker', 'URLChecker'] diff --git a/flake8_django/checkers/default_app_config.py b/flake8_django/checkers/default_app_config.py new file mode 100644 index 0000000..9032089 --- /dev/null +++ b/flake8_django/checkers/default_app_config.py @@ -0,0 +1,29 @@ +import ast + +import django + +from .checker import Checker +from .issue import Issue + + +class DJ09(Issue): + code = 'DJ09' + description = 'New applications should avoid default_app_config' + + +class DefaultAppConfigChecker(Checker): + + def run(self, node): + if django.VERSION < (1, 7): + return [] + issues = [] + for elem in node.body: + if not isinstance(elem, ast.Assign): + continue + target_names = map(lambda n: n.id == 'default_app_config', elem.targets) + if any(target_names): + issues.append(DJ09( + elem.lineno, + elem.col_offset, + )) + return issues diff --git a/setup.py b/setup.py index 4fdeb1f..811667f 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ ], }, install_requires=['flake8'], - tests_require=['pytest'], + tests_require=['django', 'pytest'], classifiers=[ 'Framework :: Flake8', 'License :: OSI Approved :: MIT License', diff --git a/tests/fixtures/default_app_config.py b/tests/fixtures/default_app_config.py new file mode 100644 index 0000000..d31e519 --- /dev/null +++ b/tests/fixtures/default_app_config.py @@ -0,0 +1 @@ +default_app_config = 'foobar' diff --git a/tests/test_default_app_config.py b/tests/test_default_app_config.py new file mode 100644 index 0000000..e713170 --- /dev/null +++ b/tests/test_default_app_config.py @@ -0,0 +1,16 @@ +import django + +from .utils import run_check, load_fixture_file + + +def test_default_app_config_django_16(monkeypatch): + monkeypatch.setattr(django, 'VERSION', (1, 6)) + code = load_fixture_file('default_app_config.py') + assert len(run_check(code)) == 0 + + +def test_default_app_config_django_17(monkeypatch): + monkeypatch.setattr(django, 'VERSION', (1, 7)) + code = load_fixture_file('default_app_config.py') + assert len(run_check(code)) == 1 + assert 'DJ09' in run_check(code)[0][2] diff --git a/tox.ini b/tox.ini index e4bf517..98c79dd 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,8 @@ envlist = py34,py35,py36,py37 max-line-length = 120 exclude = tests/fixtures/* [testenv] -deps = pytest +deps = + pytest + django commands = pytest