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', ...)

    @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.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.2.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

flake8_plugin_utils-1.3.2-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flake8-plugin-utils-1.3.2.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.6.7 Linux/4.15.0-1077-gcp

File hashes

Hashes for flake8-plugin-utils-1.3.2.tar.gz
Algorithm Hash digest
SHA256 20fa2a8ca2decac50116edb42e6af0a1253ef639ad79941249b840531889c65a
MD5 342ab86fad087a9190e354e2fade6a19
BLAKE2b-256 c798c5578cb38ec12898eded60c790535972eeff3e40d068271ac09cf30d0ec1

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for flake8_plugin_utils-1.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1fe43e3e9acf3a7c0f6b88f5338cad37044d2f156c43cb6b080b5f9da8a76f06
MD5 b185ca4ccc7a32cc9a8274d8530e2e20
BLAKE2b-256 cf803af9f57f3e1a9cde22c3561aef126c937d72d0f0bf9c068b502d82aa9179

See more details on using hashes here.

Provenance

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