summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Sassoulas <pierre.sassoulas@gmail.com>2023-03-08 15:03:12 +0100
committerGitHub <noreply@github.com>2023-03-08 15:03:12 +0100
commit491c53985cae113daa11c20d80c124a8df243840 (patch)
treeb61799d776f9305d1319566613bd131d9b22614f
parent395042b4700ee8e23025bb7401221a5c0d32e5a7 (diff)
downloadpylint-git-491c53985cae113daa11c20d80c124a8df243840.tar.gz
[deprecation] epylint removal for pylint 3.0.0 (#8400)
Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>
-rw-r--r--doc/development_guide/api/epylint.rst22
-rw-r--r--doc/development_guide/api/index.rst3
-rw-r--r--doc/user_guide/installation/ide_integration/flymake-emacs.rst75
-rw-r--r--doc/whatsnew/fragments/7737.user_action3
-rw-r--r--pylint/__init__.py18
-rwxr-xr-xpylint/epylint.py224
-rw-r--r--pyproject.toml1
-rw-r--r--tests/test_epylint.py68
-rw-r--r--tests/test_pylint_runners.py24
9 files changed, 8 insertions, 430 deletions
diff --git a/doc/development_guide/api/epylint.rst b/doc/development_guide/api/epylint.rst
deleted file mode 100644
index 8359587ed..000000000
--- a/doc/development_guide/api/epylint.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-=======
-epylint
-=======
-
-To silently run epylint on a ``module_name.py`` module, and get its standard output and error:
-
-.. sourcecode:: python
-
- from pylint import epylint as lint
-
- (pylint_stdout, pylint_stderr) = lint.py_run('module_name.py', return_std=True)
-
-It is also possible to include additional Pylint options in the first argument to ``py_run``:
-
-.. sourcecode:: python
-
- from pylint import epylint as lint
-
- (pylint_stdout, pylint_stderr) = lint.py_run('module_name.py --disable C0114', return_std=True)
-
-The options ``--msg-template="{path}:{line}: {category} ({msg_id}, {symbol}, {obj}) {msg}"`` and
-``--reports=n`` are set implicitly inside the ``epylint`` module.
diff --git a/doc/development_guide/api/index.rst b/doc/development_guide/api/index.rst
index 00e6e1a9f..ac4e96900 100644
--- a/doc/development_guide/api/index.rst
+++ b/doc/development_guide/api/index.rst
@@ -2,7 +2,7 @@
API
###
-You can call ``Pylint``, ``epylint``, ``symilar`` and ``pyreverse`` from another
+You can call ``Pylint``, ``symilar`` and ``pyreverse`` from another
Python program thanks to their APIs:
.. sourcecode:: python
@@ -19,4 +19,3 @@ Python program thanks to their APIs:
:hidden:
pylint
- epylint
diff --git a/doc/user_guide/installation/ide_integration/flymake-emacs.rst b/doc/user_guide/installation/ide_integration/flymake-emacs.rst
index 79310ff59..64aad8a66 100644
--- a/doc/user_guide/installation/ide_integration/flymake-emacs.rst
+++ b/doc/user_guide/installation/ide_integration/flymake-emacs.rst
@@ -4,75 +4,6 @@ Using Pylint through Flymake in Emacs
=====================================
.. warning::
- The Emacs package now has its own repository and is looking for a maintainer.
- If you're reading this doc and are interested in maintaining this package or
- are actually using flymake please open an issue at
- https://github.com/emacsorphanage/pylint/issues/new/choose
-
-To enable Flymake for Python, insert the following into your .emacs:
-
-.. sourcecode:: common-lisp
-
- ;; Configure Flymake for Python
- (when (load "flymake" t)
- (defun flymake-pylint-init ()
- (let* ((temp-file (flymake-init-create-temp-buffer-copy
- 'flymake-create-temp-inplace))
- (local-file (file-relative-name
- temp-file
- (file-name-directory buffer-file-name))))
- (list "epylint" (list local-file))))
- (add-to-list 'flymake-allowed-file-name-masks
- '("\\.py\\'" flymake-pylint-init)))
-
- ;; Set as a minor mode for Python
- (add-hook 'python-mode-hook '(lambda () (flymake-mode)))
-
-Above stuff is in ``pylint/elisp/pylint-flymake.el``, which should be automatically
-installed on Debian systems, in which cases you don't have to put it in your ``.emacs`` file.
-
-Other things you may find useful to set:
-
-.. sourcecode:: common-lisp
-
- ;; Configure to wait a bit longer after edits before starting
- (setq-default flymake-no-changes-timeout '3)
-
- ;; Keymaps to navigate to the errors
- (add-hook 'python-mode-hook '(lambda () (define-key python-mode-map "\C-cn" 'flymake-goto-next-error)))
- (add-hook 'python-mode-hook '(lambda () (define-key python-mode-map "\C-cp" 'flymake-goto-prev-error)))
-
-
-Finally, by default Flymake only displays the extra information about the error when you
-hover the mouse over the highlighted line. The following will use the minibuffer to display
-messages when you the cursor is on the line.
-
-.. sourcecode:: common-lisp
-
- ;; To avoid having to mouse hover for the error message, these functions make Flymake error messages
- ;; appear in the minibuffer
- (defun show-fly-err-at-point ()
- "If the cursor is sitting on a Flymake error, display the message in the minibuffer"
- (require 'cl)
- (interactive)
- (let ((line-no (line-number-at-pos)))
- (dolist (elem flymake-err-info)
- (if (eq (car elem) line-no)
- (let ((err (car (second elem))))
- (message "%s" (flymake-ler-text err)))))))
-
- (add-hook 'post-command-hook 'show-fly-err-at-point)
-
-
-Alternative, if you only wish to pollute the minibuffer after an explicit flymake-goto-* then use
-the following instead of a post-command-hook
-
-.. sourcecode:: common-lisp
-
- (defadvice flymake-goto-next-error (after display-message activate compile)
- "Display the error in the mini-buffer rather than having to mouse over it"
- (show-fly-err-at-point))
-
- (defadvice flymake-goto-prev-error (after display-message activate compile)
- "Display the error in the mini-buffer rather than having to mouse over it"
- (show-fly-err-at-point))
+ epylint was deprecated in 2.16.0 and targeted for deletion in 3.0.0.
+ All emacs and flymake related files were removed and their support will
+ now happen in an external repository: https://github.com/emacsorphanage/pylint.
diff --git a/doc/whatsnew/fragments/7737.user_action b/doc/whatsnew/fragments/7737.user_action
new file mode 100644
index 000000000..1a992f563
--- /dev/null
+++ b/doc/whatsnew/fragments/7737.user_action
@@ -0,0 +1,3 @@
+epylint was removed. It now lives at: https://github.com/emacsorphanage/pylint.
+
+Refs #7737
diff --git a/pylint/__init__.py b/pylint/__init__.py
index 2cc7edadb..1e9d34ee0 100644
--- a/pylint/__init__.py
+++ b/pylint/__init__.py
@@ -9,14 +9,12 @@ __all__ = [
"version",
"modify_sys_path",
"run_pylint",
- "run_epylint",
"run_symilar",
"run_pyreverse",
]
import os
import sys
-import warnings
from collections.abc import Sequence
from typing import NoReturn
@@ -48,22 +46,6 @@ def _run_pylint_config(argv: Sequence[str] | None = None) -> None:
_PylintConfigRun(argv or sys.argv[1:])
-def run_epylint(argv: Sequence[str] | None = None) -> NoReturn:
- """Run epylint.
-
- argv can be a list of strings normally supplied as arguments on the command line
- """
- from pylint.epylint import Run as EpylintRun
-
- warnings.warn(
- "'run_epylint' will be removed in pylint 3.0, use "
- "https://github.com/emacsorphanage/pylint instead.",
- DeprecationWarning,
- stacklevel=1,
- )
- EpylintRun(argv)
-
-
def run_pyreverse(argv: Sequence[str] | None = None) -> NoReturn:
"""Run pyreverse.
diff --git a/pylint/epylint.py b/pylint/epylint.py
deleted file mode 100755
index dd23b450b..000000000
--- a/pylint/epylint.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4
-# -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4
-
-# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
-# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
-# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
-
-"""Emacs and Flymake compatible Pylint.
-
-This script is for integration with Emacs and is compatible with Flymake mode.
-
-epylint walks out of python packages before invoking pylint. This avoids
-reporting import errors that occur when a module within a package uses the
-absolute import path to get another module within this package.
-
-For example:
- - Suppose a package is structured as
-
- a/__init__.py
- a/b/x.py
- a/c/y.py
-
- - Then if y.py imports x as "from a.b import x" the following produces pylint
- errors
-
- cd a/c; pylint y.py
-
- - The following obviously doesn't
-
- pylint a/c/y.py
-
- - As this script will be invoked by Emacs within the directory of the file
- we are checking we need to go out of it to avoid these false positives.
-
-You may also use py_run to run pylint with desired options and get back (or not)
-its output.
-"""
-
-from __future__ import annotations
-
-import os
-import shlex
-import sys
-import warnings
-from collections.abc import Sequence
-from io import StringIO
-from subprocess import PIPE, Popen
-from typing import NoReturn, TextIO, overload
-
-if sys.version_info >= (3, 8):
- from typing import Literal
-else:
- from typing_extensions import Literal
-
-
-def _get_env() -> dict[str, str]:
- """Extracts the environment PYTHONPATH and appends the current 'sys.path'
- to it.
- """
- env = dict(os.environ)
- env["PYTHONPATH"] = os.pathsep.join(sys.path)
- return env
-
-
-def lint(filename: str, options: Sequence[str] = ()) -> int:
- """Pylint the given file.
-
- When run from Emacs we will be in the directory of a file, and passed its
- filename. If this file is part of a package and is trying to import other
- modules from within its own package or another package rooted in a directory
- below it, pylint will classify it as a failed import.
-
- To get around this, we traverse down the directory tree to find the root of
- the package this module is in. We then invoke pylint from this directory.
-
- Finally, we must correct the filenames in the output generated by pylint so
- Emacs doesn't become confused (it will expect just the original filename,
- while pylint may extend it with extra directories if we've traversed down
- the tree)
- """
- # traverse downwards until we are out of a python package
- full_path = os.path.abspath(filename)
- parent_path = os.path.dirname(full_path)
- child_path = os.path.basename(full_path)
-
- while parent_path != "/" and os.path.exists(
- os.path.join(parent_path, "__init__.py")
- ):
- child_path = os.path.join(os.path.basename(parent_path), child_path)
- parent_path = os.path.dirname(parent_path)
-
- # Start pylint
- # Ensure we use the python and pylint associated with the running epylint
- run_cmd = "import sys; from pylint.lint import Run; Run(sys.argv[1:])"
- cmd = (
- [sys.executable, "-c", run_cmd]
- + [
- "--msg-template",
- "{path}:{line}: {category} ({msg_id}, {symbol}, {obj}) {msg}",
- "-r",
- "n",
- child_path,
- ]
- + list(options)
- )
-
- with Popen(
- cmd, stdout=PIPE, cwd=parent_path, env=_get_env(), universal_newlines=True
- ) as process:
- for line in process.stdout: # type: ignore[union-attr]
- # remove pylintrc warning
- if line.startswith("No config file found"):
- continue
-
- # modify the file name that's put out to reverse the path traversal we made
- parts = line.split(":")
- if parts and parts[0] == child_path:
- line = ":".join([filename] + parts[1:])
- print(line, end=" ")
-
- process.wait()
- return process.returncode
-
-
-@overload
-def py_run(
- command_options: str = ...,
- return_std: Literal[False] = ...,
- stdout: TextIO | int | None = ...,
- stderr: TextIO | int | None = ...,
-) -> None:
- ...
-
-
-@overload
-def py_run(
- command_options: str,
- return_std: Literal[True],
- stdout: TextIO | int | None = ...,
- stderr: TextIO | int | None = ...,
-) -> tuple[StringIO, StringIO]:
- ...
-
-
-def py_run(
- command_options: str = "",
- return_std: bool = False,
- stdout: TextIO | int | None = None,
- stderr: TextIO | int | None = None,
-) -> tuple[StringIO, StringIO] | None:
- """Run pylint from python.
-
- ``command_options`` is a string containing ``pylint`` command line options;
- ``return_std`` (boolean) indicates return of created standard output
- and error (see below);
- ``stdout`` and ``stderr`` are 'file-like' objects in which standard output
- could be written.
-
- Calling agent is responsible for stdout/err management (creation, close).
- Default standard output and error are those from sys,
- or standalone ones (``subprocess.PIPE``) are used
- if they are not set and ``return_std``.
-
- If ``return_std`` is set to ``True``, this function returns a 2-uple
- containing standard output and error related to created process,
- as follows: ``(stdout, stderr)``.
-
- To silently run Pylint on a module, and get its standard output and error:
- >>> (pylint_stdout, pylint_stderr) = py_run( 'module_name.py', True)
- """
- warnings.warn(
- "'epylint' will be removed in pylint 3.0, use https://github.com/emacsorphanage/pylint instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- # Detect if we use Python as executable or not, else default to `python`
- executable = sys.executable if "python" in sys.executable else "python"
-
- # Create command line to call pylint
- epylint_part = [executable, "-c", "from pylint import epylint;epylint.Run()"]
- options = shlex.split(command_options, posix=not sys.platform.startswith("win"))
- cli = epylint_part + options
-
- # Providing standard output and/or error if not set
- if stdout is None:
- stdout = PIPE if return_std else sys.stdout
- if stderr is None:
- stderr = PIPE if return_std else sys.stderr
- # Call pylint in a sub-process
- with Popen(
- cli,
- shell=False,
- stdout=stdout,
- stderr=stderr,
- env=_get_env(),
- universal_newlines=True,
- ) as process:
- proc_stdout, proc_stderr = process.communicate()
- # Return standard output and error
- if return_std:
- return StringIO(proc_stdout), StringIO(proc_stderr)
- return None
-
-
-def Run(argv: Sequence[str] | None = None) -> NoReturn:
- warnings.warn(
- "'epylint' will be removed in pylint 3.0, use https://github.com/emacsorphanage/pylint instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- if not argv and len(sys.argv) == 1:
- print(f"Usage: {sys.argv[0]} <filename> [options]")
- sys.exit(1)
-
- argv = argv or sys.argv[1:]
- if not os.path.exists(argv[0]):
- print(f"{argv[0]} does not exist")
- sys.exit(1)
- else:
- sys.exit(lint(argv[0], argv[1:]))
-
-
-if __name__ == "__main__":
- Run()
diff --git a/pyproject.toml b/pyproject.toml
index 333d2856e..0c2b2a817 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -65,7 +65,6 @@ spelling = ["pyenchant~=3.2"]
[project.scripts]
pylint = "pylint:run_pylint"
pylint-config = "pylint:_run_pylint_config"
-epylint = "pylint:run_epylint"
pyreverse = "pylint:run_pyreverse"
symilar = "pylint:run_symilar"
diff --git a/tests/test_epylint.py b/tests/test_epylint.py
deleted file mode 100644
index 7e9116e99..000000000
--- a/tests/test_epylint.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
-# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
-# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt
-
-"""Test for issue https://github.com/PyCQA/pylint/issues/4286."""
-# pylint: disable=redefined-outer-name
-from pathlib import PosixPath
-
-import pytest
-
-from pylint import epylint as lint
-
-
-@pytest.fixture()
-def example_path(tmp_path: PosixPath) -> PosixPath:
- content = """class IvrAudioApp:
-
- def run(self):
- self.hassan()
- """
- path = tmp_path / "my_app.py"
- with open(path, "w", encoding="utf-8") as f:
- f.write(content)
- return path
-
-
-def test_epylint_good_command(example_path: PosixPath) -> None:
- with pytest.warns(DeprecationWarning):
- out, _ = lint.py_run(
- f"{example_path} -E --disable=E1111 --msg-template "
- "'{category} {module} {obj} {line} {column} {msg}'",
- return_std=True,
- )
- msg = out.read()
- assert (
- msg
- == """\
-************* Module my_app
- error my_app IvrAudioApp.run 4 8 Instance of 'IvrAudioApp' has no 'hassan' member
- """
- )
-
-
-def test_epylint_strange_command(example_path: PosixPath) -> None:
- with pytest.warns(DeprecationWarning):
- out, _ = lint.py_run(
- # pylint: disable-next=consider-using-f-string
- "%s -E --disable=E1111 --msg-template={category} {module} {obj} {line} {column} {msg}"
- % example_path,
- return_std=True,
- )
- assert (
- out.read()
- == """\
-************* Module {module}
- fatal
- ************* Module {obj}
- fatal
- ************* Module {line}
- fatal
- ************* Module {column}
- fatal
- ************* Module {msg}
- fatal
- ************* Module my_app
- error
- """
- )
diff --git a/tests/test_pylint_runners.py b/tests/test_pylint_runners.py
index 6a55db9eb..dab1dc025 100644
--- a/tests/test_pylint_runners.py
+++ b/tests/test_pylint_runners.py
@@ -17,7 +17,7 @@ from unittest.mock import MagicMock, mock_open, patch
import pytest
-from pylint import run_epylint, run_pylint, run_pyreverse, run_symilar
+from pylint import run_pylint, run_pyreverse, run_symilar
from pylint.testutils import GenericTestReporter as Reporter
from pylint.testutils._run import _Run as Run
from pylint.testutils.utils import _test_cwd
@@ -44,17 +44,6 @@ def test_runner(runner: _RunCallable, tmp_path: pathlib.Path) -> None:
assert err.value.code == 0
-def test_epylint(tmp_path: pathlib.Path) -> None:
- """TODO: 3.0 delete with epylint."""
- filepath = os.path.abspath(__file__)
- with _test_cwd(tmp_path):
- with patch.object(sys, "argv", ["", filepath]):
- with pytest.raises(SystemExit) as err:
- with pytest.warns(DeprecationWarning):
- run_epylint()
- assert err.value.code == 0
-
-
@pytest.mark.parametrize("runner", [run_pylint, run_pyreverse, run_symilar])
def test_runner_with_arguments(runner: _RunCallable, tmp_path: pathlib.Path) -> None:
"""Check the runners with arguments as parameter instead of sys.argv."""
@@ -66,17 +55,6 @@ def test_runner_with_arguments(runner: _RunCallable, tmp_path: pathlib.Path) ->
assert err.value.code == 0
-def test_epylint_with_arguments(tmp_path: pathlib.Path) -> None:
- """TODO: 3.0 delete with epylint."""
- filepath = os.path.abspath(__file__)
- testargs = [filepath]
- with _test_cwd(tmp_path):
- with pytest.raises(SystemExit) as err:
- with pytest.warns(DeprecationWarning):
- run_epylint(testargs)
- assert err.value.code == 0
-
-
def test_pylint_argument_deduplication(
tmp_path: pathlib.Path, tests_directory: pathlib.Path
) -> None: