diff --git a/both_isort_4_5.patch b/both_isort_4_5.patch new file mode 100644 index 0000000..3b0b68a --- /dev/null +++ b/both_isort_4_5.patch @@ -0,0 +1,436 @@ +From bc0a82a2104f063bf2b9d74406de4b7be0880938 Mon Sep 17 00:00:00 2001 +From: Damien Baty +Date: Sun, 5 Jul 2020 23:06:04 +0200 +Subject: [PATCH 1/3] Support both isort 4 and isort 5 + +The API of isort 5 (released on 2020-07-04) is completely different. +We must still support isort 4 because isort 5 dropped the +compatibility with Python 3.5, which pylint still supports. + +Fix #3722. +--- + ChangeLog | 4 +++ + pylint/__pkginfo__.py | 2 +- + pylint/checkers/imports.py | 8 +++--- + pylint/utils/__init__.py | 2 ++ + pylint/utils/utils.py | 31 +++++++++++++++++++++++ + tests/functional/w/wrong_import_order.txt | 6 ++--- + tests/test_functional.py | 5 ++++ + tox.ini | 4 ++- + 8 files changed, 52 insertions(+), 10 deletions(-) + +--- a/ChangeLog ++++ b/ChangeLog +@@ -40,6 +40,10 @@ Release date: 2020-06-8 + + Close #3646 + ++* Support both isort 4 and isort 5. ++ ++ Close #3722 ++ + + What's New in Pylint 2.5.2? + =========================== +--- a/pylint/__pkginfo__.py ++++ b/pylint/__pkginfo__.py +@@ -37,7 +37,7 @@ if dev_version is not None: + + 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", + ] +--- a/pylint/checkers/imports.py ++++ b/pylint/checkers/imports.py +@@ -46,7 +46,6 @@ import sys + from distutils import sysconfig + + import astroid +-import isort + from astroid import modutils + from astroid.decorators import cached + +@@ -60,7 +59,7 @@ from pylint.exceptions import EmptyRepor + 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): +@@ -709,8 +708,7 @@ class ImportsChecker(BaseChecker): + third_party_not_ignored = [] + first_party_not_ignored = [] + local_not_ignored = [] +- isort_obj = isort.SortImports( +- file_contents="", ++ isort_driver = IsortDriver( + known_third_party=self.config.known_third_party, + known_standard_library=self.config.known_standard_library, + ) +@@ -723,7 +721,7 @@ class ImportsChecker(BaseChecker): + 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) +--- a/pylint/utils/__init__.py ++++ b/pylint/utils/__init__.py +@@ -46,6 +46,8 @@ main pylint class + 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, +--- a/pylint/utils/utils.py ++++ b/pylint/utils/utils.py +@@ -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 < 4 ++ import isort ++ ++ HAS_ISORT_5 = False ++ + import codecs + import os + import re +@@ -398,3 +407,25 @@ 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, known_third_party, known_standard_library): ++ if HAS_ISORT_5: ++ self.isort5_config = isort.api.Config( ++ known_third_party=known_third_party, ++ known_standard_library=known_standard_library, ++ ) ++ else: ++ self.isort4_obj = isort.SortImports( # pylint: disable=no-member ++ file_contents="", ++ known_third_party=known_third_party, ++ known_standard_library=known_standard_library, ++ ) ++ ++ 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) +--- a/tests/functional/w/wrong_import_order.txt ++++ b/tests/functional/w/wrong_import_order.txt +@@ -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" +--- a/tests/test_functional.py ++++ b/tests/test_functional.py +@@ -28,6 +28,7 @@ import sys + import pytest + + from pylint import testutils ++from pylint.utils import HAS_ISORT_5 + + + class test_dialect(csv.excel): +@@ -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 + +--- a/pylint/checkers/base.py ++++ b/pylint/checkers/base.py +@@ -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 +@@ -67,8 +66,8 @@ import astroid.bases + 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, +--- a/pylint/checkers/spelling.py ++++ b/pylint/checkers/spelling.py +@@ -21,7 +21,6 @@ + + """Checker for spelling errors in comments and docstrings. + """ +- + import os + import re + import tokenize +@@ -33,12 +32,12 @@ from pylint.interfaces import IAstroidCh + try: + import enchant + from enchant.tokenize import ( # type: ignore +- get_tokenizer, + Chunker, +- Filter, + EmailFilter, ++ Filter, + URLFilter, + WikiWordFilter, ++ get_tokenizer, + ) + except ImportError: + enchant = None +--- a/pylint/checkers/utils.py ++++ b/pylint/checkers/utils.py +@@ -50,13 +50,12 @@ import string + from functools import lru_cache, partial + from typing import Callable, Dict, Iterable, List, Match, Optional, Set, Tuple, Union + ++import _string # pylint: disable=wrong-import-position, wrong-import-order + 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, +--- a/pylint/epylint.py ++++ b/pylint/epylint.py +@@ -56,10 +56,10 @@ You may also use py_run to run pylint wi + 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 + + +--- a/pylint/extensions/docparams.py ++++ b/pylint/extensions/docparams.py +@@ -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 + + +--- a/pylint/graph.py ++++ b/pylint/graph.py +@@ -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): +--- a/setup.py ++++ b/setup.py +@@ -39,8 +39,8 @@ try: + + 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 +--- a/tests/extensions/test_bad_builtin.py ++++ b/tests/extensions/test_bad_builtin.py +@@ -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 + +--- a/tests/extensions/test_broad_try_clause.py ++++ b/tests/extensions/test_broad_try_clause.py +@@ -10,8 +10,8 @@ + """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 +--- a/tests/extensions/test_check_docs_utils.py ++++ b/tests/extensions/test_check_docs_utils.py +@@ -14,7 +14,7 @@ in particular the parameter documentatio + import astroid + import pytest + +-import pylint.extensions._check_docs_utils as utils ++from pylint.extensions import _check_docs_utils as utils + + + @pytest.mark.parametrize( +--- a/tests/extensions/test_check_mccabe.py ++++ b/tests/extensions/test_check_mccabe.py +@@ -9,7 +9,7 @@ + + """Tests for the pylint checker in :mod:`pylint.extensions.check_mccabe""" + +-import os.path as osp ++from os import path as osp + + import pytest + +--- a/tests/extensions/test_elseif_used.py ++++ b/tests/extensions/test_elseif_used.py +@@ -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 + +--- a/tests/extensions/test_emptystring.py ++++ b/tests/extensions/test_emptystring.py +@@ -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 + +--- a/tests/extensions/test_redefined.py ++++ b/tests/extensions/test_redefined.py +@@ -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 + +--- a/tests/lint/unittest_lint.py ++++ b/tests/lint/unittest_lint.py +@@ -46,8 +46,7 @@ from shutil import rmtree + + 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, +--- a/tests/test_import_graph.py ++++ b/tests/test_import_graph.py +@@ -17,7 +17,7 @@ from os.path import exists + + import pytest + +-import pylint.testutils as testutils ++from pylint import testutils + from pylint.checkers import imports, initialize + from pylint.lint import PyLinter + +--- a/tests/test_regr.py ++++ b/tests/test_regr.py +@@ -23,7 +23,7 @@ from os.path import abspath, dirname, jo + 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) +--- a/tests/unittest_pyreverse_diadefs.py ++++ b/tests/unittest_pyreverse_diadefs.py +@@ -21,6 +21,7 @@ from pathlib import Path + + import astroid + import pytest ++from unittest_pyreverse_writer import Config, get_project + + from pylint.pyreverse.diadefslib import ( + ClassDiadefGenerator, +@@ -29,7 +30,6 @@ from pylint.pyreverse.diadefslib import + DiadefsHandler, + ) + from pylint.pyreverse.inspector import Linker +-from unittest_pyreverse_writer import Config, get_project + + + def _process_classes(classes): +--- a/tests/unittest_pyreverse_inspector.py ++++ b/tests/unittest_pyreverse_inspector.py +@@ -14,9 +14,9 @@ import os + import astroid + import pytest + from astroid import bases, nodes ++from unittest_pyreverse_writer import get_project + + from pylint.pyreverse import inspector +-from unittest_pyreverse_writer import get_project + + + @pytest.fixture diff --git a/python-pylint.changes b/python-pylint.changes index 63de3c8..a51aab6 100644 --- a/python-pylint.changes +++ b/python-pylint.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Jul 13 22:31:19 UTC 2020 - Matej Cepl + +- Added both_isort_4_5.patch (gh#PyCQA/pylint#3725) allowing + work with both versions of isort. + ------------------------------------------------------------------- Tue Jun 23 16:28:35 UTC 2020 - Benjamin Greiner diff --git a/python-pylint.spec b/python-pylint.spec index 0ea0282..6e9f1e2 100644 --- a/python-pylint.spec +++ b/python-pylint.spec @@ -27,6 +27,9 @@ License: GPL-2.0-or-later Group: Development/Languages/Python URL: https://github.com/pycqa/pylint Source: https://files.pythonhosted.org/packages/source/p/pylint/pylint-%{version}.tar.gz +# PATCH-FIX-UPSTREAM both_isort_4_5.patch gh#PyCQA/pylint#3725 mcepl@suse.com +# allow using both isort 4 and 5 +Patch0: both_isort_4_5.patch BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -69,6 +72,8 @@ feature. %prep %setup -q -n pylint-%{version} +%autopatch -p1 + # fix test: ignore unexpected message gh#PyCQA/pylint#3635 sed -i 's/import matplotlib.pyplot as plt/& # pylint: disable=no-name-in-module/' tests/functional/u/undefined_variable.py