Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No documentation on how to write plugins. #556

Open
asottile opened this issue Apr 3, 2021 · 8 comments
Open

No documentation on how to write plugins. #556

asottile opened this issue Apr 3, 2021 · 8 comments

Comments

@asottile
Copy link
Member

asottile commented Apr 3, 2021

In GitLab by @graingert on Jan 18, 2017, 04:39

I currently maintain https://pypi.python.org/pypi/flake8-commas and I'm trying to port it to flake8 >=3.

I currently only need the simple tokenize token stream to work.

However there's no documentation on what I should do to change my plugin to work with flake8 3.

http://flake8.pycqa.org/en/latest/plugin-development/index.html#getting-started
and http://flake8.pycqa.org/en/latest/plugin-development/registering-plugins.html

mention adding an entry point 'X = flake8_example:ExamplePlugin',

but not what ExamplePlugin should look like.

Do I use a run method? __init__ ? etc.

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @sigmavirus24 on Jan 18, 2017, 05:09

Would you prefer more examples of plugins or just an interface definition that plugins need to satisfy?

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @graingert on Jan 18, 2017, 05:29

Now that you've given me the option, I'd like both :D

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @sigmavirus24 on Jan 21, 2017, 05:32

@graingert then I expect you to do the review on the pull request that will be made for this. ;)

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @graingert on Jan 22, 2017, 03:34

Sure. If you can provide a mypy abc that would be even better

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @pawamoy on Jun 18, 2020, 07:17

+1!

I just started trying to write a check plugin for Flake8, and nowhere in the docs could I find an example of what the plugin should look like. The docs mention add_options and parse_options, but do not show where to put them.

  • Should my plugin inherit from a base class?
  • Should it declare some attributes?
  • What methods should I implement?

OK, at this point I just searched for a recent plugin to see how it's written.
It would be nice if the docs showed a minimal example, something like this:

class MyFlake8Plugin:
    name = 'my-flake8-plugin'
    version = 0.2.3

    my_option = None
    default_my_option = 3

    def __init__(self, tree, filename: str):
        self.filename = filename
        self.tree = tree
        if MyFlake8Plugin.my_option is None:
            MyFlake8Plugin.my_option = self.default_my_option 

    @classmethod
    def add_options(cls, parser) -> None:
        parser.add_option(
            '--my-option ',
            type=int,
            parse_from_config=True,
            default=cls.default_my_option,
        )

    @classmethod
    def parse_options(cls, options) -> None:
        cls.my_option = int(options.my_option )

    def run(self):
        errors = [...]  # compute errors with self.tree
        for error in errors:
            yield (
                error.lineno,
                error.col_offset,
                f"ABC{error.number} {error.message}",
                type(self),
            )

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @asottile on Jun 18, 2020, 09:17

fwiw, I threw together a youtube video about making a plugin that might be helpful

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @pawamoy on Jun 18, 2020, 09:56

Thanks, I love astpretty, I wish I knew it before!

@asottile
Copy link
Member Author

asottile commented Apr 3, 2021

In GitLab by @spookylukey on Dec 21, 2020, 02:50

Thanks @pawamoy that's really helpful.

I found a simpler case that is possible using just a function. This one operates on physical lines, so the expected returned items are just (text_offset_into_line, error_message)

def no_bare_typing_import(physical_line):
    if physical_line == 'import typing\n':
        return [(0, "XXX001 'import typing' found, use 'from typing import ...' "
                    "instead for shorter type signatures")]


no_bare_typing_import.name = no_bare_typing_import.__name__
no_bare_typing_import.version = '1.0'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant