Custom Python linting through AST expressions

Overview

bellybutton

Build Status PyPI version PyPI - Python Version

bellybutton is a customizable, easy-to-configure linting engine for Python.

What is this good for?

Tools like pylint and flake8 provide, out-of-the-box, a wide variety of rules for enforcing Python best practices, ensuring PEP-8 compliance, and avoiding frequent sources of bugs. However, many projects have project-specific candidates for static analysis, such as internal style guides, areas of deprecated functionality, or common sources of error. This is especially true of those projects with many contributors or with large or legacy codebases.

bellybutton allows custom linting rules to be specified on a per-project basis and detected as part of your normal build, test and deployment process and, further, makes specifying these rules highly accessible, greatly lowering the cost of adoption.

Give bellybutton a try if:

  • You find yourself making the same PR comments over and over again
  • You need a means of gradually deprecating legacy functionality
  • You're looking to build a self-enforcing style guide
  • Your project needs to onboard new or junior developers more quickly and effectively
  • You have Python nitpicks that go beyond what standard linting tools enforce

Installation & getting started

bellybutton can be installed via:

pip install bellybutton

Once installed, running

bellybutton init

in your project's root directory will create a .bellybutton.yml configuration file with an example rule for you to begin adapting. bellybutton will also try to provide additional rule settings based on the directory structure of your project.

Once you have configured bellybutton for your project, running

bellybutton lint

will lint the project against the rules specified in your .bellybutton.yml. Additionally, running

bellybutton lint --modified-only

will, if using git, only lint those files that differ from origin/master.

For adding bellybutton to your CI pipeline, take a look at this repository's tox configuration and .travis.yml as an example.

Concepts

Rules

Rules in bellybutton supply patterns that should be caught and cause linting to fail. Rules as specified in your .bellybutton.yml configuration must consist of:

  • A description description, expressing the meaning of the rule
  • An expression expr, specifying the pattern to be caught - either as an astpath expression or as a regular expression (!regex ...).

Additionally, the key used for the rule within the rules mapping serves as its name.

Rules may also consist of:

  • Settings settings that specify on which files the rule is to be enforced, as well as whether it can be ignored via a # bb: ignore comment
  • An example example of Python code that would be matched by the rule
  • A counter-example instead of an alternative piece of code, for guiding the developer in fixing their linting error.

These example and instead clauses are checked at run-time to ensure that they respectively are and are not matched by the rule's expr.

As an example, a rule to lint for a deprecated function call using an astpath expression might look like:

DeprecatedFnCall:
  description: `deprecated_fn` will be deprecated in v9.1.2. Please use `new_fn` instead.
  expr: //Call[func/Name/@id='deprecated_fn']
  example: "deprecated_fn(*values)"
  instead: "new_fn(values)"

Settings

!settings nodes specify:

  • included paths on which rules are to be run, using glob notation
  • excluded paths on which rules are not to be run (even when matching the included paths)
  • A boolean allow_ignore which determines whether rules can be ignored, providing the line matching the rule has a # bb: ignore comment.

Additionally, at the root level of .bellybutton.yml, a default_settings setting may be specified which will be used by rules without explicit settings. Each rule must either have a settings parameter or be able to fall back on the default_settings.

As an example, a !settings node to lint only a specific module might look like:

my_module_settings: !settings
  included:
    - ~+/my_package/my_module.py
  excluded: []
  allow_ignore: no

Example usage

Check out this repository's .bellybutton.yml as an example bellybutton configuration file, and astpath's README for examples of the types of patterns you can lint for using bellybutton.

Development status

bellybutton is in an alpha release and, as such, is missing some key features, documentation, and full test coverage. Further, bellybutton is not optimized for performance on extremely large codebases and may contain breaking bugs. Please report any bugs encountered.

Known issues:

  • The !chain and !verbal expression nodes are not yet implemented

Contacts

Owner
H. Chase Stevens
Metaprogramming, natural language processing, and global optimization technique enthusiast.
H. Chase Stevens
Easy saving and switching between multiple KDE configurations.

