diff --git a/doc/development_guide/api/epylint.rst b/doc/development_guide/api/epylint.rst new file mode 100644 index 0000000000..8359587ed5 --- /dev/null +++ b/doc/development_guide/api/epylint.rst @@ -0,0 +1,22 @@ +======= +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 new file mode 100644 index 0000000000..373c498667 --- /dev/null +++ b/doc/development_guide/api/index.rst @@ -0,0 +1,23 @@ +### +API +### + +You can call ``Pylint``, ``epylint``, ``symilar`` and ``pyreverse`` from another +Python program thanks to their APIs: + +.. sourcecode:: python + + from pylint import run_pylint, run_epylint, run_pyreverse, run_symilar + + run_pylint("--disable=C", "myfile.py") + run_epylint(...) + run_pyreverse(...) + run_symilar(...) + + +.. toctree:: + :maxdepth: 1 + :hidden: + + pylint + epylint diff --git a/doc/development_guide/api/pylint.rst b/doc/development_guide/api/pylint.rst new file mode 100644 index 0000000000..9ba371ea71 --- /dev/null +++ b/doc/development_guide/api/pylint.rst @@ -0,0 +1,67 @@ +======= + Pylint +======= + +As you would launch the command line +------------------------------------ + +You can use the ``run_pylint`` function, which is the same function +called by the command line (using ``sys.argv``). You can supply +arguments yourself: + +.. sourcecode:: python + + from pylint import run_pylint + + run_pylint(argv=["--disable=line-too-long", "myfile.py"]) + + +Recover the result in a stream +------------------------------ + +You can also use ``pylint.lint.Run`` directly if you want to do something that +can't be done using only pylint's command line options. Here's the basic example: + +.. sourcecode:: python + + from pylint.lint import Run + + Run(argv=["--disable=line-too-long", "myfile.py"]) + +With ``Run`` it is possible to invoke pylint programmatically with a +reporter initialized with a custom stream: + +.. sourcecode:: python + + from io import StringIO + + from pylint.lint import Run + from pylint.reporters.text import TextReporter + + pylint_output = StringIO() # Custom open stream + reporter = TextReporter(pylint_output) + Run(["test_file.py"], reporter=reporter, do_exit=False) + print(pylint_output.getvalue()) # Retrieve and print the text report + +The reporter can accept any stream object as as parameter. In this example, +the stream outputs to a file: + +.. sourcecode:: python + + from pylint.lint import Run + from pylint.reporters.text import TextReporter + + with open("report.out", "w") as f: + reporter = TextReporter(f) + Run(["test_file.py"], reporter=reporter, do_exit=False) + +This would be useful to capture pylint output in an open stream which +can be passed onto another program. + +If your program expects that the files being linted might be edited +between runs, you will need to clear pylint's inference cache: + +.. sourcecode:: python + + from pylint.lint import pylinter + pylinter.MANAGER.clear_cache() diff --git a/doc/development_guide/index.rst b/doc/development_guide/index.rst index 190efa3692..4e61de0cbb 100644 --- a/doc/development_guide/index.rst +++ b/doc/development_guide/index.rst @@ -8,4 +8,5 @@ Development contribute testing + api/index profiling diff --git a/doc/faq.rst b/doc/faq.rst index 0cf2d4186e..66856daf94 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -24,35 +24,7 @@ Pylint uses git. To get the latest version of Pylint from the repository, simply 3. Running Pylint ================= -3.1 Can I give pylint a file as an argument instead of a module? ----------------------------------------------------------------- - -Pylint expects the name of a package or module as its argument. As a -convenience, you can give it a file name if it's possible to guess a module name from -the file's path using the python path. Some examples: - -"pylint mymodule.py" should always work since the current working -directory is automatically added on top of the python path - -"pylint directory/mymodule.py" will work if "directory" is a python -package (i.e. has an __init__.py file), an implicit namespace package -or if "directory" is in the python path. - -"pylint /whatever/directory/mymodule.py" will work if either: - - - "/whatever/directory" is in the python path - - - your cwd is "/whatever/directory" - - - "directory" is a python package and "/whatever" is in the python - path - - - "directory" is an implicit namespace package and is in the python path. - - - "directory" is a python package and your cwd is "/whatever" and so - on... - -3.2 Where is the persistent data stored to compare between successive runs? +3.1 Where is the persistent data stored to compare between successive runs? --------------------------------------------------------------------------- Analysis data are stored as a pickle file in a directory which is @@ -71,7 +43,7 @@ localized using the following rules: * ".pylint.d" directory in the current directory -3.3 How do I find the option name corresponding to a specific command line option? +3.2 How do I find the option name corresponding to a specific command line option? ---------------------------------------------------------------------------------- You can generate a sample configuration file with ``--generate-toml-config``. @@ -82,28 +54,6 @@ For example:: pylint --disable=bare-except,invalid-name --class-rgx='[A-Z][a-z]+' --generate-toml-config -3.5 I need to run pylint over all modules and packages in my project directory. -------------------------------------------------------------------------------- - -By default the ``pylint`` command only accepts a list of python modules and packages. Using a -directory which is not a package results in an error:: - - pylint mydir - ************* Module mydir - mydir/__init__.py:1:0: F0010: error while code parsing: Unable to load file mydir/__init__.py: - [Errno 2] No such file or directory: 'mydir/__init__.py' (parse-error) - -To execute pylint over all modules and packages under the directory, the ``--recursive=y`` option must -be provided. This option makes ``pylint`` attempt to discover all modules (files ending with ``.py`` extension) -and all packages (all directories containing a ``__init__.py`` file). -Those modules and packages are then analyzed:: - - pylint --recursive=y mydir - -When ``--recursive=y`` option is used, modules and packages are also accepted as parameters:: - - pylint --recursive=y mydir mymodule mypackage - 4. Message Control ================== diff --git a/doc/user_guide/run.rst b/doc/user_guide/run.rst index b9bbbf5ff5..9a15d04a38 100644 --- a/doc/user_guide/run.rst +++ b/doc/user_guide/run.rst @@ -2,126 +2,46 @@ Running Pylint ================ -From the command line ---------------------- +On module packages or directories +--------------------------------- Pylint is meant to be called from the command line. The usage is :: pylint [options] modules_or_packages -You should give Pylint the name of a python package or module, or some number -of packages or modules. Pylint -``will not import`` this package or module, though uses Python internals -to locate them and as such is subject to the same rules and configuration. -You should pay attention to your ``PYTHONPATH``, since it is a common error -to analyze an installed version of a module instead of the -development version. - -It is also possible to analyze Python files, with a few -restrictions. The thing to keep in mind is that Pylint will try to -convert the file name to a module name, and only be able to process -the file if it succeeds. :: - - pylint mymodule.py - -should always work since the current working -directory is automatically added on top of the python path :: - - pylint directory/mymodule.py - -will work if ``directory`` is a python package (i.e. has an __init__.py -file or it is an implicit namespace package) or if "directory" is in the -python path. - -By default, pylint will exit with an error when one of the arguments is a directory which is not -a python package. In order to run pylint over all modules and packages within the provided -subtree of a directory, the ``--recursive=y`` option must be provided. - -For more details on this see the :ref:`faq`. - -From another python program ---------------------------- - -It is also possible to call Pylint from another Python program, -thanks to the ``Run()`` function in the ``pylint.lint`` module -(assuming Pylint options are stored in a list of strings ``pylint_options``) as: - -.. sourcecode:: python - - import pylint.lint - 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(argv=["your_file"]) +By default the ``pylint`` command only accepts a list of python modules and packages. Using a +directory which is not a package results in an error:: -To silently run Pylint on a ``module_name.py`` module, -and get its standard output and error: + pylint mydir + ************* Module mydir + mydir/__init__.py:1:0: F0010: error while code parsing: Unable to load file mydir/__init__.py: + [Errno 2] No such file or directory: 'mydir/__init__.py' (parse-error) -.. sourcecode:: python +When ``--recursive=y`` option is used, modules and packages are also accepted as parameters:: - from pylint import epylint as lint + pylint --recursive=y mydir mymodule mypackage - (pylint_stdout, pylint_stderr) = lint.py_run('module_name.py', return_std=True) +This option makes ``pylint`` attempt to discover all modules (files ending with ``.py`` extension) +and all packages (all directories containing a ``__init__.py`` file). -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. - -Finally, it is possible to invoke pylint programmatically with a -reporter initialized with a custom stream: - -.. sourcecode:: python - - from io import StringIO - - from pylint.lint import Run - from pylint.reporters.text import TextReporter - - pylint_output = StringIO() # Custom open stream - reporter = TextReporter(pylint_output) - Run(["test_file.py"], reporter=reporter, do_exit=False) - print(pylint_output.getvalue()) # Retrieve and print the text report - -The reporter can accept any stream object as as parameter. In this example, -the stream outputs to a file: - -.. sourcecode:: python - - from pylint.lint import Run - from pylint.reporters.text import TextReporter - - with open("report.out", "w") as f: - reporter = TextReporter(f) - Run(["test_file.py"], reporter=reporter, do_exit=False) - -This would be useful to capture pylint output in an open stream which -can be passed onto another program. +Pylint **will not import** this package or module, though uses Python internals +to locate them and as such is subject to the same rules and configuration. +You should pay attention to your ``PYTHONPATH``, since it is a common error +to analyze an installed version of a module instead of the development version. -If your program expects that the files being linted might be edited -between runs, you will need to clear pylint's inference cache: +On files +-------- -.. sourcecode:: python +It is also possible to analyze Python files, with a few restrictions. As a convenience, +you can give it a file name if it's possible to guess a module name from the file's +path using the python path. Some examples: - from pylint.lint import pylinter - pylinter.MANAGER.clear_cache() +``pylint mymodule.py`` should always work since the current working +directory is automatically added on top of the python path +``pylint directory/mymodule.py`` will work if: ``directory`` is a python +package (i.e. has an ``__init__.py`` file), an implicit namespace package +or if ``directory`` is in the python path. Command line options --------------------