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

Support both isort 4 and isort 5 #3725

Merged
merged 3 commits into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ line_length=88
known_third_party=astroid, sphinx, isort, pytest, mccabe, six, toml
include_trailing_comma=True
skip_glob=tests/functional/**,tests/input/**,tests/extensions/data/**,tests/regrtest_data/**,tests/data/**,astroid/**,venv/**
project=pylint
src_paths=pylint
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Release date: TBA

* Add `raise-missing-from` check for exceptions that should have a cause.

* Support both isort 4 and isort 5. If you have pinned isort 4 in your projet requirements, nothing changes. If you use isort 5, though, note that the `known-standard-library` option is not interpreted the same in isort 4 and isort 5 (see the migration guide in isort documentation for further details). For compatibility's sake for most pylint users, the `known-standard-library` option in pylint now maps to `extra-standard-library` in isort 5. If you really want what `known-standard-library` now means in isort 5, you must disable the `wrong-import-order` check in pylint and run isort manually with a proper isort configuration file.

Close #3722


What's New in Pylint 2.5.4?
===========================
Expand Down
4 changes: 4 additions & 0 deletions doc/whatsnew/2.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ Other Changes
* `mixed-indentation` has been removed, it is no longer useful since TabError is included directly in python3

* Fix superfluous-parens false-positive for the walrus operator

* Add support for both isort 4 and isort 5. If you have pinned isort 4 in your projet requirements, nothing changes. If you use isort 5, though, note that the `known-standard-library` option is not interpreted the same in isort 4 and isort 5 (see `the migration guide in isort documentation`_ for further details). For compatibility's sake for most pylint users, the `known-standard-library` option in pylint now maps to `extra-standard-library` in isort 5. If you really want what `known-standard-library` now means in isort 5, you must disable the `wrong-import-order` check in pylint and run isort manually with a proper isort configuration file.

.. _the migration guide in isort documentation: https://timothycrosley.github.io/isort/docs/upgrade_guides/5.0.0/#known_standard_library
2 changes: 1 addition & 1 deletion man/pylint.1
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Create a graph of external dependencies in the given file (report RP0402 must no
.IP "--int-import-graph=<file.dot>"
Create a graph of internal dependencies in the given file (report RP0402 must not be disabled). [default: none]
.IP "--known-standard-library=<modules>"
Force import order to recognize a module as part of the standard compatibility libraries. [default: none]
Force import order to recognize a module as part of the standard compatibility libraries.
.IP "--known-third-party=<modules>"
Force import order to recognize a module as part of a third party library. [default: enchant]
.IP "--allow-any-import-level=<modules>"
Expand Down
2 changes: 1 addition & 1 deletion pylint/__pkginfo__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

install_requires = [
"astroid>=2.4.0,<=2.5",
"isort>=4.2.5,<5",
"isort>=4.2.5,<6",
"mccabe>=0.6,<0.7",
"toml>=0.7.1",
]
Expand Down
3 changes: 1 addition & 2 deletions pylint/checkers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

"""basic checker for Python code"""

import builtins
import collections
import itertools
Expand All @@ -67,8 +66,8 @@
import astroid.scoped_nodes
from astroid.arguments import CallSite

import pylint.utils as lint_utils
from pylint import checkers, exceptions, interfaces
from pylint import utils as lint_utils
from pylint.checkers import utils
from pylint.checkers.utils import (
is_overload_stub,
Expand Down
11 changes: 3 additions & 8 deletions pylint/checkers/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
from distutils import sysconfig

import astroid
import isort
from astroid import modutils
from astroid.decorators import cached

Expand All @@ -60,7 +59,7 @@
from pylint.graph import DotBackend, get_cycles
from pylint.interfaces import IAstroidChecker
from pylint.reporters.ureports.nodes import Paragraph, VerbatimText
from pylint.utils import get_global_option
from pylint.utils import IsortDriver, get_global_option


def _qualified_names(modname):
Expand Down Expand Up @@ -709,11 +708,7 @@ def _check_imports_order(self, _module_node):
third_party_not_ignored = []
first_party_not_ignored = []
local_not_ignored = []
isort_obj = isort.SortImports(
file_contents="",
known_third_party=self.config.known_third_party,
known_standard_library=self.config.known_standard_library,
)
isort_driver = IsortDriver(self.config)
for node, modname in self._imports_stack:
if modname.startswith("."):
package = "." + modname.split(".")[1]
Expand All @@ -723,7 +718,7 @@ def _check_imports_order(self, _module_node):
ignore_for_import_order = not self.linter.is_message_enabled(
"wrong-import-order", node.fromlineno
)
import_category = isort_obj.place_module(package)
import_category = isort_driver.place_module(package)
node_and_package_import = (node, package)
if import_category in ("FUTURE", "STDLIB"):
std_imports.append(node_and_package_import)
Expand Down
5 changes: 2 additions & 3 deletions pylint/checkers/spelling.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

Pierre-Sassoulas marked this conversation as resolved.
Show resolved Hide resolved
"""Checker for spelling errors in comments and docstrings.
"""

import os
import re
import tokenize
Expand All @@ -33,12 +32,12 @@
try:
import enchant
from enchant.tokenize import ( # type: ignore
get_tokenizer,
Chunker,
Filter,
EmailFilter,
Filter,
URLFilter,
WikiWordFilter,
get_tokenizer,
)
except ImportError:
enchant = None
Expand Down
3 changes: 1 addition & 2 deletions pylint/checkers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@
from functools import lru_cache, partial
from typing import Callable, Dict, Iterable, List, Match, Optional, Set, Tuple, Union

import _string
import astroid
from astroid import bases as _bases
from astroid import helpers, scoped_nodes
from astroid.exceptions import _NonDeducibleTypeHierarchy

import _string # pylint: disable=wrong-import-position, wrong-import-order

BUILTINS_NAME = builtins.__name__
COMP_NODE_TYPES = (
astroid.ListComp,
Expand Down
2 changes: 1 addition & 1 deletion pylint/epylint.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@
its output.
"""
import os
import os.path as osp
import shlex
import sys
from io import StringIO
from os import path as osp
from subprocess import PIPE, Popen


Expand Down
2 changes: 1 addition & 1 deletion pylint/extensions/docparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"""
import astroid

import pylint.extensions._check_docs_utils as utils
from pylint.checkers import BaseChecker
from pylint.checkers import utils as checker_utils
from pylint.extensions import _check_docs_utils as utils
from pylint.interfaces import IAstroidChecker


Expand Down
3 changes: 1 addition & 2 deletions pylint/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@

(dot generation adapted from pypy/translator/tool/make_dot.py)
"""

import codecs
import os
import os.path as osp
import subprocess
import sys
import tempfile
from os import path as osp


def target_info_from_filename(filename):
Expand Down
2 changes: 2 additions & 0 deletions pylint/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
from pylint.utils.ast_walker import ASTWalker
from pylint.utils.file_state import FileState
from pylint.utils.utils import (
HAS_ISORT_5,
IsortDriver,
_basename_in_blacklist_re,
_check_csv,
_format_option_value,
Expand Down
35 changes: 35 additions & 0 deletions pylint/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

try:
import isort.api

HAS_ISORT_5 = True
except ImportError: # isort < 5
import isort

HAS_ISORT_5 = False

import codecs
import os
import re
Expand Down Expand Up @@ -398,3 +407,29 @@ def _ini_format(stream, options):
# remove trailing ',' from last element of the list
value = value[:-1]
print("%s=%s" % (optname, value), file=stream)


class IsortDriver:
"""A wrapper around isort API that changed between versions 4 and 5."""

def __init__(self, config):
if HAS_ISORT_5:
self.isort5_config = isort.api.Config(
# There is not typo here. EXTRA_standard_library is
# what most users want. The option has been named
# KNOWN_standard_library for ages in pylint and we
# don't want to break compatibility.
extra_standard_library=config.known_standard_library,
known_third_party=config.known_third_party,
)
else:
self.isort4_obj = isort.SortImports( # pylint: disable=no-member
file_contents="",
known_standard_library=config.known_standard_library,
known_third_party=config.known_third_party,
)

def place_module(self, package):
if HAS_ISORT_5:
return isort.api.place_module(package, self.isort5_config)
return self.isort4_obj.place_module(package)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@

USE_SETUPTOOLS = 1
except ImportError:
from distutils.core import setup
from distutils.command import install_lib # pylint: disable=unused-import
from distutils.core import setup

USE_SETUPTOOLS = 0
easy_install_lib = None
Expand Down
2 changes: 1 addition & 1 deletion tests/checkers/unittest_typecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from pylint.testutils import CheckerTestCase, Message, set_config

try:
import coverage.tracer as _
from coverage import tracer as _ # pylint: disable=unused-import

C_EXTENTIONS_AVAILABLE = True
except ImportError:
Expand Down
3 changes: 1 addition & 2 deletions tests/extensions/test_bad_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

"""Tests for the pylint checker in :mod:`pylint.extensions.bad_builtin
"""

import os.path as osp
from os import path as osp

import pytest

Expand Down
3 changes: 1 addition & 2 deletions tests/extensions/test_broad_try_clause.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

"""Tests for the pylint checker in :mod:`pylint.extensions.broad_try_clause`"""

import os.path as osp
import unittest
from os import path as osp

from pylint import checkers
from pylint.extensions.broad_try_clause import BroadTryClauseChecker
Expand Down
2 changes: 1 addition & 1 deletion tests/extensions/test_check_docs_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import astroid
import pytest

import pylint.extensions._check_docs_utils as utils
from pylint.extensions import _check_docs_utils as utils


@pytest.mark.parametrize(
Expand Down
2 changes: 1 addition & 1 deletion tests/extensions/test_check_mccabe.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""Tests for the pylint checker in :mod:`pylint.extensions.check_mccabe"""
# pylint: disable=redefined-outer-name

import os.path as osp
from os import path as osp

import pytest

Expand Down
3 changes: 1 addition & 2 deletions tests/extensions/test_elseif_used.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

"""Tests for the pylint checker in :mod:`pylint.extensions.check_elif
"""

import os.path as osp
from os import path as osp

import pytest

Expand Down
3 changes: 1 addition & 2 deletions tests/extensions/test_emptystring.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

"""Tests for the pylint checker in :mod:`pylint.extensions.emptystring
"""

import os.path as osp
from os import path as osp

import pytest

Expand Down
3 changes: 1 addition & 2 deletions tests/extensions/test_redefined.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

"""Tests for the pylint checker in :mod:`pylint.extensions.check_elif"""

import os.path as osp
from os import path as osp

import pytest

Expand Down
6 changes: 3 additions & 3 deletions tests/functional/w/wrong_import_order.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
wrong-import-order:12::standard import "import os.path" should be placed before "import six"
wrong-import-order:14::standard import "import sys" should be placed before "import six"
wrong-import-order:15::standard import "import datetime" should be placed before "import six"
wrong-import-order:18::first party import "import totally_missing" should be placed before "from .package import Class"
wrong-import-order:20::third party import "import astroid" should be placed before "import unused_import"
wrong-import-order:24::third party import "from six.moves.urllib.parse import quote" should be placed before "import unused_import"
wrong-import-order:18::third party import "import totally_missing" should be placed before "from .package import Class"
wrong-import-order:20::third party import "import astroid" should be placed before "from .package import Class"
wrong-import-order:24::third party import "from six.moves.urllib.parse import quote" should be placed before "from .package import Class"
3 changes: 1 addition & 2 deletions tests/lint/unittest_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@

import pytest

import pylint.testutils as testutils
from pylint import checkers, config, exceptions, interfaces, lint
from pylint import checkers, config, exceptions, interfaces, lint, testutils
from pylint.checkers.utils import check_messages
from pylint.constants import (
MSG_STATE_CONFIDENCE,
Expand Down
5 changes: 5 additions & 0 deletions tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import pytest

from pylint import testutils
from pylint.utils import HAS_ISORT_5


class test_dialect(csv.excel):
Expand Down Expand Up @@ -77,6 +78,10 @@ def get_tests():
continue
for filename in filenames:
if filename != "__init__.py" and filename.endswith(".py"):
# isort 5 has slightly different rules as isort 4. Testing
# both would be hard: test with isort 5 only.
if filename == "wrong_import_order.py" and not HAS_ISORT_5:
continue
suite.append(testutils.FunctionalTestFile(dirpath, filename))
return suite

Expand Down
2 changes: 1 addition & 1 deletion tests/test_import_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import pytest

import pylint.testutils as testutils
from pylint import testutils
from pylint.checkers import imports, initialize
from pylint.lint import PyLinter

Expand Down
2 changes: 1 addition & 1 deletion tests/test_regr.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import astroid
import pytest

import pylint.testutils as testutils
from pylint import testutils

REGR_DATA = join(dirname(abspath(__file__)), "regrtest_data")
sys.path.insert(1, REGR_DATA)
Expand Down
2 changes: 1 addition & 1 deletion tests/unittest_pyreverse_diadefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import astroid
import pytest
from unittest_pyreverse_writer import Config, get_project

from pylint.pyreverse.diadefslib import (
ClassDiadefGenerator,
Expand All @@ -27,7 +28,6 @@
DiadefsHandler,
)
from pylint.pyreverse.inspector import Linker
from unittest_pyreverse_writer import Config, get_project


def _process_classes(classes):
Expand Down