Konfsave Konfsave is a config manager. That is, it allows you to save, back up, and easily switch between different (per-user) system configurations.

42 Sep 25, 2022
Pyright extension for coc.nvim

coc-pyright Pyright extension for coc.nvim Install :CocInstall coc-pyright Note: Pyright may not work as expected if can't detect project root correct

Heyward Fann 1.1k Jan 02, 2023
Collection of awesome Python types, stubs, plugins, and tools to work with them.

Awesome Python Typing Collection of awesome Python types, stubs, plugins, and tools to work with them. Contents Static type checkers Dynamic type chec

TypedDjango 1.2k Jan 04, 2023
Stubs with type annotations for ordered-set Python library

ordered-set-stubs - stubs with type annotations for ordered-set Python library Archived - now type annotations are the part of the ordered-set library

Roman Inflianskas 2 Feb 06, 2020
Mypy stubs for the PyQt5 framework

Mypy stubs for the PyQt5 framework This repository holds the stubs of the PyQt5 framework. It uses the stub files that are produced during compilation

62 Nov 22, 2022
Flake8 extension for checking quotes in python

Flake8 Extension to lint for quotes. Major update in 2.0.0 We automatically encourage avoiding escaping quotes as per PEP 8. To disable this, use --no

Zachary Heller 157 Dec 13, 2022
Flake8 extension for enforcing trailing commas in python

Flake8 Extension to enforce better comma placement. Usage If you are using flake8 it's as easy as: pip install flake8-commas Now you can avoid those a

Python Code Quality Authority 127 Sep 03, 2022
Tool for pinpointing circular imports in Python. Find cyclic imports in any project

Pycycle: Find and fix circular imports in python projects Pycycle is an experimental project that aims to help python developers fix their circular de

Vadim Kravcenko 311 Dec 15, 2022
MyPy types for WSGI applications

WSGI Types for Python This is an attempt to bring some type safety to WSGI applications using Python's new typing features (TypedDicts, Protocols). It

Blake Williams 2 Aug 18, 2021
Python classes with types validation at runtime.

typedclasses Python classes with types validation at runtime. (Experimental & Under Development) Installation You can install this library using Pytho

Izhar Ahmad 8 Feb 06, 2022
Silence mypy by adding or removing code comments

mypy-silent Automatically add or remove # type: ignore commends to silence mypy. Inspired by pylint-silent Why? Imagine you want to add type check for

Wu Haotian 8 Nov 30, 2022
❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

flake8-comprehensions A flake8 plugin that helps you write better list/set/dict comprehensions. Requirements Python 3.6 to 3.9 supported. Installation

Adam Johnson 398 Dec 23, 2022
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
Unbearably fast O(1) runtime type-checking in pure Python.

Look for the bare necessities, the simple bare necessities. Forget about your worries and your strife. — The Jungle Book.

beartype 1.4k Jan 01, 2023
A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

flake8-bugbear A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycode

Python Code Quality Authority 869 Dec 30, 2022
mypy plugin to type check Kubernetes resources

kubernetes-typed mypy plugin to dynamically define types for Kubernetes objects. Features Type checking for Custom Resources Type checking forkubernet

Artem Yarmoliuk 16 Oct 10, 2022
A Python Parser

parso - A Python Parser Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python

Dave Halter 520 Dec 26, 2022
PEP-484 typing stubs for SQLAlchemy 1.4 and SQLAlchemy 2.0

SQLAlchemy 2 Stubs These are PEP-484 typing stubs for SQLAlchemy 1.4 and 2.0. They are released concurrently along with a Mypy extension which is desi

SQLAlchemy 139 Dec 30, 2022
Tool to check the completeness of MANIFEST.in for Python packages

check-manifest Are you a Python developer? Have you uploaded packages to the Python Package Index? Have you accidentally uploaded broken packages with

Marius Gedminas 270 Dec 26, 2022
Plugin for mypy to support zope.interface

Plugin for mypy to support zope.interface The goal is to be able to make zope interfaces to be treated as types in mypy sense. Usage Install both mypy

Shoobx 36 Oct 29, 2022