Skip to main content

Highly opinionated: Spaces around `=` in multiline function calls

Project description

flake8-multilne-equals

A Flake8 plugin that enforces consistent spacing around = in function call keyword arguments, with different rules for single-line vs. multiline calls.

Installation

pip install flake8-multilne-equals

Motivation

This plugin improves code readability in multiline function calls by:

  • Visual consistency: Spaces around = in multiline calls make keyword arguments easier to scan
  • Better diffs: One argument per line produces cleaner git diffs when arguments change
  • PEP 8 compliance: Maintains standard Python style (no spaces around =) for single-line calls

This style deliberately contradicts PEP 8's E251 rule for multiline calls, trading strict adherence for improved readability in long function signatures.

Rules

MNA001: Missing spaces around = in multiline function call

Bad:

result = foo(
    a=1,
    b=2,
)

Good:

result = foo(
    a = 1,
    b = 2,
)

MNA002: Unexpected spaces around = in single-line function call

This rule replaces E251 for single-line calls.

Bad:

result = foo(a = 1, b = 2)

Good:

result = foo(a=1, b=2)

MNA003: Multiple arguments on same line in multiline function call

Bad - Multiple keyword arguments:

result = foo(
    a = 1, b = 2,
    c = 3,
)

Bad - Keyword mixed with positional:

result = foo(
    1, 2, a = 3,
    b = 4,
)

Good:

result = foo(
    a = 1,
    b = 2,
    c = 3,
)

Configuration

Since this plugin contradicts PEP 8's E251, you need to configure Flake8 to ignore E251 and enable MNA checks.

Option 1: Command line

flake8 --extend-ignore=E251 your_file.py

Option 2: Configuration file

Create or edit .flake8 in your project root:

[flake8]
extend-ignore = E251
extend-select = MNA

Or in setup.cfg:

[flake8]
extend-ignore = E251
extend-select = MNA

Or in tox.ini:

[flake8]
extend-ignore = E251
extend-select = MNA

Option 3: pyproject.toml (requires flake8 >= 5.0)

[tool.flake8]
extend-ignore = ["E251"]
extend-select = ["MNA"]

Examples

Correct usage

# Single-line calls: no spaces around =
result1 = foo(a=1, b=2)
obj = MyClass(x=10, y=20, z=30)

# Multiline calls: spaces around =, one argument per line
result2 = foo(
    a = 1,
    b = 2,
    c = 3,
)

result3 = MyClass(
    x = 10,
    y = 20,
    z = 30,
)

# Positional args separate from keyword args
result4 = foo(
    1,
    2,
    a = 3,
    b = 4,
)

Common violations

# MNA002: Spaces in single-line call
result = foo(a = 1, b = 2)

# MNA001: No spaces in multiline call
result = foo(
    a=1,
    b=2,
)

# MNA003: Multiple keywords on same line
result = foo(a = 1, b = 2,
             c = 3)

# MNA003: Keyword mixed with positional on same line
result = foo(1, 2, a = 3,
             b = 4)

Editor Integration

VS Code

Install the Python extension and configure Flake8 in your settings.json:

{
    "python.linting.flake8Enabled": true,
    "python.linting.flake8Args": ["--extend-ignore=E251"]
}

PyCharm

  1. Go to Settings → Tools → External Tools
  2. Add Flake8 with arguments: --extend-ignore=E251 $FilePath$
  3. Or configure in Settings → Editor → Inspections → Python → Flake8

Vim/Neovim

With ALE:

let g:ale_python_flake8_options = '--extend-ignore=E251'

Emacs

With Flycheck:

(setq flycheck-flake8rc ".flake8")

Then use a .flake8 config file.

Pre-commit Hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/PyCQA/flake8
    rev: 6.1.0
    hooks:
      - id: flake8
        args: ['--extend-ignore=E251']
        additional_dependencies: ['/path/to/flake8-multiline-equals']

Development

Running tests

Create test files in test/ directory and run:

flake8 --extend-ignore=E251 [FILES]

Limitations

  • The plugin only checks keyword arguments, not positional arguments
  • Nested function calls are handled correctly, but deeply nested calls with complex line spans may have edge cases
  • Multiline keyword argument values (e.g., lambda expressions, list comprehensions) only track the = line, not the full value span

FAQ

Q: Why deviate from PEP 8?

A: While PEP 8 (E251) prohibits spaces around = in keyword arguments, this plugin prioritizes readability for multiline calls. The spaces create visual separation that makes complex function signatures easier to read and modify.

Q: Can I use this with other formatters like Black?

A: Black does not add spaces around = in keyword arguments, so it conflicts with this plugin's MNA001 rule. You would need to manually format multiline calls or configure Black to skip those sections.

Q: What if I only want to enforce the "one argument per line" rule (MNA003)?

A: You can selectively ignore rules in your Flake8 config:

[flake8]
extend-ignore = E251, MNA001, MNA002
extend-select = MNA

Q: Does this work with Python 2?

A: No, this plugin requires Python 3.9+ for type hints and AST features.

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all checks pass
  5. Submit a pull request

Changelog

1.0.0 (2024-12-13)

  • Initial release
  • MNA001: Enforce spaces around = in multiline calls
  • MNA002: Prohibit spaces around = in single-line calls
  • MNA003: One argument per line in multiline calls

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_multiline_equals-1.0.1.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flake8_multiline_equals-1.0.1-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file flake8_multiline_equals-1.0.1.tar.gz.

File metadata

  • Download URL: flake8_multiline_equals-1.0.1.tar.gz
  • Upload date:
  • Size: 10.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for flake8_multiline_equals-1.0.1.tar.gz
Algorithm Hash digest
SHA256 dd1d4079e7756323d9e2be46ae843aa1302d47f89ee1914f73edd1cf02bb066a
MD5 259285f21154ad99b664866cd2ff5cc5
BLAKE2b-256 a3e75f208626cb422033e24970a0da385b86eb479b960662b66885977d2f58f4

See more details on using hashes here.

File details

Details for the file flake8_multiline_equals-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for flake8_multiline_equals-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ae7e8d99d76728bd1609804724da2495374b2da5f5760fb0b156c458873a85c4
MD5 953cd4ecce42335f46eb6f5c2c6f742c
BLAKE2b-256 edde8ba39a81abcdf6a2680dd6b62dc464fa32ee101f00bdafc98bf4ff741876

See more details on using hashes here.

Supported by

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