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.2.0.tar.gz (11.0 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.2.0-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flake8_multiline_equals-1.2.0.tar.gz
  • Upload date:
  • Size: 11.0 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.2.0.tar.gz
Algorithm Hash digest
SHA256 ea873e557ce836cab99bfa7db8313d68d3886bf123c30f320a34434fdf1e73f8
MD5 846485be463679bf3e3cd877b1a46dbb
BLAKE2b-256 102c581289180bbff45a3b5dd0cf8505830ade8bec48f5226cf18c213e169b92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for flake8_multiline_equals-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7ad8f12653726701b1874d8906e1b5522d4c448bfda3a6940e4e3c0d3e1aaa9c
MD5 69e34fe7fcc451b91f0505f8fbec3e94
BLAKE2b-256 784300d47cf9e158b1c1f143e9272df91d3aa89143738227d67abfe2ec0bc8cb

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