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.1.0.tar.gz (10.6 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.1.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flake8_multiline_equals-1.1.0.tar.gz
  • Upload date:
  • Size: 10.6 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.1.0.tar.gz
Algorithm Hash digest
SHA256 4d38682f6053fe17e9daf573d81becd3a15514ab7a584290cd5dadc6b2fd566f
MD5 0ca79686a1c809d270879b3d8237d7d7
BLAKE2b-256 3e256cfe0ecd7f2e0a73450a9ce683688ebf916ebd34f6a3f9fe72cdb788070f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for flake8_multiline_equals-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 714dca3e8eecc93ce0ff8105aa268d110a12590a7164d34578c934f5448c490f
MD5 4695477020f2ecf00341d845b492885f
BLAKE2b-256 b6676eab7278b7e94a9261901142f313eac7b0b7a4c1b80fb016e9bdbf89f943

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