diff options
author | Ashley Whetter <AWhetter@users.noreply.github.com> | 2017-07-12 05:45:16 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-12 05:45:16 +0100 |
commit | 9f7797ae15bd5e4e5c4ad320afcc15eeb4cdae82 (patch) | |
tree | a3316d20d3be3ce78f0aed8b1e39ade7f75176bc | |
parent | 6794b421d0004c593748df850083914049f11a98 (diff) | |
download | pylint-git-9f7797ae15bd5e4e5c4ad320afcc15eeb4cdae82.tar.gz |
Expanded documentation for new contributors (#1569)
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | doc/conf.py | 16 | ||||
-rw-r--r-- | doc/development_guide/contribute.rst | 43 | ||||
-rwxr-xr-x | doc/exts/pylint_extensions.py | 2 | ||||
-rwxr-xr-x | doc/exts/pylint_features.py | 2 | ||||
-rw-r--r-- | doc/how_tos/custom_checkers.rst | 284 | ||||
-rw-r--r-- | doc/how_tos/index.rst | 10 | ||||
-rw-r--r-- | doc/how_tos/plugins.rst (renamed from doc/reference_guide/plugins.rst) | 25 | ||||
-rw-r--r-- | doc/how_tos/transform_plugins.rst (renamed from doc/reference_guide/transform_plugins.rst) | 0 | ||||
-rw-r--r-- | doc/index.rst | 3 | ||||
-rw-r--r-- | doc/reference_guide/custom_checkers.rst | 61 | ||||
-rw-r--r-- | doc/reference_guide/index.rst | 11 | ||||
-rw-r--r-- | doc/technical_reference/checkers.rst | 7 | ||||
-rw-r--r-- | doc/technical_reference/index.rst | 19 | ||||
-rw-r--r-- | doc/technical_reference/startup.rst | 22 | ||||
-rw-r--r-- | doc/whatsnew/index.rst | 1 | ||||
-rw-r--r-- | examples/custom.py | 56 |
17 files changed, 456 insertions, 110 deletions
diff --git a/.gitignore b/.gitignore index 9d9ec161c..8170446b5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ /pylint.egg-info/ .tox *.sw[a-z] -doc/extensions.rst -doc/features.rst +doc/technical_reference/extensions.rst +doc/technical_reference/features.rst pyve build-stamp debian/files diff --git a/doc/conf.py b/doc/conf.py index ce9aa94ef..7e21fd473 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -25,9 +25,12 @@ sys.path.append(os.path.abspath('exts')) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['pylint_features', - 'pylint_extensions', - 'sphinx.ext.autosectionlabel'] +extensions = [ + 'pylint_features', + 'pylint_extensions', + 'sphinx.ext.autosectionlabel', + 'sphinx.ext.intersphinx', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -43,7 +46,7 @@ master_doc = 'index' # General information about the project. project = u'Pylint' -copyright = u'2003-2016, Logilab, PyCQA and contributors' +copyright = u'2003-2017, Logilab, PyCQA and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -216,3 +219,8 @@ man_pages = [ ('index', 'pylint', u'Pylint Documentation', [u'Logilab, PyCQA and contributors'], 1) ] + +intersphinx_mapping = { + 'astroid': ('http://astroid.readthedocs.io/en/latest/', None), + 'python': ('https://docs.python.org/3', None), +} diff --git a/doc/development_guide/contribute.rst b/doc/development_guide/contribute.rst index 924979900..e367a42de 100644 --- a/doc/development_guide/contribute.rst +++ b/doc/development_guide/contribute.rst @@ -39,6 +39,8 @@ Archives before April 2013 are available at http://lists.logilab.org/pipermail/python-projects/ +.. _repository: + Repository ---------- @@ -91,7 +93,9 @@ your patch gets accepted. about this topic) -Functional tests +.. _functional_tests: + +Functional Tests ---------------- These are residing under '/test/functional' and they are formed of multiple @@ -128,3 +132,40 @@ current environment in order to have faster feedback. Run with:: .. _`Closing issues via commit messages`: https://help.github.com/articles/closing-issues-via-commit-messages/ .. _`About pull requests`: https://help.github.com/articles/using-pull-requests/ .. _tox: http://tox.readthedocs.io/en/latest/ + + +Tips for Getting Started with Pylint Development +------------------------------------------------ +* Read the :ref:`technical-reference`. It gives a short walkthrough of the pylint + codebase and will help you identify where you will need to make changes + for what you are trying to implement. +* :func:`astroid.extract_node` is your friend. Most checkers are AST based, + so you will likely need to interact with :mod:`astroid`. + A short example of how to use :func:`astroid.extract_node` is given + :ref:`here <astroid_extract_node>`. +* When fixing a bug for a specific check, search the code for the warning + message to find where the warning is raised, + and therefore where the logic for that code exists. + +A Typical Development Workflow +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#. Create a virtualenv in which to work:: + + $ tox + +#. Write the tests. See :ref:`functional_tests`. +#. Check that the tests fail:: + + $ tox + +#. Fix pylint! +#. Make sure your tests pass:: + + $ tox + + It is also possible to give tox a `pytest specifier <https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests>`_ + to run only your test:: + + $ tox pylint/test/test_functional.py::test_functional + +#. Package up and submit your changes as outlined in `repository`_. diff --git a/doc/exts/pylint_extensions.py b/doc/exts/pylint_extensions.py index a371cd275..eeb8d6026 100755 --- a/doc/exts/pylint_extensions.py +++ b/doc/exts/pylint_extensions.py @@ -48,7 +48,7 @@ def builder_inited(app): linter = PyLinter() linter.load_plugin_modules(modules) - extensions_doc = os.path.join(base_path, 'doc', 'reference_guide', 'extensions.rst') + extensions_doc = os.path.join(base_path, 'doc', 'technical_reference', 'extensions.rst') with open(extensions_doc, 'w') as stream: stream.write("Optional Pylint checkers in the extensions module\n") stream.write("=================================================\n\n") diff --git a/doc/exts/pylint_features.py b/doc/exts/pylint_features.py index 5322c27cb..fcb2d10e1 100755 --- a/doc/exts/pylint_features.py +++ b/doc/exts/pylint_features.py @@ -18,7 +18,7 @@ def builder_inited(app): linter = PyLinter() linter.load_default_plugins() - features = os.path.join(base_path, 'doc', 'reference_guide', 'features.rst') + features = os.path.join(base_path, 'doc', 'technical_reference', 'features.rst') with open(features, 'w') as stream: stream.write("Pylint features\n") stream.write("===============\n\n") diff --git a/doc/how_tos/custom_checkers.rst b/doc/how_tos/custom_checkers.rst new file mode 100644 index 000000000..abafb91fa --- /dev/null +++ b/doc/how_tos/custom_checkers.rst @@ -0,0 +1,284 @@ +.. _write_a_checker: + +How to Write a Checker +====================== +You can find some simple examples in the distribution +(`custom.py <https://github.com/PyCQA/pylint/blob/master/examples/custom.py>`_ +and +`custom_raw.py <https://github.com/PyCQA/pylint/blob/master/examples/custom_raw.py>`_). + +.. TODO Create custom_token.py + +There are three kinds of checkers: + +* Raw checkers, which analyse each module as a raw file stream. +* Token checkers, which analyse a file using the list of tokens that + represent the source code in the file. +* AST checkers, which work on an AST representation of the module. + +The AST representation is provided by the :mod:`astroid` library. +:mod:`astroid` adds additional information and methods +over :mod:`ast` in the standard library, +to make tree navigation and code introspection easier. + +.. TODO Writing a Raw Checker + +.. TODO Writing a Token Checker + +Writing an AST Checker +---------------------- +Let's implement a checker to make sure that all ``return`` nodes in a function +return a unique constant. +Firstly we will need to fill in some required boilerplate: + +.. code-block:: python + + import astroid + + from pylint.checkers import BaseChecker + from pylint.interfaces import IAstroidChecker + + class UniqueReturnChecker(BaseChecker): + __implements__ = IAstroidChecker + + name = 'unique-returns' + priority = -1 + msgs = { + 'W0001': ( + 'Returns a non-unique constant.', + 'non-unique-returns', + 'All constants returned in a function should be unique.' + ), + } + options = ( + ( + 'ignore-ints', + { + 'default': False, 'type': 'yn', 'metavar' : '<y_or_n>', + 'help': 'Allow returning non-unique integers', + } + ), + ) + + +So far we have defined the following required components of our checker: + +* A name. The name is used to generate a special configuration + section for the checker, when options have been provided. + +* A priority. This must be to be lower than 0. The checkers are ordered by + the priority when run, from the most negative to the most positive. + +* A message dictionary. Each checker is being used for finding problems + in your code, the problems being displayed to the user through **messages**. + The message dictionary should specify what messages the checker is + going to emit. It has the following format:: + + msgs = { + 'message-id': ( + 'displayed-message', 'message-symbol', 'message-help' + ) + } + + * The ``message-id`` should be a 5-digit number, + prefixed with a **message category**. + There are multiple message categories, + these being ``C``, ``W``, ``E``, ``F``, ``R``, + standing for ``Convention``, ``Warning``, ``Error``, ``Fatal`` and ``Refactoring``. + The rest of the 5 digits should not conflict with existing checkers + and they should be consistent across the checker. + For instance, + the first two digits should not be different across the checker. + + * The ``displayed-message`` is used for displaying the message to the user, + once it is emitted. + + * The ``message-symbol`` is an alias of the message id + and it can be used wherever the message id can be used. + + * The ``message-help`` is used when calling ``pylint --help-msg``. + +We have also defined an optional component of the checker. +The options list defines any user configurable options. +It has the following format:: + + options = ( + 'option-symbol': {'argparse-like-kwarg': 'value'}, + ) + +* The ``option-symbol`` is a unique name for the option. + This is used on the command line and in config files. + The hyphen is replaced by an underscore when used in the checker, + similarly to how you would use :class:`argparse.Namespace`. + +Next we'll track when we enter and leave a function. + +.. code-block:: python + + def __init__(self, linter=None): + super(UniqueReturnChecker, self).__init__(linter) + self._function_stack = [] + + def visit_functiondef(self, node): + self._function_stack.append([]) + + def leave_functiondef(self, node): + self._function_stack.pop() + +In the constructor we initialise a stack to keep a list of return nodes +for each function. +An AST checker is a visitor, and should implement +``visit_<lowered class name>`` or ``leave_<lowered class name>`` +methods for the nodes it's interested in. +In this case we have implemented ``visit_functiondef`` and ``leave_functiondef`` +to add a new list of return nodes for this function, +and to remove the list of return nodes when we leave the function. + +Finally we'll implement the check. +We will define a ``visit_return`` function, +which is called with a :class:`.astroid.node_classes.Return` node. + +.. _astroid_extract_node: +.. TODO We can shorten/remove this bit once astroid has API docs. +We'll need to be able to figure out what attributes a +:class:`.astroid.node_classes.Return` node has available. +We can use :func:`astroid.extract_node` for this:: + + >>> node = astroid.extract_node("return 5") + >>> node + <Return l.1 at 0x7efe62196390> + >>> help(node) + >>> node.value + <Const.int l.1 at 0x7efe62196ef0> + +We could also construct a more complete example:: + + >>> node_a, node_b = astroid.extract_node(""" + ... def test(): + ... if True: + ... return 5 #@ + ... return 5 #@ + """) + >>> node_a.value + <Const.int l.4 at 0x7efe621a74e0> + >>> node_a.value.value + 5 + >>> node_a.value.value == node_b.value.value + True + +For more information on :func:`astroid.extract_node`, +see the `astroid documentation <http://astroid.readthedocs.io/en/latest/>`_. + +Now we know how to use the astroid node, we can implement our check. + +.. code-block:: python + + def visit_return(self, node): + if not isinstance(node.value, astroid.node_classes.Const): + return + + for other_return in self._function_stack[-1]: + if (node.value.value == other_return.value.value and + not (self.config.ignore_ints and node.value.pytype() == int)): + self.add_message( + 'non-unique-returns', node=node, + ) + + self._function_stack[-1].append(node) + +Once we have established that the source code has failed our check, +we use :func:`~.BaseChecker.add_message` to emit our failure message. + +Finally, we need to register the checker with pylint. +Add the ``register`` function to the top level of the file. + +.. code-block:: python + + def register(linter): + linter.register_checker(UniqueReturnChecker(linter)) + +We are now ready to debug and test our checker! + +Debugging a Checker +------------------- +It is very simple to get to a point where we can use :mod:`pdb`. +We'll need a small test case. +Put the following into a Python file: + +.. code-block:: python + + def test(): + if True: + return 5 + return 5 + + def test2(): + if True: + return 1 + return 5 + +After inserting pdb into our checker and installing it, +we can run pylint with only our checker:: + + $ pylint --load-plugins=my_plugin --disable=all --enable=non-unique-returns test.py + (Pdb) + +Now we can debug our checker! + +Testing a Checker +----------------- +Pylint is very well suited to test driven development. +You can implement the template of the checker, +produce all of your test cases and check that they fail, +implement the checker, +then check that all of your test cases work. + +Pylint provides a :class:`pylint.testutils.CheckerTestCase` +to make test cases very simple. +We can use the example code that we used for debugging as our test cases. + +.. code-block:: python + + import my_plugin + import pylint.testutils + + class TestUniqueReturnChecker(pylint.testutils.CheckerTestCase): + CHECKER_CLASS = my_plugin.UniqueReturnChecker + + def test_finds_non_unique_ints(self): + func_node, return_node_a, return_node_b = astroid.extract_node(""" + def test(): #@ + if True: + return 5 #@ + return 5 #@ + """) + + self.checker.visit_functiondef(func_node) + self.checker.visit_return(return_node_a) + with self.assertAddsMessages( + pylint.testutils.Message( + msg_id='non-unique-returns', + node=return_node_b, + ), + ): + self.checker.visit_return(return_node_b) + + def test_ignores_unique_ints(self): + func_node, return_node_a, return_node_b = astroid.extract_node(""" + def test(): #@ + if True: + return 1 #@ + return 5 #@ + """) + + with self.assertNoMessages(): + self.checker.visit_functiondef(func_node) + self.checker.visit_return(return_node_a) + self.checker.visit_return(return_node_b) + + +Once again we are using :func:`astroid.extract_node` to +construct our test cases. +:class:`pylint.testutils.CheckerTestCase` has created the linter and checker for us, +we simply simulate a traversal of the AST tree +using the nodes that we are interested in. diff --git a/doc/how_tos/index.rst b/doc/how_tos/index.rst new file mode 100644 index 000000000..7ec3a2f36 --- /dev/null +++ b/doc/how_tos/index.rst @@ -0,0 +1,10 @@ +How To Guides +============= + +.. toctree:: + :maxdepth: 2 + :titlesonly: + + custom_checkers + plugins + transform_plugins diff --git a/doc/reference_guide/plugins.rst b/doc/how_tos/plugins.rst index 21926dbdb..abbf2bdcb 100644 --- a/doc/reference_guide/plugins.rst +++ b/doc/how_tos/plugins.rst @@ -1,13 +1,14 @@ .. -*- coding: utf-8 -*-
-================
-Extending Pylint
-================
-
-Pylint provides support for writing two types of extensions. First, there
-is the concept of **checkers**, which can be used for finding problems in your
-code. Secondly, there is also the concept of **transform plugin**, which represents a
-way through which the inference and the capabilities of Pylint can be enhanced
+How To Write a Pylint Plugin
+============================
+
+Pylint provides support for writing two types of extensions.
+First, there is the concept of **checkers**,
+which can be used for finding problems in your code.
+Secondly, there is also the concept of **transform plugin**,
+which represents a way through which the inference and
+the capabilities of Pylint can be enhanced
and tailored to a particular module, library of framework.
In general, a plugin is a module which should have a function ``register``,
@@ -36,10 +37,4 @@ object, by calling the following inside the ``register`` function:: linter.register_checker(OurChecker(linter))
-
-.. toctree::
- :maxdepth: 2
- :titlesonly:
-
- custom_checkers
- transform_plugins
+For more information on writing a checker see _`write_a_checker`.
diff --git a/doc/reference_guide/transform_plugins.rst b/doc/how_tos/transform_plugins.rst index 39db6c2b1..39db6c2b1 100644 --- a/doc/reference_guide/transform_plugins.rst +++ b/doc/how_tos/transform_plugins.rst diff --git a/doc/index.rst b/doc/index.rst index c27f062f5..57e194eef 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -10,7 +10,8 @@ Pylint User Manual tutorial user_guide/index.rst - reference_guide/index.rst + how_tos/index.rst + technical_reference/index.rst development_guide/index.rst faq diff --git a/doc/reference_guide/custom_checkers.rst b/doc/reference_guide/custom_checkers.rst deleted file mode 100644 index 800006b0f..000000000 --- a/doc/reference_guide/custom_checkers.rst +++ /dev/null @@ -1,61 +0,0 @@ -Custom checkers -^^^^^^^^^^^^^^^ - -Writing your own checker ------------------------- -You can find some simple examples in the examples -directory of the distribution (custom.py and custom_raw.py). - -First, there are two kinds of checkers: - -* raw checkers, which are analysing each module as a raw file stream -* AST checkers, which are working on an AST representation of the module - -The AST representation used is an extension of the one provided with the -standard Python distribution in the `ast package`_. The extension -adds additional information and methods on the tree nodes to ease -navigation and code introspection. - -An AST checker is a visitor, and should implement -`visit_<lowered class name>` or `leave_<lowered class name>` -methods for the nodes it's interested in. To get description of the different -classes used in an ast tree, look at the `ast package`_ documentation. -For each module, Pylint's engine is doing the following: - -1. give the module source file as a stream to raw checkers -2. get an AST representation for the module -3. make a depth first descent of the tree, calling ``visit_<>`` on each AST - checker when entering a node, and ``leave_<>`` on the back traversal - -A checker is composed from multiple components, which needs to be given -in order for it to work properly: - -1. a name. The name is internally for a couple of things, one of them - being used for generating a special configuration - section of the checker, in case in has provided options. - -2. a priority that needs to be lower than 0. The checkers are ordered by - the priority, from the most negative to the most positive. - -3. a message dictionary. Each checker is being used for finding problems - in your code, the problems being displayed to the user through **messages**. - The message dictionary should specify what messages the said checker is - going to emit. It has the following format:: - - msgs = {'message-id': ('displayed-message', 'message-symbol', 'message-help')} - - The ``message id`` should be a 5-digits number, prefixed with a **message category**. - There are multiple message categories, these being ``C``, ``W``, ``E``, ``F``, ``R``, - standing for ``Convention``, ``Warning``, ``Error``, ``Fatal`` and ``Refactoring``. - The rest of the 5 digits should not conflict with existing checkers and they should - be consistent across the checker. For instance, the first two digits should not be - different across the checker. - - The displayed message is used for displaying the message to the user, once it is emitted. - The message symbol is an alias of the message id and it can be used wherever the message id - can be used. The message help is used when calling ``pylint --help-msg``. - -4. An options list (optional) - - -.. _`ast package`: http://docs.python.org/2/library/ast diff --git a/doc/reference_guide/index.rst b/doc/reference_guide/index.rst deleted file mode 100644 index d17868992..000000000 --- a/doc/reference_guide/index.rst +++ /dev/null @@ -1,11 +0,0 @@ - -Reference Guide -=============== - -.. toctree:: - :maxdepth: 2 - :titlesonly: - - plugins - extensions - features
\ No newline at end of file diff --git a/doc/technical_reference/checkers.rst b/doc/technical_reference/checkers.rst new file mode 100644 index 000000000..d59e316c6 --- /dev/null +++ b/doc/technical_reference/checkers.rst @@ -0,0 +1,7 @@ +Checkers +-------- +All of the default pylint checkers exist in ``pylint.checkers``. +This is where most of pylint's brains exist. +Most checkers are AST based and so use :mod:`astroid`. +``pylint.checkers.utils`` provides a large number of utility methods for +dealing with :mod:`astroid`. diff --git a/doc/technical_reference/index.rst b/doc/technical_reference/index.rst new file mode 100644 index 000000000..5e603f90d --- /dev/null +++ b/doc/technical_reference/index.rst @@ -0,0 +1,19 @@ +.. _technical-reference: + +Technical Reference +=================== + +.. TODO Configuration + +.. TODO Messages + +.. TODO Reports + +.. toctree:: + :maxdepth: 2 + :titlesonly: + + startup + checkers + extensions + features diff --git a/doc/technical_reference/startup.rst b/doc/technical_reference/startup.rst new file mode 100644 index 000000000..5a2063d4a --- /dev/null +++ b/doc/technical_reference/startup.rst @@ -0,0 +1,22 @@ +Startup and the Linter Class +---------------------------- +The two main classes in :mod:`pylint.lint` are +:class:`.pylint.lint.Run` and :class:`.pylint.lint.PyLinter`. + +The :class:`.pylint.lint.Run` object is responsible for starting up pylint. +It does some basic checking of the given command line options to +find the initial hook to run, +find the config file to use, +and find which plugins have been specified. +It can then create the master :class:`.pylint.lint.PyLinter` instance +and initialise it with the config file and plugins that were discovered +when preprocessing the command line options. +Finally the :class:`.pylint.lint.Run` object launches any child linters +for parallel jobs, and starts the linting process. + +The :class:`.pylint.lint.PyLinter` is responsible for coordinating the +linting process. +It parses the configuration and provides it for the checkers and other plugins, +it handles the messages emitted by the checkers, +it handles the output reporting, +and it launches the checkers. diff --git a/doc/whatsnew/index.rst b/doc/whatsnew/index.rst index 17f395ebc..8c8bb0ac2 100644 --- a/doc/whatsnew/index.rst +++ b/doc/whatsnew/index.rst @@ -9,6 +9,7 @@ High level descriptions of the most important changes between major Pylint versi .. toctree:: :maxdepth: 1 + 1.8.rst 1.7.rst 1.6.rst diff --git a/examples/custom.py b/examples/custom.py index ee4ed65cf..54c2937b1 100644 --- a/examples/custom.py +++ b/examples/custom.py @@ -3,38 +3,68 @@ import astroid from pylint.interfaces import IAstroidChecker from pylint.checkers import BaseChecker + +# This is our checker class. +# Checkers should always inherit from `BaseChecker`. class MyAstroidChecker(BaseChecker): - """add member attributes defined using my own "properties" function - to the class locals dictionary - """ - + """Add class member attributes to the class locals dictionary.""" + + # This class variable defines the type of checker that we are implementing. + # In this case, we are implementing an AST checker. __implements__ = IAstroidChecker + # The name defines a custom section of the config for this checker. name = 'custom' + # The priority indicates the order that pylint will run the checkers. + priority = -1 + # This class variable declares the messages (ie the warnings and errors) + # that the checker can emit. msgs = { + # Each message has a code, a message that the user will see, + # a unique symbol that identifies the message, + # and a detailed help message + # that will be included in the documentation. 'W0001': ('Message that will be emitted', 'message-symbol', 'Message help') } - options = () - # this is important so that your checker is executed before others - priority = -1 + # This class variable declares the options + # that are configurable by the user. + options = ( + # Each option definition has a name which is used on the command line + # and in config files, and a dictionary of arguments + # (similar to those to those to + # argparse.ArgumentParser.add_argument). + ('store-locals-indicator', + {'default': 'properties', + 'help': ('The expression name that indicates that the locals should ' + 'be stored'), + }, + ), + ) def visit_call(self, node): - """called when a Call node is encountered. + """Called when a :class:`.astroid.node_classes.Call` node is visited. + + See :mod:`astroid` for the description of available nodes. - See astroid for the description of available nodes.""" + :param node: The node to check. + :type node: astroid.node_classes.Call + """ if not (isinstance(node.func, astroid.Attribute) and isinstance(node.func.expr, astroid.Name) - and node.func.expr.name == 'properties' + and node.func.expr.name == self.config.store_locals_indicator and node.func.attrname == 'create'): return in_class = node.frame() for param in node.args: in_class.locals[param.name] = node - + def register(linter): - """required method to auto register this checker""" + """This required method auto registers the checker. + + :param linter: The linter to register the checker to. + :type linter: pylint.lint.PyLinter + """ linter.register_checker(MyAstroidChecker(linter)) - |