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
- Go to Settings → Tools → External Tools
- Add Flake8 with arguments:
--extend-ignore=E251 $FilePath$ - 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:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all checks pass
- 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
Metadata
Release files for flake8-multiline-equals 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flake8_multiline_equals-1.2.0.tar.gz | 11.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flake8_multiline_equals-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.0 kB
Release files / flake8_multiline_equals-1.2.0.tar.gz
| Download URL | flake8_multiline_equals-1.2.0.tar.gz |
|---|---|
| Size | 11.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ea873e557ce836cab99bfa7db8313d68d3886bf123c30f320a34434fdf1e73f8
|
|
BLAKE2b-256 checksum How to use checksums |
102c581289180bbff45a3b5dd0cf8505830ade8bec48f5226cf18c213e169b92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / flake8_multiline_equals-1.2.0-py3-none-any.whl
| Download URL | flake8_multiline_equals-1.2.0-py3-none-any.whl |
|---|---|
| Size | 9.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ad8f12653726701b1874d8906e1b5522d4c448bfda3a6940e4e3c0d3e1aaa9c
|
|
BLAKE2b-256 checksum How to use checksums |
784300d47cf9e158b1c1f143e9272df91d3aa89143738227d67abfe2ec0bc8cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|