Plugin Handling
Plugin Management
Flake8 3.0 added support for other plugins besides those which define new checks. It now supports:
extra checks
alternative report formatters
To facilitate this, Flake8 needed a more mature way of managing plugins.
Thus, we developed the PluginManager
which accepts a namespace and will load
the plugins for that namespace. A PluginManager
creates and manages many
Plugin
instances.
A Plugin
lazily loads the underlying entry-point provided by setuptools.
The entry-point will be loaded either by calling
load_plugin()
or accessing the plugin
attribute. We also use this abstraction to retrieve options that the plugin
wishes to register and parse.
The only public method the PluginManager
provides is
map()
. This will accept a function
(or other callable) and call it with each plugin as the first parameter.
We build atop the PluginManager
with the PluginTypeManager
. It is expected that users of
the PluginTypeManager
will subclass it and specify the namespace
, e.g.,
class ExamplePluginType(flake8.plugin.manager.PluginTypeManager):
namespace = 'example-plugins'
This provides a few extra methods via the PluginManager
’s map
method.
Finally, we create two classes of plugins:
These are used to interact with each of the types of plugins individually.
Note
Our inspiration for our plugin handling comes from the author’s extensive
experience with stevedore
.
Default Plugins
Finally, Flake8 has always provided its own plugin shim for Pyflakes. As
part of that we carry our own shim in-tree and now store that in
flake8.plugins.pyflakes
.
Flake8 also registers plugins for pep8. Each check in pep8 requires
different parameters and it cannot easily be shimmed together like Pyflakes
was. As such, plugins have a concept of a “group”. If you look at our
setup.py
you will see that we register pep8 checks roughly like so:
pep8.<check-name> = pep8:<check-name>
We do this to identify that <check-name>>
is part of a group. This also
enables us to special-case how we handle reporting those checks. Instead of
reporting each check in the --version
output, we report pep8
and check
pep8
the module for a __version__
attribute. We only report it once
to avoid confusing users.
API Documentation
- class flake8.plugins.manager.PluginManager(namespace: str, local_plugins: Optional[List[str]] = None)[source]
Find and manage plugins consistently.
- __init__(namespace: str, local_plugins: Optional[List[str]] = None) None [source]
Initialize the manager.
- Parameters:
namespace (str) – Namespace of the plugins to manage, e.g., ‘flake8.extension’.
local_plugins (list) – Plugins from config (as “X = path.to:Plugin” strings).
- map(func, *args, **kwargs)[source]
Call
func
with the plugin and *args and **kwargs after.This yields the return value from
func
for each plugin.- Parameters:
func (collections.Callable) –
Function to call with each plugin. Signature should at least be:
def myfunc(plugin): pass
Any extra positional or keyword arguments specified with map will be passed along to this function after the plugin. The plugin passed is a
Plugin
.args – Positional arguments to pass to
func
after each plugin.kwargs – Keyword arguments to pass to
func
after each plugin.
- class flake8.plugins.manager.Plugin(name, entry_point, local=False)[source]
Wrap an EntryPoint from setuptools and other logic.
- __init__(name, entry_point, local=False)[source]
Initialize our Plugin.
- Parameters:
name (str) – Name of the entry-point as it was registered with setuptools.
entry_point (setuptools.EntryPoint) – EntryPoint returned by setuptools.
local (bool) – Is this a repo-local plugin?
- is_in_a_group()[source]
Determine if this plugin is in a group.
- Returns:
True if the plugin is in a group, otherwise False.
- Return type:
bool
- load_plugin()[source]
Retrieve the plugin for this entry-point.
This loads the plugin, stores it on the instance and then returns it. It does not reload it after the first time, it merely returns the cached plugin.
- Returns:
Nothing
- property off_by_default
Return whether the plugin is ignored by default.
- property parameter_names
List of argument names that need to be passed to the plugin.
- property parameters
List of arguments that need to be passed to the plugin.
- property plugin
Load and return the plugin associated with the entry-point.
This property implicitly loads the plugin and then caches it.
- property plugin_name
Return the name of the plugin.
- provide_options(optmanager, options, extra_args)[source]
Pass the parsed options and extra arguments to the plugin.
- register_options(optmanager)[source]
Register the plugin’s command-line options on the OptionManager.
- Parameters:
optmanager (flake8.options.manager.OptionManager) – Instantiated OptionManager to register options on.
- Returns:
Nothing
- property version
Return the version of the plugin.
- class flake8.plugins.manager.PluginTypeManager(local_plugins=None)[source]
Parent class for most of the specific plugin types.
- get(name, default=None)[source]
Retrieve the plugin referred to by
name
or return the default.- Parameters:
name (str) – Name of the plugin to retrieve.
default – Default value to return.
- Returns:
Plugin object referred to by name, if it exists.
- Return type:
- property names
Proxy attribute to underlying manager.
- property plugins
Proxy attribute to underlying manager.
- class flake8.plugins.manager.Checkers(local_plugins=None)[source]
All of the checkers registered through entry-points or config.
- property ast_plugins
List of plugins that expect the AST tree.
- checks_expecting(argument_name)[source]
Retrieve checks that expect an argument with the specified name.
Find all checker plugins that are expecting a specific argument.
- property logical_line_plugins
List of plugins that expect the logical lines.
- property physical_line_plugins
List of plugins that expect the physical lines.