hhatto / autopep8

A tool that automatically formats Python code to conform to the PEP 8 style guide.
https://pypi.org/project/autopep8/
MIT License
4.56k stars 290 forks source link

It seems autopep8 isn't ignoring W191 (tab) errors #417

Open caballerofelipe opened 6 years ago

caballerofelipe commented 6 years ago

Hi, I tried using --ignore=W191 but that doesn't seem to do anything... I tried with other codes and the ignore parameter seems to work...

Is this on purpose or is it a bug?

Is there a work around?

––––––– Does the pycodestyle tool behave correctly? yes autopep8 --version autopep8 1.3.5 (pycodestyle: 2.4.0) pycodestyle --version 2.4.0 python --version 3.7.0

sampleCode.py.txt

martemyev commented 6 years ago

Hi, do you have an example that reproduces the unexpected behaviour?

caballerofelipe commented 6 years ago

Sure, here's my initial code:

a=2

def someFn():
    print('hello there')
    print(a==3)

After running ./autopep8 ~/sampleCode.py, I get the following which is what I would expect to get (a=2 changed to a = 2, lines after a = 2, tabs changed for spaces, a==3 changed to a == 3).

a = 2

def someFn():
    print('hello there')
    print(a == 3)

Now, running ./autopep8 --ignore=W191,E225 ~/sampleCode.py, I get the described behavior in the title but the E225 ignoring does work. Also notice that when the output is in the terminal directly (not saving to a file (...> filename.py) I get a white space in the first line, weird, I hadn't noticed this behavior.


a=2

def someFn():
    print('hello there')
    print(a==3)

Just to be sure I did:

$ ./autopep8 --version
autopep8 1.3.5 (pycodestyle: 2.4.0)
martemyev commented 6 years ago

I have older versions: autopep8, pycodestyle 2.3.1, but that's what I have

$ autopep8.py test.py -v
--->  Applying global fix for E265
--->  Applying global fix for W602
--->  3 issue(s) to fix {'E302': set([3]), 'E225': set([1, 5])}
--->  0 issue(s) to fix {}
a = 2

def someFn():
    print('hello there')
    print(a == 3)

Could you check that pycodestyle reports W191 warnings for your example?

caballerofelipe commented 6 years ago

When running your code I get:

$ ./autopep8 ~/sampleCode.py -v
[file:[path]/sampleCode.py]
--->  Applying global fix for E265
--->  3 issue(s) to fix {'E225': {1, 5}, 'E302': {3}}
--->  0 issue(s) to fix {}
a = 2

def someFn():
    print('hello there')
    print(a == 3)

And when running pycodestyle I get:

$ ./pycodestyle ~/sampleCode.py
[path]/sampleCode.py:1:2: E225 missing whitespace around operator
[path]/sampleCode.py:3:1: E302 expected 2 blank lines, found 1
[path]/sampleCode.py:4:1: W191 indentation contains tabs
[path]/sampleCode.py:5:1: W191 indentation contains tabs
[path]/sampleCode.py:5:9: E225 missing whitespace around operator

sampleCode.py.txt

martemyev commented 6 years ago

So, this is what happens:

  1. autopep8 reindents all lines globally https://github.com/hhatto/autopep8/blob/159bb88843e298534e46914da242e680a1c8c47d/autopep8.py#L3322
  2. running pycodestyle after that doesn't reveal any W191 warnings
  3. since autopep8 doesn't know anything about W191, you can't ignore it

One solution is to prevent autopep8 from reindenting all lines globally:

$ autopep8.py test.py --ignore=E101,E111 -v
--->  Applying global fix for E265
--->  Applying global fix for W602
--->  5 issue(s) to fix {'W191': set([4, 5]), 'E302': set([3]), 'E225': set([1, 5])}
--->  2 issue(s) to fix {'W191': set([5, 6])}
a = 2

def someFn():
        print('hello there')
        print(a == 3)

Ideally --ignore=E101 should've been enough, but I think this piece of code is broken: https://github.com/hhatto/autopep8/blob/159bb88843e298534e46914da242e680a1c8c47d/autopep8.py#L3320 therefore you need both -ignore=E101,E111

caballerofelipe commented 6 years ago

Thanks! That works!

How did you come by with E101 and E111? Is it because of previous knowledge or did you see some output from one of the commands?

martemyev commented 6 years ago

Please check the links to the source code from the previous message. It shows that you can avoid running global 'reindent' function (that replaces tabs and fixes indentation globally) only if both E101 and E111 are ignored.

caballerofelipe commented 6 years ago

Ok but I meant without looking at code would I have been able to find a solution? Perhaps at looking at pycodestyle?

martemyev commented 6 years ago

I'm afraid you couldn't avoid looking at the code in this case.