Skip to main content

The package provides base classes and utils for flake8 plugin writing

Project description

flake8-plugin-utils

pypi Python: 3.6+ Downloads Build Status Code coverage License: MIT Code style: black

The package provides base classes and utils for flake8 plugin writing.

Installation

pip install flake8-plugin-utils

Example

Write simple plugin

from flake8_plugin_utils import Error, Visitor, Plugin

class MyError(Error):
    code = 'X100'
    message = 'my error'

class MyVisitor(Visitor):
    def visit_ClassDef(self, node):
        self.error_from_node(MyError, node)

class MyPlugin(Plugin):
    name = 'MyPlugin'
    version = '0.1.0'
    visitors = [MyVisitor]

and test it with pytest

from flake8_plugin_utils import assert_error, assert_not_error

def test_code_with_error():
    assert_error(MyVisitor, 'class Y: pass', MyError)

def test_code_without_error():
    assert_not_error(MyVisitor, 'x = 1')

Configuration

To add configuration to a plugin, do the following:

  1. Implement classmethod add_options in your plugin class, as per the flake8 docs.
  2. Override classmethod parse_options_to_config in your plugin class to return any object holding the options you need.
  3. If you need a custom __init__ for your visitor, make sure it accepts a keyword argument named config and pass it to super().__init__
  4. Use self.config in visitor code.

Example:

from flake8_plugin_utils import Error, Visitor, Plugin, assert_error

class MyError(Error):
    code = 'X100'
    message = 'my error with {thing}'

class MyConfig:
    def __init__(self, config_option):
        self.config_option = config_option

class MyVisitorWithConfig(Visitor):
    def visit_ClassDef(self, node):
        self.error_from_node(
            MyError, node, thing=f'{node.name} {self.config.config_option}'
        )

class MyPluginWithConfig(Plugin):
    name = 'MyPluginWithConfig'
    version = '0.0.1'
    visitors = [MyVisitorWithConfig]

    @classmethod
    def add_options(cls, options_manager):
        options_manager.add_option('--config_option', parse_from_config=True, ...)

    @classmethod
    def parse_options_to_config(cls, option_manager, options, args):
        return MyConfig(config_option=options.config_option)


def test_code_with_error():
    assert_error(
        MyVisitorWithConfig,
        'class Y: pass',
        MyError,
        config=MyConfig(config_option='123'),
        thing='Y 123',
    )

Formatting

Your Errors can take formatting arguments in their message:

from flake8_plugin_utils import Error, Visitor, assert_error

class MyFormattedError(Error):
    code = 'X101'
    message = 'my error with {thing}'

class MyFormattedVisitor(Visitor):
    def visit_ClassDef(self, node):
        self.error_from_node(MyFormattedError, node, thing=node.name)

def test_code_with_error():
    assert_error(
        MyFormattedVisitor,
        'class Y: pass',
        MyFormattedError,
        thing='Y',
    )

Usage with typing/mypy

The Plugin and Visitor classes are generic with the config class as type parameter. If your plugin does not have any config, inherit it from Plugin[None] and the visitors from Visitor[None]. Otherwise, use the config class as the type parameter (e.g. Plugin[MyConfig] and Visitor[MyConfig] in the above example).

Utility functions

  • assert_error, assert_not_error Utilities for testing visitors (see examples above).

  • is_true, is_false, is_none Convenience functions to check if an AST node represents a True/False/None value.

  • check_equivalent_nodes Checks if two given AST nodes are equivalent. The nodes are considered equivalent in the following cases:

    • dicts -- if they contain same key-value pairs, possibly in different order, with duplicates and **expansions taken into account
    • sets -- if they contain same elements, possibly in different order, with duplicates taken into account
    • anything else -- if they represent the same AST, regardless of formatting (with any dicts in sets inside checked according to the rules above)

For developers

Show help

make help

Create venv and install deps

make init

Install git precommit hook

make precommit

Run linters, autoformat, tests etc.

make pretty lint test

Bump new version

make bump_major
make bump_minor
make bump_patch

Change Log

Unreleased

  • ...

1.3.3 - 2022-01-14

  • add py.typed file (#78)

1.3.2 - 2021-05-05

  • Drop noqa detection (#56)
  • docs: Add help for Makefile

1.3.1 - 2020-08-06

  • Fix handling of encoding when loading files (#37)

1.3.0 - 2020-03-26

  • add check_equivalent_nodes utility function

1.2.0 - 2020-03-06

  • add config argument to assert_error and assert_not_error

1.1.1 - 2020-03-02

  • ignore encoding errors when reading strings for noqa validation

1.1.0 - 2020-03-01

  • add ability for plugins to parse and use configuration NB: this change breaks type-checking if you use typing/mypy. Change your code to inherit from Plugin[None] and Visitor[None] to fix.

1.0.0 - 2019-05-23

  • add message formatting to Error

0.2.1 - 2019-04-01

  • don`t strip before src dedent in _error_from_src
  • add is_none, is_true, is_false util functions

0.2.0 - 2019.02.21

  • add assert methods

0.1.0 - 2019.02.09

  • initial

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flake8-plugin-utils-1.3.3.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

flake8_plugin_utils-1.3.3-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file flake8-plugin-utils-1.3.3.tar.gz.

File metadata

  • Download URL: flake8-plugin-utils-1.3.3.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.14 CPython/3.10.10 Darwin/22.4.0

File hashes

Hashes for flake8-plugin-utils-1.3.3.tar.gz
Algorithm Hash digest
SHA256 39f6f338d038b301c6fd344b06f2e81e382b68fa03c0560dff0d9b1791a11a2c
MD5 ed50d2e9196cfa51cb67308fb6f35912
BLAKE2b-256 511453727a2bc5bbda1e1f7e266e0e2d2718e5eb6c943a1e8cc2b33e5af002e0

See more details on using hashes here.

File details

Details for the file flake8_plugin_utils-1.3.3-py3-none-any.whl.

File metadata

File hashes

Hashes for flake8_plugin_utils-1.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e4848c57d9d50f19100c2d75fa794b72df068666a9041b4b0409be923356a3ed
MD5 b19c78a6bafd15a9530ce31a87262641
BLAKE2b-256 daa723c012c9becaacb24e9ba8e359e48db5f96982d505e38a3e7003902c5b9f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page