{"id":4539,"library":"flake8-plugin-utils","title":"flake8-plugin-utils","description":"flake8-plugin-utils is a Python package providing base classes and utility functions to simplify the creation of custom plugins for the Flake8 linter. It aims to reduce boilerplate and offer helpful tools for AST (Abstract Syntax Tree) analysis within Flake8 plugins. The current version is 1.3.3, released on 2022-01-14, with a moderate release cadence based on contributions.","status":"active","version":"1.3.3","language":"en","source_language":"en","source_url":"https://github.com/afonasev/flake8-plugin-utils","tags":["flake8","linter","plugin","code quality","ast","static analysis"],"install":[{"cmd":"pip install flake8-plugin-utils","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"Error","correct":"from flake8_plugin_utils import Error"},{"symbol":"Visitor","correct":"from flake8_plugin_utils import Visitor"},{"symbol":"Plugin","correct":"from flake8_plugin_utils import Plugin"},{"symbol":"assert_error","correct":"from flake8_plugin_utils import assert_error"},{"symbol":"assert_not_error","correct":"from flake8_plugin_utils import assert_not_error"}],"quickstart":{"code":"from flake8_plugin_utils import Error, Visitor, Plugin, assert_error\nimport ast\n\n# Define a custom error\nclass MyError(Error):\n    code = 'X100'\n    message = 'Avoid using the name {thing}'\n\n# Define a custom visitor\nclass MyVisitor(Visitor):\n    def visit_Name(self, node: ast.Name):\n        if node.id == 'footgun':\n            self.report(node, thing=node.id)\n\n# Define the plugin (without configuration for simplicity)\nclass MyPlugin(Plugin[None]):\n    name = 'flake8-myplugin'\n    version = '0.1.0'\n    visitors = [MyVisitor]\n\n# Example of testing the plugin (typically in a test suite)\ndef test_my_plugin_error():\n    src = \"\"\"import os\\nfootgun = 1\"\"\"\n    assert_error(MyVisitor, src, MyError, row=2, col=0, thing='footgun')\n\n# To run the linter (outside this snippet, typically from command line)\n# flake8 --isolated --select=X100 my_code.py\n# or integrate via entry points in setup.py\n","lang":"python","description":"This quickstart demonstrates how to define a custom Flake8 error, a visitor to detect specific AST patterns (here, the use of 'footgun' as a variable name), and a minimal plugin integrating these components. It also shows a basic test using `assert_error`."},"warnings":[{"fix":"Change `class MyPlugin(Plugin):` to `class MyPlugin(Plugin[None]):` and `class MyVisitor(Visitor):` to `class MyVisitor(Visitor[None]):` if no custom config is used. Otherwise, use your config class as the type parameter (e.g., `Plugin[MyConfig]`).","message":"When using `flake8-plugin-utils` with typing (e.g., MyPy), the `Plugin` and `Visitor` classes are generic. If your plugin does not have any custom configuration, you must explicitly inherit from `Plugin[None]` and `Visitor[None]` to avoid type-checking errors.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Verify your `setup.py` contains an `entry_points` section like `{'flake8.extension': ['X = your_package.your_module:YourPluginClass']}`. The 'X' should be your plugin's unique error code prefix (e.g., 'X100', 'Y200').","message":"Flake8 plugins are registered via `setuptools` entry points. Incorrectly configuring the `entry_points` in your `setup.py` or `pyproject.toml` can lead to your plugin not being detected or conflicting with other plugins. Ensure your entry point is unique and correctly points to your plugin class.","severity":"gotcha","affected_versions":"All"},{"fix":"Manually remove any orphaned configuration sections related to uninstalled plugins from your Flake8 configuration files. Use `flake8 --isolated` during testing to ensure only command-line options are considered, or specify a clean config file.","message":"When developing and testing Flake8 plugins, ensure you understand how Flake8 handles configuration files and local plugins. Issues can arise if configuration sections for uninstalled plugins are left in `.flake8`, `setup.cfg`, or `pyproject.toml`.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}