diff --git a/.travis.yml b/.travis.yml index 87a4cc64..4a2c4df8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: python python: - - 2.7 - 3.4 - 3.5 - 3.6 @@ -18,7 +17,6 @@ stages: matrix: exclude: # Python/Django combinations that aren't officially supported - - { python: 2.7, env: DJANGO=2.0 } - { python: "3.7-dev", env: DJANGO=1.11 } include: - { stage: django_not_installed, python: 3.6, env: TOXENV=django_not_installed } @@ -29,7 +27,6 @@ matrix: - { stage: build_and_package_sanity, python: 3.6, env: SANITY_CHECK=1 } allow_failures: - env: TOXENV=pylint - - python: 2.7 install: - pip install tox-travis diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 713475f3..a63e1022 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,9 +4,12 @@ Changelog Unreleased ---------- +- Requires pylint >= 2.0 which doesn't support Python 2 anymore! + - Add modelform-uses-unicode check to flag dangerous use of the exclude attribute in ModelForm.Meta. + Version 0.11.1 (25 May 2018), the DjangoCon Heidelberg edittion --------------------------------------------------------------- diff --git a/pylint_django/__init__.py b/pylint_django/__init__.py index f46339e2..e6eba5ab 100644 --- a/pylint_django/__init__.py +++ b/pylint_django/__init__.py @@ -2,12 +2,11 @@ from __future__ import absolute_import import sys -import warnings from pylint_django import plugin if sys.version_info < (3, ): - warnings.warn("Version 0.8.0 is the last to support Python 2. " - "Please migrate to Python 3!", DeprecationWarning) + raise DeprecationWarning("Version 0.11.1 was the last to support Python 2. " + "Please migrate to Python 3!") register = plugin.register # pylint: disable=invalid-name diff --git a/pylint_django/augmentations/__init__.py b/pylint_django/augmentations/__init__.py index 56ac4ffd..d84ea858 100644 --- a/pylint_django/augmentations/__init__.py +++ b/pylint_django/augmentations/__init__.py @@ -5,7 +5,7 @@ from astroid import InferenceError from astroid.objects import Super from astroid.nodes import ClassDef, ImportFrom, Attribute -from astroid.scoped_nodes import Class as ScopedClass, Module +from astroid.scoped_nodes import ClassDef as ScopedClass, Module from pylint.checkers.base import DocStringChecker, NameChecker from pylint.checkers.design_analysis import MisdesignChecker @@ -714,8 +714,17 @@ def wrap_func(*args, **kwargs): def is_wsgi_application(node): frame = node.frame() - return node.name == 'application' and isinstance(frame, Module) and \ - (frame.name == 'wsgi' or frame.path.endswith('wsgi.py') or frame.file.endswith('wsgi.py')) + + if node.name == 'application' and isinstance(frame, Module): + path_ends_with_wsgi = False + for path in frame.path: + if path.endswith('wsgi.py'): + path_ends_with_wsgi = True + break + + return frame.name == 'wsgi' or path_ends_with_wsgi or frame.file.endswith('wsgi.py') + + return False def apply_augmentations(linter): @@ -754,8 +763,8 @@ def apply_augmentations(linter): # forms implement __getitem__ but not __len__, thus raising a "Badly implemented container" warning which # we will suppress. NOTE: removed from pylint, https://github.com/PyCQA/pylint/issues/112 # keeping here in case it gets re-implemented - # suppress_message(linter, _leave_class(MisdesignChecker), 'R0924', is_class('django.forms.forms.Form')) - # suppress_message(linter, _leave_class(MisdesignChecker), 'R0924', is_class('django.forms.models.ModelForm')) + # suppress_message(linter, _leave_classdef(MisdesignChecker), 'R0924', is_class('django.forms.forms.Form')) + # suppress_message(linter, _leave_classdef(MisdesignChecker), 'R0924', is_class('django.forms.models.ModelForm')) # Meta suppress_message(linter, DocStringChecker.visit_classdef, 'missing-docstring', is_model_meta_subclass) diff --git a/pylint_django/transforms/fields.py b/pylint_django/transforms/fields.py index fc6dd245..c50ead4b 100644 --- a/pylint_django/transforms/fields.py +++ b/pylint_django/transforms/fields.py @@ -80,4 +80,4 @@ def apply_type_shim(cls, _context=None): # noqa def add_transforms(manager): - manager.register_transform(nodes.Class, inference_tip(apply_type_shim), is_model_or_form_field) + manager.register_transform(nodes.ClassDef, inference_tip(apply_type_shim), is_model_or_form_field) diff --git a/pylint_django/transforms/foreignkey.py b/pylint_django/transforms/foreignkey.py index bc8c6146..9645d179 100644 --- a/pylint_django/transforms/foreignkey.py +++ b/pylint_django/transforms/foreignkey.py @@ -24,7 +24,7 @@ def infer_key_classes(node, context=None): for arg in node.args: # typically the class of the foreign key will # be the first argument, so we'll go from left to right - if isinstance(arg, (nodes.Name, nodes.Getattr)): + if isinstance(arg, (nodes.Name, nodes.Attribute)): try: key_cls = None for inferred in arg.infer(context=context): @@ -56,5 +56,5 @@ def infer_key_classes(node, context=None): def add_transform(manager): - manager.register_transform(nodes.CallFunc, inference_tip(infer_key_classes), + manager.register_transform(nodes.Call, inference_tip(infer_key_classes), is_foreignkey_in_class) diff --git a/setup.py b/setup.py index d5ab0722..8f9125d6 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ include_package_data=True, install_requires=[ 'pylint-plugin-utils>=0.4', - 'pylint>=1.8.2', + 'pylint>=2.0', ], extras_require={ 'with_django': ['Django'], diff --git a/tox.ini b/tox.ini index ffbe3985..f3c49427 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ envlist = flake8 pylint readme - py{27,34,35,36}-django111 + py{34,35,36}-django111 py{34,35,36,37}-django20 [testenv] @@ -18,8 +18,7 @@ commands = flake8: flake8 pylint: pylint --rcfile=tox.ini -d missing-docstring --ignore=tests pylint_django setup readme: python setup.py check --restructuredtext --strict - py{27,34,35,36}-django111: coverage run pylint_django/tests/test_func.py -v - py{34,35,36,37}-django20: coverage run pylint_django/tests/test_func.py -v + py{34,35,36,37}-django{111,20}: coverage run pylint_django/tests/test_func.py -v clean: find . -type f -name '*.pyc' -delete clean: find . -type d -name __pycache__ -delete clean: rm -rf build/ .cache/ dist/ .eggs/ pylint_django.egg-info/ .tox/ @@ -33,14 +32,14 @@ deps = django20: Django>=2.0,<2.1 py{37}: https://github.com/PyCQA/astroid/tarball/master#egg=astroid-master py{37}: https://github.com/PyCQA/pylint/tarball/master#egg=pylint-master - py{27,34,35,36,37}: coverage - py{27,34,35,36,37}: djangorestframework - py{27,34,35,36,37}: django-model-utils - py{27,34,35,36,37}: django-tables2 - py{27,34,35,36,37}: factory-boy - py{27,34,35,36,37}: psycopg2 - py{27,34,35,36,37}: pylint-plugin-utils - py{27,34,35,36,37}: pytest + py{34,35,36,37}: coverage + py{34,35,36,37}: djangorestframework + py{34,35,36,37}: django-model-utils + py{34,35,36,37}: django-tables2 + py{34,35,36,37}: factory-boy + py{34,35,36,37}: psycopg2 + py{34,35,36,37}: pylint-plugin-utils + py{34,35,36,37}: pytest setenv = PIP_DISABLE_PIP_VERSION_CHECK = 1 PYTHONPATH = .