132

I know there are tools which validate whether your Python code is compliant with PEP8, for example there is both an online service and a python module.

However, I cannot find a service or module which can convert my Python file to a self-contained, PEP8 valid Python file. Does anyone know if there are any?
I assume it's feasible since PEP8 is all about the appearance of the code, right?

0 _
  • 10,524
  • 11
  • 77
  • 109
Chen Xie
  • 3,849
  • 8
  • 27
  • 46
  • 1
    I don't think there's any tool that converts the code to PEP8 compatible code. PEP8 included variable naming rules as well , so, if such tool exists then it'll rename your variable names as well and you might not be able to understand your own code then. – Ashwini Chaudhary Jan 14 '13 at 23:08
  • 1
    @AshwiniChaudhary That's a good point, it's also worth mentioning that changing variable names may affect others already using your code, as such it's not always a good idea. (autopep8 doesn't do this.) – Andy Hayden Jan 15 '13 at 01:32

6 Answers6

213

You can use autopep8! Whilst you make yourself a cup of coffee this tool happily removes all those pesky PEP8 violations which don't change the meaning of the code.

Install it via pip:

pip install autopep8

Apply this to a specific file:

autopep8 py_file --in-place

or to your project (recursively), the verbose option gives you some feedback of how it's going:

autopep8 project_dir --recursive --in-place --pep8-passes 2000 --verbose

Note: Sometimes the default of 100 passes isn't enough, I set it to 2000 as it's reasonably high and will catch all but the most troublesome files (it stops passing once it finds no resolvable pep8 infractions)...

At this point I suggest retesting and doing a commit!

If you want "full" PEP8 compliance: one tactic I've used is to run autopep8 as above, then run PEP8, which prints the remaining violations (file, line number, and what):

pep8 project_dir --ignore=E501

and manually change these individually (e.g. E712s - comparison with boolean).

Note: autopep8 offers an --aggressive argument (to ruthlessly "fix" these meaning-changing violations), but beware if you do use aggressive you may have to debug... (e.g. in numpy/pandas True == np.bool_(True) but not True is np.bool_(True)!)

You can check how many violations of each type (before and after):

pep8 --quiet --statistics .

Note: I consider E501s (line too long) are a special case as there will probably be a lot of these in your code and sometimes these are not corrected by autopep8.

As an example, I applied this technique to the pandas code base.

Community
  • 1
  • 1
Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
  • @hayden Do you have any comments on how reliable this is, and the ratio of automagic fixes to weird issues it introduces? – Marius Jan 14 '13 at 23:15
  • @Marius I used this on pandas code (which is pretty big) and it didn't show any weird issues, it won't change code which changes the *meaning*, I've updated my answer to mention these. It previously had an issue with Sphinx's hashbang (a bug in PEP8 now fixed). – Andy Hayden Jan 14 '13 at 23:21
  • 2
    Does this enforce Strunk and White within comments? – Eric Nov 04 '16 at 19:32
  • 1
    As of Oct 25, 2017, the `pep8` package mentioned in this answer has been renamed to `pycodestyle`: https://github.com/PyCQA/pycodestyle/releases/tag/1.7.1 – hb20007 May 10 '20 at 12:15
  • Does the max-line-length work for you? For me it does not; e.g.:```autopep8 test.py --in-place --max-line-lengdth=79``` – Siebe Albers Dec 07 '21 at 22:17
43

Unfortunately "pep8 storming" (the entire project) has several negative side-effects:

  • lots of merge-conflicts
  • break git blame
  • make code review difficult

As an alternative (and thanks to @y-p for the idea), I wrote a small package which autopep8s only those lines which you have been working on since the last commit/branch:

Basically leaving the project a little better than you found it:

pip install pep8radius

Suppose you've done your work off of master and are ready to commit:

# be somewhere in your project directory
# see the diff with pep, see the changes you've made since master
pep8radius master --diff
# make those changes
pep8radius master --diff --in-place

Or to clean the new lines you've commited since the last commit:

pep8radius --diff
pep8radius --diff --in-place

