Internal Docs

Here you can find:

  1. How our development process works

  2. How to contribute to the project

  3. How to write new rules

  4. How our internal API looks like

This information will also be helpful if you would like to create your own flake8 plugin.

How to read this documentation

You will need to start from the glossary where we define the terms for this project.

Then move to the contributing guide where we specify all technical details about our workflow and tools.

Then you will be ready to dive into our “Creating a new rule tutorial”.

And finally you will need to go through the API reference to cover specific technical questions you will encounter.

Philosophy

  1. Done is better than perfect

  2. However, we pursue perfect software

  3. False negatives over false positives

  4. If you cannot sustain your promise - do not promise

  5. Code must be written for people to read, and only incidentally for machines to execute

  6. Value consistency over syntax-ish readability

  7. Consistent code is more readable than inconsistent

  8. Do not force people to choose, they will make mistakes

  9. Made choices must be respected

Overview

This schema should give you a brief overview of what is happening inside our linter. This is a very simplified architecture that will help you to understand how all components are bound together.

        sequenceDiagram
   participant flake8
   participant Checker
   participant Transformation
   participant Visitor
   participant Violation

   flake8->>Checker: flake8 runs our checker alongside with other plugins
   Checker->>Transformation: Checker asks to perform different ast transformations before we actually start doing anything
   Checker->>Visitor: Checker runs all visitors that it is aware of
   Visitor->>Violation: Visitors raise violations when they find bad code
   Violation-->>flake8: Raised violations are shown to user by flake8
    

Architecture overview.

High-level overview of our codebase:

Code organization

We use a layered architecture that follows this contract:

[importlinter]
root_package = wemake_python_styleguide
include_external_packages = True


[importlinter:contract:layers]
name = Layered architecture of our linter
type = layers

containers =
  wemake_python_styleguide

layers =
  checker
  formatter
  transformations
  presets
  visitors
  violations
  logic
  compat
  options
  constants
  types


# TODO: provide independence contract for visitors
[importlinter:contract:violation-independence]
name = Independence contract for violations (all shall be free!)
type = independence

modules =
  wemake_python_styleguide.violations.system
  wemake_python_styleguide.violations.naming
  wemake_python_styleguide.violations.complexity
  wemake_python_styleguide.violations.consistency
  wemake_python_styleguide.violations.best_practices
  wemake_python_styleguide.violations.refactoring
  wemake_python_styleguide.violations.oop


[importlinter:contract:flake8-independence]
name = Independence contract for flake8 API (all shall be free!)
type = independence

modules =
  wemake_python_styleguide.checker
  wemake_python_styleguide.formatter


[importlinter:contract:api-restrictions]
name = Forbids to import anything from dependencies
type = forbidden

source_modules =
  wemake_python_styleguide

forbidden_modules =
  # Std imports we don't like:
  dataclasses

  # Important direct and indirect dependencies:
  flake8

  pygments
  pyflakes
  pycodestyle
  mccabe

ignore_imports =
  # These modules must import from flake8 to provide required API:
  wemake_python_styleguide.checker -> flake8
  wemake_python_styleguide.formatter -> flake8
  wemake_python_styleguide.options.config -> flake8
  # We disallow direct imports of our dependencies from anywhere, except:
  wemake_python_styleguide.formatter -> pygments


[importlinter:contract:subapi-restrictions]
name = Forbids to import anything from our sub-API packages
type = forbidden

source_modules =
  wemake_python_styleguide.visitors
  wemake_python_styleguide.violations
  wemake_python_styleguide.compat
  wemake_python_styleguide.logic

forbidden_modules =
  # Our sub-API parts:
  wemake_python_styleguide.options.config
  wemake_python_styleguide.transformations
  wemake_python_styleguide.presets


[importlinter:contract:tests-restrictions]
name = Explicit import restrictions for tests
type = forbidden

source_modules =
  wemake_python_styleguide

forbidden_modules =
  tests

Contributing

Creating a new rule

This tutorial will guide you through the whole process of creating new rules for this linter.

API Reference

Raw technical information with interface and types declarations, featuring architecture and composition of classes.