Skip to content

Allow passing arguments when entry points are used as functions #5613

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

Merged
merged 2 commits into from
Dec 30, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ Release date: TBA

Closes #5504

* When invoking ``pylint``, ``symilar`` or ``pyreverse`` by importing them in a python file
you can now pass an ``arguments`` keyword besides patching ``sys.argv``.

Closes #5320

* The ``PyLinter`` class will now be initialized with a ``TextReporter``
as its reporter if none is provided.

Expand Down
14 changes: 14 additions & 0 deletions doc/user_guide/run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ thanks to the ``Run()`` function in the ``pylint.lint`` module
pylint_opts = ['--disable=line-too-long', 'myfile.py']
pylint.lint.Run(pylint_opts)

Another option would be to use the ``run_pylint`` function, which is the same function
called by the command line. You can either patch ``sys.argv`` or supply arguments yourself:

.. sourcecode:: python

import pylint

sys.argv = ["pylint", "your_file"]
pylint.run_pylint()

# Or:

pylint.run_pylint(arguments=["your_file"])

To silently run Pylint on a ``module_name.py`` module,
and get its standard output and error:

Expand Down
5 changes: 5 additions & 0 deletions doc/whatsnew/2.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ Other Changes

Closes #5557

* When invoking ``pylint``, ``symilar`` or ``pyreverse`` by importing them in a python file
you can now pass an ``arguments`` keyword besides patching ``sys.argv``.

Closes #5320

* The ``PyLinter`` class will now be initialized with a ``TextReporter``
as its reporter if none is provided.

Expand Down
27 changes: 19 additions & 8 deletions pylint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@

import os
import sys
from typing import List, Optional

from pylint.__pkginfo__ import __version__

# pylint: disable=import-outside-toplevel


def run_pylint():
def run_pylint(*, arguments: Optional[List[str]] = None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm probably a bit late on this one.

I would suggest using args or argv instead, without the keyword requirement. This is what I usually see in these cases.

def main(argv: Optional[Sequence[str]] = None):
    argv = argv or sys.argv[1:]
    ...

Keyword only isn't really necessary here, it's just one argument. Even with more, the first will likely always be args / argv. More detail (optional) once can always be keyword only later, although even then not strictly necessary.

"""Run pylint

Arguments can be a list of strings normally supplied as arguments on the command line
"""
from pylint.lint import Run as PylintRun

try:
PylintRun(sys.argv[1:])
PylintRun(arguments or sys.argv[1:])
except KeyboardInterrupt:
sys.exit(1)

Expand All @@ -32,18 +37,24 @@ def run_epylint():
EpylintRun()


def run_pyreverse():
"""run pyreverse"""
def run_pyreverse(*, arguments: Optional[List[str]] = None):
"""Run pyreverse

Arguments can be a list of strings normally supplied as arguments on the command line
"""
from pylint.pyreverse.main import Run as PyreverseRun

PyreverseRun(sys.argv[1:])
PyreverseRun(arguments or sys.argv[1:])


def run_symilar(*, arguments: Optional[List[str]] = None):
"""Run symilar

def run_symilar():
"""run symilar"""
Arguments can be a list of strings normally supplied as arguments on the command line
"""
from pylint.checkers.similar import Run as SimilarRun

SimilarRun(sys.argv[1:])
SimilarRun(arguments or sys.argv[1:])


def modify_sys_path() -> None:
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pylint_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@ def test_runner(runner: Callable, tmpdir: LocalPath) -> None:
with pytest.raises(SystemExit) as err:
runner()
assert err.value.code == 0


@pytest.mark.parametrize("runner", [run_pylint, run_pyreverse, run_symilar])
def test_runner_with_arguments(runner: Callable, tmpdir: LocalPath) -> None:
"""Check the runners with arguments as parameter instead of sys.argv"""
filepath = os.path.abspath(__file__)
testargs = [filepath]
with tmpdir.as_cwd():
with pytest.raises(SystemExit) as err:
runner(arguments=testargs)
assert err.value.code == 0