# the lines which changed since a specific commit `git diff 98f51f`
pep8radius 98f51f --diff

Basically pep8radius is applying autopep8 to lines in the output of git/hg diff (from the last shared commit).

This script currently works with git and hg, if your using something else and want this to work please post a comment/issue/PR!

Community
  • 1
  • 1
Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
  • 2
    +1 very good initiative ... i am thinking about how to make a Notepad++ plugin for the same purpose ... as that is my favorite editor on Windows – kmonsoor Apr 27 '14 at 13:26
  • 1
    @kmonsoor good idea, i hadn't thought about editor plugins! Let me know on github any way i can help out / make easier to use outside of CLI... I forsee a few (resolvable) issues. – Andy Hayden Apr 27 '14 at 20:04
  • here i found a interesting list of editor plugins https://github.com/jcrocholl/pep8/wiki/RelatedTools , though no luck for Notepad++ ... – kmonsoor Apr 28 '14 at 12:10
  • 1
    i just created a script to bridge between Notepad++ and Autopep8, basing on another plugin "Python Script". However, it works. Plz check here: http://bit.ly/pep8_tonizer – kmonsoor Apr 28 '14 at 15:23
9

@Andy Hayden gave good overview of autopep8. In addition to that there is one more package called pep8ify which also does the same thing.

However both packages can remove only lint errors but they cannot format code.

little = more[3:   5]

Above code remains same after pep8ifying also. But the code doesn't look good yet. You can use formatters like yapf, which will format the code even if the code is PEP8 compliant. Above code will be formatted to

little = more[3:5]

Some times this even destroys Your manual formatting. For example

BAZ = {
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
}

will be converted to

BAZ = {[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]}

But You can tell it to ignore some parts.

BAZ = {
   [1, 2, 3, 4],
   [5, 6, 7, 8],
   [9, 10, 11, 12]
}  # yapf: disable

Taken from my old blog post: Automatically PEP8 & Format Your Python Code!

Chillar Anand
  • 27,936
  • 9
  • 119
  • 136
  • 3
    Is the `little = more[3: 5]` a bug in pep8 (the library)? yapf is definitely the future here, the algorithm behind it (essentially a shortest-path in the graph of all formatting options) is a very elegant solution, and will likely have fewer bugs as well as canonical formatting. – Andy Hayden Sep 29 '15 at 21:59
  • @AndyHayden Looks like it is a missing feature, it doesn't fix E225 – Chillar Anand Sep 30 '15 at 04:30
9

I made wide research about different instruments for python and code style. There are two types of instruments: linters - analyzing your code and give some warnings about bad used code styles and showing advises how to fix it, and code formatters - when you save your file it re-format your document using PEP style.

Because re-formatting must be more accurate - if it reformat something that you don't want it became useless - they cover less part of PEP, linters show much more.

All of them have different permissions for configuring - for example, pylinter configurable in all its rules (you can turn on/off every type of warnings), black unconfigurable at all.

Here are some useful links and tutorials:

Documentation:

Linters (in order of popularity):

Code formatters (in order of popularity):

Mikhail_Sam
  • 10,602
  • 11
  • 66
  • 102
6

If you're using eclipse + PyDev you can simply activate autopep8 from PyDev's settings: Windows -> Preferences -> type 'autopep8' in the search filter.

Check the 'use autopep8.py for code formatting?' -> OK

Now eclipse's CTRL-SHIFT-F code formatting should format your code using autopep8 :)

screen shot

mork
  • 1,747
  • 21
  • 23
3

There are many.

IDEs usually have some formatting capability built in. IntelliJ Idea / PyCharm does, same goes for the Python plugin for Eclipse, and so on.

There are formatters/linters that can target multiple languages. https://coala.io is a good example of those.

Then there are the single purpose tools, of which many are mentioned in other answers.

One specific method of automatic reformatting is to parse the file into AST tree (without dropping comments) and then dump it back to text (meaning nothing of the original formatting is preserved). Example of that would be https://github.com/python/black.

user7610
  • 25,267
  • 15
  • 124
  • 150