Code Monkey home page Code Monkey logo

autopep8's Introduction

autopep8

PyPI Version

Build status

Code Coverage

autopep8 automatically formats Python code to conform to the PEP 8 style guide. It uses the pycodestyle utility to determine what parts of the code needs to be formatted. autopep8 is capable of fixing most of the formatting issues that can be reported by pycodestyle.

Installation

From pip:

$ pip install --upgrade autopep8

Consider using the --user option.

Requirements

autopep8 requires pycodestyle.

Usage

To modify a file in place (with aggressive level 2):

$ autopep8 --in-place --aggressive --aggressive <filename>

Before running autopep8.

import math, sys;

def example1():
    ####This is a long comment. This should be wrapped to fit within 72 characters.
    some_tuple=(   1,2, 3,'a'  );
    some_variable={'long':'Long code lines should be wrapped within 79 characters.',
    'other':[math.pi, 100,200,300,9876543210,'This is a long string that goes on'],
    'more':{'inner':'This whole logical line should be wrapped.',some_tuple:[1,
    20,300,40000,500000000,60000000000000000]}}
    return (some_tuple, some_variable)
def example2(): return {'has_key() is deprecated':True}.has_key({'f':2}.has_key(''));
class Example3(   object ):
    def __init__    ( self, bar ):
     #Comments should have a space after the hash.
     if bar : bar+=1;  bar=bar* bar   ; return bar
     else:
                    some_string = """
                   Indentation in multiline strings should not be touched.
Only actual code should be reindented.
"""
                    return (sys.path, some_string)

After running autopep8.

import math
import sys


def example1():
    # This is a long comment. This should be wrapped to fit within 72
    # characters.
    some_tuple = (1, 2, 3, 'a')
    some_variable = {
        'long': 'Long code lines should be wrapped within 79 characters.',
        'other': [
            math.pi,
            100,
            200,
            300,
            9876543210,
            'This is a long string that goes on'],
        'more': {
            'inner': 'This whole logical line should be wrapped.',
            some_tuple: [
                1,
                20,
                300,
                40000,
                500000000,
                60000000000000000]}}
    return (some_tuple, some_variable)


def example2(): return ('' in {'f': 2}) in {'has_key() is deprecated': True}


class Example3(object):
    def __init__(self, bar):
        # Comments should have a space after the hash.
        if bar:
            bar += 1
            bar = bar * bar
            return bar
        else:
            some_string = """
                   Indentation in multiline strings should not be touched.
Only actual code should be reindented.
"""
            return (sys.path, some_string)

Options:

usage: autopep8 [-h] [--version] [-v] [-d] [-i] [--global-config filename]
                [--ignore-local-config] [-r] [-j n] [-p n] [-a]
                [--experimental] [--exclude globs] [--list-fixes]
                [--ignore errors] [--select errors] [--max-line-length n]
                [--line-range line line] [--hang-closing] [--exit-code]
                [files [files ...]]

Automatically formats Python code to conform to the PEP 8 style guide.

positional arguments:
  files                 files to format or '-' for standard in

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -v, --verbose         print verbose messages; multiple -v result in more
                        verbose messages
  -d, --diff            print the diff for the fixed source
  -i, --in-place        make changes to files in place
  --global-config filename
                        path to a global pep8 config file; if this file does
                        not exist then this is ignored (default:
                        ~/.config/pep8)
  --ignore-local-config
                        don't look for and apply local config files; if not
                        passed, defaults are updated with any config files in
                        the project's root directory
  -r, --recursive       run recursively over directories; must be used with
                        --in-place or --diff
  -j n, --jobs n        number of parallel jobs; match CPU count if value is
                        less than 1
  -p n, --pep8-passes n
                        maximum number of additional pep8 passes (default:
                        infinite)
  -a, --aggressive      enable non-whitespace changes; multiple -a result in
                        more aggressive changes
  --experimental        enable experimental fixes
  --exclude globs       exclude file/directory names that match these comma-
                        separated globs
  --list-fixes          list codes for fixes; used by --ignore and --select
  --ignore errors       do not fix these errors/warnings (default:
                        E226,E24,W50,W690)
  --select errors       fix only these errors/warnings (e.g. E4,W)
  --max-line-length n   set maximum allowed line length (default: 79)
  --line-range line line, --range line line
                        only fix errors found within this inclusive range of
                        line numbers (e.g. 1 99); line numbers are indexed at
                        1
  --hang-closing        hang-closing option passed to pycodestyle
  --exit-code           change to behavior of exit code. default behavior of
                        return value, 0 is no differences, 1 is error exit.
                        return 2 when add this option. 2 is exists
                        differences.

Features

autopep8 fixes the following issues reported by pycodestyle:

E101 - Reindent all lines.
E11  - Fix indentation.
E121 - Fix indentation to be a multiple of four.
E122 - Add absent indentation for hanging indentation.
E123 - Align closing bracket to match opening bracket.
E124 - Align closing bracket to match visual indentation.
E125 - Indent to distinguish line from next logical line.
E126 - Fix over-indented hanging indentation.
E127 - Fix visual indentation.
E128 - Fix visual indentation.
E129 - Fix visual indentation.
E131 - Fix hanging indent for unaligned continuation line.
E133 - Fix missing indentation for closing bracket.
E20  - Remove extraneous whitespace.
E211 - Remove extraneous whitespace.
E22  - Fix extraneous whitespace around keywords.
E224 - Remove extraneous whitespace around operator.
E225 - Fix missing whitespace around operator.
E226 - Fix missing whitespace around arithmetic operator.
E227 - Fix missing whitespace around bitwise/shift operator.
E228 - Fix missing whitespace around modulo operator.
E231 - Add missing whitespace.
E241 - Fix extraneous whitespace around keywords.
E242 - Remove extraneous whitespace around operator.
E251 - Remove whitespace around parameter '=' sign.
E252 - Missing whitespace around parameter equals.
E26  - Fix spacing after comment hash for inline comments.
E265 - Fix spacing after comment hash for block comments.
E266 - Fix too many leading '#' for block comments.
E27  - Fix extraneous whitespace around keywords.
E301 - Add missing blank line.
E302 - Add missing 2 blank lines.
E303 - Remove extra blank lines.
E304 - Remove blank line following function decorator.
E305 - Expected 2 blank lines after end of function or class.
E306 - Expected 1 blank line before a nested definition.
E401 - Put imports on separate lines.
E402 - Fix module level import not at top of file
E501 - Try to make lines fit within --max-line-length characters.
E502 - Remove extraneous escape of newline.
E701 - Put colon-separated compound statement on separate lines.
E70  - Put semicolon-separated compound statement on separate lines.
E711 - Fix comparison with None.
E712 - Fix comparison with boolean.
E713 - Use 'not in' for test for membership.
E714 - Use 'is not' test for object identity.
E721 - Use "isinstance()" instead of comparing types directly.
E722 - Fix bare except.
E731 - Use a def when use do not assign a lambda expression.
W291 - Remove trailing whitespace.
W292 - Add a single newline at the end of the file.
W293 - Remove trailing whitespace on blank line.
W391 - Remove trailing blank lines.
W503 - Fix line break before binary operator.
W504 - Fix line break after binary operator.
W605 - Fix invalid escape sequence 'x'.

autopep8 also fixes some issues not found by pycodestyle.

  • Normalize files with mixed line endings.
  • Put a blank line between a class docstring and its first method declaration. (Enabled with E301.)
  • Remove blank lines between a function declaration and its docstring. (Enabled with E303.)

autopep8 avoids fixing some issues found by pycodestyle.

  • E112/E113 for non comments are reports of bad indentation that break syntax rules. These should not be modified at all.
  • E265, which refers to spacing after comment hash, is ignored if the comment looks like code. autopep8 avoids modifying these since they are not real comments. If you really want to get rid of the pycodestyle warning, consider just removing the commented-out code. (This can be automated via eradicate.)

More advanced usage

By default autopep8 only makes whitespace changes. Thus, by default, it does not fix E711 and E712. (Changing x == None to x is None may change the meaning of the program if x has its __eq__ method overridden.) Nor does it correct deprecated code W6. To enable these more aggressive fixes, use the --aggressive option:

$ autopep8 --aggressive <filename>

Use multiple --aggressive to increase the aggressiveness level. For example, E712 requires aggressiveness level 2 (since x == True could be changed to either x or x is True, but autopep8 chooses the former).

--aggressive will also shorten lines more aggressively. It will also remove trailing whitespace more aggressively. (Usually, we don't touch trailing whitespace in docstrings and other multiline strings. And to do even more aggressive changes to docstrings, use docformatter.)

To enable only a subset of the fixes, use the --select option. For example, to fix various types of indentation issues:

$ autopep8 --select=E1,W1 <filename>

If the file being fixed is large, you may want to enable verbose progress messages:

$ autopep8 -v <filename>

Passing in --experimental enables the following functionality:

  • Shortens code lines by taking its length into account
$ autopep8 --experimental <filename>

Disabling line-by-line

It is possible to disable autopep8 untill it it turned back on again in the file, using autopep8: off and then renabling autopep8: on.

# autopep8: off
    [
        [23, 23, 13, 43],
        [32, 34, 34, 34],
        [56, 34, 34, 11],
        [10, 10, 10, 10],
    ]
# autopep8: on

fmt: off and fmt: on are also valid.

Use as a module

The simplest way of using autopep8 as a module is via the fix_code() function:

>>> import autopep8 >>> autopep8.fix_code('x= 123n') 'x = 123n'

Or with options:

>>> import autopep8 >>> autopep8.fix_code('print( 123 )n', ... options={'ignore': ['E']}) 'print( 123 )n'

Configuration

By default, if $HOME/.config/pycodestyle (~\.pycodestyle in Windows environment) exists, it will be used as global configuration file. Alternatively, you can specify the global configuration file with the --global-config option.

Also, if setup.cfg, tox.ini, .pep8 and .flake8 files exist in the directory where the target file exists, it will be used as the configuration file.

pep8, pycodestyle, and flake8 can be used as a section.

configuration file example:

[pycodestyle]
max_line_length = 120
ignore = E501

pyproject.toml

autopep8 can also use pyproject.toml. The section must be [tool.autopep8], and pyproject.toml takes precedence over any other configuration files.

configuration file example:

[tool.autopep8]
max_line_length = 120
ignore = "E501,W6"  # or ["E501", "W6"]
in-place = true
recursive = true
aggressive = 3

Usage with pre-commit

autopep8 can be used as a hook for pre-commit.

To add autopep8 as a plugin, add this repo definition to your configuration:

repos:
-   repo: https://github.com/hhatto/autopep8
    rev: ...  # select the tag or revision you want, or run `pre-commit autoupdate`
    hooks:
    -   id: autopep8

Testing

Test cases are in test/test_autopep8.py. They can be run directly via python test/test_autopep8.py or via tox. The latter is useful for testing against multiple Python interpreters. (We currently test against CPython versions 3.8, 3.9, 3.10, 3.11 and 3.12. We also test against PyPy.)

Broad spectrum testing is available via test/acid.py. This script runs autopep8 against Python code and checks for correctness and completeness of the code fixes. It can check that the bytecode remains identical. test/acid_pypi.py makes use of acid.py to test against the latest released packages on PyPI.

Troubleshooting

pkg_resources.DistributionNotFound

If you are using an ancient version of setuptools, you might encounter pkg_resources.DistributionNotFound when trying to run autopep8. Try upgrading setuptools to workaround this setuptools problem:

$ pip install --upgrade setuptools

Use sudo if you are installing to the system.

autopep8's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

autopep8's Issues

pep8 error E501 is ignored completely

steps to reproduce :

  1. [xxxxx@localhost guest]# cat testpyt.py

    ! /usr/bin/env python

    k = "this is a super long sentence to test the character limit of defining a variable that exceeds atleast 80 characters and see if this is taken care of autopep8 and what changes it does"
    print k

  2. [xxxxx@localhost guest]# pep8 testpyt.py
    testpyt.py:2:80: E501 line too long (188 > 79 characters)

  3. [xxxxx@localhost guest]# autopep8 testpyt.py > testpyt2.py

  4. [root@localhost guest]# pep8 testpyt2.py
    testpyt2.py:2:80: E501 line too long (188 > 79 characters)

version information :

[root@localhost guest]# pep8 --version
1.3.3

[root@localhost guest]# autopep8 --version
autopep8: 0.8

Cannot correct indentation of this function

Try autopep8 on this function:

def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

and it suggests:

def long_function_name(
    var_one, var_two, var_three,
        var_four):
    print(var_one)

autopep8.fix_string() doesn't work in fallback mode

I was attempting to use autopep8.fix_string() to format a string and my system pep8 version is < 1.3a2. The fallback/compatibility mode attempts to open filename("") to determine encoding (line 230) which causes an exception. I worked around it by using a newer version of pep8, but thought I'd open an issue if you wanted to handle the failure more gracefully or make note of this limitation somewhere.

French character é failed to parse file

I launch autopep8 on a file which containt é in a comment i have this traceback (my file starts with # -- coding: utf-8 --)

/Envs/anpv/lib/python2.6/site-packages/autopep8.py:1488: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
if fixed_source == tmp_source:
'ascii' codec can't decode byte 0xc3 in position 240: ordinal not in range(128)

Regards,

Acid tests should check bytecode too

The tests should verify that the pep8ized file generates the same bytecode as the original file.

There should be some sort of smart comparison because line numbers should not be compared.

I think is very important to verify that this tool doesn't actually change the code.

"Correct some non-idiomatic Python code." is mentioned in the readme but no details on what corrections are made ? This should be disabled for the bytecode match tests if it does code reductions or optimizations.

Incorrect indentation from E12 fixer

See test_e12_large() intest_autopep8.py. Also,

MACS-1.4.2/lib/PeakDetect.py
cement-1.9.10/tests/core/controller_tests.py

I wonder if we should do a syntax check in the E12 fixer and not commit the change if the indentation is wrong.

Ability to not fix block comments

Is there a possibility that autopep8 does not fix block comments (i.e. replaces #Comment with # Comment)? I have a couple of files that I want to convert to pep8 issue by issue but it seems that no matter which issue I select via --select the comments are always fixed.

autopep8 0.6.3 does not support pep8 1.3

pep8 1.3 was released yesterday. Their change log say that the internal API of pep8 1.3 is not backwards compatible to earlier releases. What I experience at runtime seems to confirm that statement:

# autopep8 --ignore=E303,W191,E501,E101 -i foo.py
:44:80: E501 line too long (109 characters)
:44:1: W191 indentation contains tabs
[..]

As you can see W191 is reported despite my request to ignore it. Did not happen with pep8 <=1.2.

Line endings do not match if CRLF are in file rather than LF

Perhaps this is not behavior that is wanted, but I do a lot of my editing on a Windows system via SSH to a Linux box. My editor warns of mixed line endings after autopep8 parses E501 errors.

If this is a fix that you want, I will work on it, since I'd like to contribute. I find this project very useful.

autopep8 fail to fix W601 (...) if code contains non-ascii chars

run autopep8 on this file (test.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Stéphane contains non-ascii char
correct = dict().has_key('good syntax ?')
$ python autopep8.py --verbose --diff /tmp/test.py
[file:/tmp/test.py]
1 issues to fix
'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)

If we replaces 'é' by 'e' then:

$ python autopep8.py --verbose --diff /tmp/test.py
[file:/tmp/test.py]
1 issues to fix
0 issues to fix
--- original//tmp/test.py
+++ fixed//tmp/test.py
@@ -1,4 +1,4 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 # Stephane contains non-ascii char
-correct = dict().has_key('good syntax ?')
+correct = 'good syntax ?' in dict()

autopep8 0.6.4: test/bad_encoding.py and test/bad_encoding2.py missing in PyPI tarball

test/bad_encoding.py and test/bad_encoding2.py are missing in PyPI tarball, which results in errors in test_read_from_filename_with_bad_encoding() and test_read_from_filename_with_bad_encoding2().

$ PYTHONPATH="." python2.7 test/test_autopep8.py
.................................................................................................................................EE.
======================================================================
ERROR: test_read_from_filename_with_bad_encoding (__main__.TestUtils)
Bad encoding should not cause an exception.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/test_autopep8.py", line 79, in test_read_from_filename_with_bad_encoding
    os.path.join(ROOT_DIR, 'test', 'bad_encoding.py')))
  File "/tmp/autopep8-0.6.4/autopep8.py", line 81, in read_from_filename
    encoding=detect_encoding(filename)) as input_file:
  File "/tmp/autopep8-0.6.4/autopep8.py", line 59, in detect_encoding
    with open(filename, 'rb') as input_file:
IOError: [Errno 2] No such file or directory: '/tmp/autopep8-0.6.4/test/bad_encoding.py'

======================================================================
ERROR: test_read_from_filename_with_bad_encoding2 (__main__.TestUtils)
Bad encoding should not cause an exception.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/test_autopep8.py", line 84, in test_read_from_filename_with_bad_encoding2
    os.path.join(ROOT_DIR, 'test', 'bad_encoding2.py')))
  File "/tmp/autopep8-0.6.4/autopep8.py", line 81, in read_from_filename
    encoding=detect_encoding(filename)) as input_file:
  File "/tmp/autopep8-0.6.4/autopep8.py", line 59, in detect_encoding
    with open(filename, 'rb') as input_file:
IOError: [Errno 2] No such file or directory: '/tmp/autopep8-0.6.4/test/bad_encoding2.py'

----------------------------------------------------------------------
Ran 132 tests in 3.852s

FAILED (errors=2)

`spam == None` check gives an error

Test file:

test.py

if spam == None:
    pass
autopep8 -vi test.py
[file:test.py]
'fix_e711' is not defined.
test.py:2:9:E711 comparison to None should be 'if cond is None:'
'fix_e711' is not defined.
test.py:2:9:E711 comparison to None should be 'if cond is None:'

Is the fix_e711 missing purposely? If so, should I write a patch to add it?

E71 is not corrected for True and False

[]$ ../autopep8/autopep8.py --diff --select=E71 jnk.txt
--- original/jnk.txt
+++ fixed/jnk.txt
@@ -1,4 +1,4 @@
-if x==None:
+if x is None:
     pass
 if x==True:
     pass
[]$ cat jnk.txtif x==None:
    pass
if x==True:
    pass
if x == True:
    pass
if x == False and 1:
    pass

[]$ pep8 --version
1.3.3
[]$ ../autopep8/autopep8.py --version
autopep8: 0.8.1
[]$ python --version
Python 2.7.3

Find a way to integrate autopep8 into `setup.py test`

It would be great to run autopep8 from setup test.

So far I was able to add autopep8 by addng this to setup.py:
tests_require=['autopep8'],

Currently running it will download autopep8 egg locally but I don't know how to make it run by default.

trailing space is left after splitting semicolon line


autopep8{* e702}]$ git diff master
diff --git a/autopep8.py b/autopep8.py
index 9294ecd..d528fda 100755
--- a/autopep8.py
+++ b/autopep8.py
@@ -710,7 +710,7 @@ class FixPEP8(object):
             return

         offset = result['column'] - 1
-        first = target[:offset].rstrip(';')
+        first = target[:offset].rstrip(';').rstrip()
         second = (_get_indentation(logical_lines[0]) +
                   target[offset:].lstrip(';').lstrip())

diff --git a/test/test_autopep8.py b/test/test_autopep8.py
index aa80e91..7138e14 100644
--- a/test/test_autopep8.py
+++ b/test/test_autopep8.py
@@ -1344,7 +1344,7 @@ if True:
         self.assertEqual(self.result, fixed)

     def test_e702(self):
-        line = "print 1; print 2\n"
+        line = "print 1 ; print 2\n"
         fixed = "print 1\nprint 2\n"
         self._inner_setup(line)
         self.assertEqual(self.result, fixed)

"Spawning" is broken in Python 2.6

In Python 2.6, the source code that gets written to the temporary file is corrupted. This is possibly due to some unicode issue. The current workaround is to install a recent version of pep8 to avoid spawning pep8 as a subprocess.

Note that this works fine in Python 2.7 and above.

Idea: pretty long lambdas

Suppose I have some function call that takes a lambda (or an expression with a lambda that can be spread on multiple lines):

some_func(stuff=lambda some, more, *arguments, **keywords: some_expressions and some_other_way_longer_expression) 

don't fit under 80 columns.

How about if autopep8 would format it like:

some_func(
    stuff=lambda some, more, *arguments, **keywords: 
        some_expressions and some_other_way_longer_expression
)

Currently it puts all the lambda on a single line.

autopep8 does not modify any files even if it finds things to fix

I don't know what causes autopep8 to not fix the files, as I am also using it in another project without any problems,

Here how I call it:

autopep8 --ignore=E501 -i .py scripts/.py scripts//.py scripts/contrib/jira/jira.py
autopep8: 0.8.2
pep8: 1.3.3

pep8 reports tons of things to fix, including mixed tab/spaces issue which were solved by autopep8 without any problems.

Running it with "-v" displays few things to fix, but not as many as expected, still it does not fix them.
---> 30 issue(s) to fix {'W191': set([8, 10]), 'E101': set([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43])}

here is the setup of pep8 (.pep8 file):

[pep8]
exclude=.svn,CVS,.bzr,.hg,.git,lib,.tox,third,*.egg,temp,plugins,textile.py,old,SOAPpy,fpconst,sqlalchemy,tendo,unittest2,wstools,requests_oauth
ignore=E501 scripts
max-line-length=1024
count=1
statistics=1

pep8 reports ~1500 things to fix.

japanese/unicode sphinx file breaks test after autopep8

I downloaded sphinx: https://bitbucket.org/birkenfeld/sphinx in order to run autopep8 on it.

  • before I begin nosetests has 11 skips but no failures.
  • autopep8 sphinx -r -v -i (still no failures in nosetests), but one file (sphinx/sphinx/search/ja.py) starts with something ridiculous like 2642 E231 missing whitespace after ':' issues.
  • blindly autopep8 this file repeatedly so all but E501s are fixed.
  • nosetest has 11 skips but 1 failure...
FAIL: test_autodoc.test_generate
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/andy/sphinx/tests/test_autodoc.py", line 447, in test_generate
    assert_processes(should, 'class', 'Class')
  File "/home/andy/sphinx/tests/test_autodoc.py", line 367, in assert_processes
    set(items)
AssertionError

I'm afraid I don't know how to give a better test case at the moment, perhaps it is something to do with the Japanese characters... It seems to be reproducible with this file... obviously looking at this file PEP8 compliance is not so important since are not important, but nevertheless autopep8 shouldn't change the meaning of the code?

p.s. Thanks for the great tool, it usually works great!

fix_e711 will broken SQLAlchemy's query

Here is SQLAlchemy query snippet.

filter(User.name != None)

after autopep8, this code will like this

filter(User.name is not None)

and this query cannot works.

autopep8 cannot fix lines that are too long

is this because there is no way to know where to split this? or you cant do it without modifying the meaning of the code?

i'm not sure if there is a way to add line continuation characters or to break up chained functions, but this is another issue i saw

--ignore not working properly

The "ignore" function of autopep8 seems to be spotty for me. Sometimes it will ignore many instances of an error, even if I don't pass any arguments to the "ignore" parameter. Sometimes it will simply not ignore the arguments I pass at all. Below is a simple example:

mydict = {
    'longkey': {
        'key2': {
            'longkey3': 1,
        }
    }
}
mydict['longkey']['key2']['longkey3'] = 'my long string goes here that goes well past line 80'

Calling pep8 on the file returns the following error:

over_80_char.py:9:80: E501 line too long (94 characters)

Running autopep8 with the following command:

autopep8 over_80_char.py --ignore=E501

Gives the following updated output:

mydict = {
    'longkey': {
        'key2': {
            'longkey3': 1,
        }
    }
}

mydict['longkey']['key2']['longkey3']
    = 'my long string goes here that goes well past line 80'

Note that it still attempted to compensate for E501 despite my ignore message. It also gives an invalid syntax for the updated line code, but that is another issue that I will submit separately.

E72

I want to fix E72 via lib2to3's "idioms" fixer. When I run it on the command line, it works.

$ 2to3 -f idioms blah.py
type('') == type('')

becomes

isinstance('', type(''))

But I haven't yet been able to get it to work via lib2to3 yet. It doesn't raise any error. It just doesn't fix it.

misindented parameter list is corrected to be too long

$ python --version
Python 2.7.3
$ pep8 --version
1.3.3
$ ../autopep8/autopep8.py --version
autopep8: 0.8.1

Notice that the offered corrections are too long, extending to 89 chars.

$ ../autopep8/autopep8.py -r --select=E128,E501 --diff sympy/solvers/ode.py
    @@ -3081,5 +3105,5 @@
         C1 = Symbol('C1')
         r = match # {'m1':m1, 'm2':m2, 'y':y}
         return Eq(C.Integral(r['m2']['coeff']*r['m2'][r['y']]/r['m1'][r['y']],
    -        (r['y'], None, f(x))), C.Integral(-r['m1']['coeff']*r['m1'][x]/
    -        r['m2'][x], x)+C1)
    +                         (r['y'], None, f(x))), C.Integral(-r['m1']['coeff']*r['m1'][x]/
    +                                                           r['m2'][x], x)+C1)

upcoming pep8.py will break compatibility

Hello,

I'm the current maintainer of pep8.py.
In order to make the library more flexible, I removed the global configuration.
Unfortunately, I cannot easily preserve the compatibility with previous version.

You can checkout the current 1.3 alpha1 and have a look.
I plan to release 1.3 later this week, or next week.

Florent

TypeError: must be unicode, not str

Commit ca66005 introduces a bug:

$ autopep8 -i *.py
Traceback (most recent call last):
  File "/Volumes/Raptor/Library/Python/2.7/bin/autopep8", line 8, in <module>
    load_entry_point('autopep8==0.8.4', 'console_scripts', 'autopep8')()
  File "/Volumes/Raptor/Library/Python/2.7/lib/python/site-packages/autopep8-0.8.4-py2.7.egg/autopep8.py", line 1906, in main
    fix_file(name, opts, output)
  File "/Volumes/Raptor/Library/Python/2.7/lib/python/site-packages/autopep8-0.8.4-py2.7.egg/autopep8.py", line 1767, in fix_file
    fp.write(fixed_source)
TypeError: must be unicode, not str

Reverting to the previous commit (c16da22) fixes this.

"x=<space><tab>3" makes recent autopep8 crash

The following Python input makes autopep8 0.5.2/HEAD crash.

class Foo():
    def __init__(self):
        x=  3 # i.e. "x=<space><tab>3"

The important (and hard to see) part is the space followed by a tab. If I remove that tab the crash goes away.

The traceback is:

Traceback (most recent call last):
  File "/usr/bin/autopep8-2.6", line 9, in <module>
    load_entry_point('autopep8==0.5.2', 'console_scripts', 'autopep8')()
  File "/usr/lib64/python2.6/site-packages/autopep8.py", line 686, in main
    fix_file(args[0], opts)
  File "/usr/lib64/python2.6/site-packages/autopep8.py", line 644, in fix_file
    fixed_source = fix.fix()
  File "/usr/lib64/python2.6/site-packages/autopep8.py", line 161, in fix
    pep8result = self._execute_pep8(self.filename)
  File "/usr/lib64/python2.6/site-packages/autopep8.py", line 121, in _execute_pep8
    tmp_checker.check_all()
  File "/usr/lib64/python2.6/site-packages/pep8.py", line 949, in check_all
    for token in tokenize.generate_tokens(self.readline_check_physical):
  File "/usr/lib64/python2.6/tokenize.py", line 346, in generate_tokens
    ("<tokenize>", lnum, pos, line))
  File "<tokenize>", line 3
    x =     3
    ^
IndentationError: unindent does not match any outer indentation level

raise UnicodeWarning error when containing CJK characters

Consider a simple .py file that just has one line of code like this:

print '**'

run autopep8 with it, the following messages will prompt:

/home/.../autopep8.py:1488: UnicodeWarning:
Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if fixed_source == tmp_source:
'ascii' codec can't decode byte 0xe4 in position 55: ordinal not in range(128)

Seems a unicode problem, then I tried:

print u'**'

but it keeps showing the same error:

/home/.../autopep8.py:1488: UnicodeWarning:
Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if fixed_source == tmp_source:
'ascii' codec can't decode byte 0xe4 in position 56: ordinal not in range(128)

This may be a serious problem since it occurs on any CJK characters (Japanese:ジャパン, Korean:한국). I didn't work out the reason, please fix it :)

autopep8 0.6.3 takes >40x the time 0.6.2 did (at 100% CPU)

From 0.6.2 to 0.6.3 the time for a file with 577 lines and 29K size has gone from 1 second to 51 seconds (with 100% CPU usage all the way).

# time autopep8 --ignore=E303,W191,E501,E101 -i foo.py  # with 0.6.2
real  0m1.186s
user  0m1.138s
sys   0m0.037s

... restoring original state of foo.py here ...

# time autopep8 --ignore=E303,W191,E501,E101 -i foo.py  # with 0.6.3
real  0m51.472s
user  0m51.033s
sys   0m0.063s

Both of these were using pep8 version 1.2 and Python 2.6.8 internally.
For copyright reasons I cannot share the involved file with you, sorry.

unfortunate breaking of empty brackets

Example:

$ echo 'someverylongindenttionwhatnot().foo().bar().baz("and here is a long string 123456789012345678901234567890")' > test.py
$ autopep8 test.py 
someverylongindenttionwhatnot().foo(
).bar().baz("and here is a long string 123456789012345678901234567890")

I'd prefer:

someverylongindenttionwhatnot().foo().bar().baz(
    "and here is a long string 123456789012345678901234567890")

recent changes break tests for Python3

Hi,
all test_w602_* fail with python3 in 0.5.1 and current HEAD:

 * Testing of dev-python/autopep8-0.5.1 with CPython 3.2...
..........................................................Traceback (most recent call last):
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 688, in 
    sys.exit(main())
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 684, in main
    fix_file(args[0], opts)
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 629, in fix_file
    fixed_source = fix.fix()
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 162, in fix
    self._fix_source()
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 137, in _fix_source
    modified_lines = fix(result)
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 484, in fix_w602
    ast_body = ast.parse(line[indent_offset:]).body[0]
  File "/usr/lib64/python3.2/ast.py", line 36, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "", line 1
    raise ValueError, "info", traceback
                    ^
SyntaxError: invalid syntax
FTraceback (most recent call last):
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 688, in 
    sys.exit(main())
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 684, in main
    fix_file(args[0], opts)
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 629, in fix_file
    fixed_source = fix.fix()
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 162, in fix
    self._fix_source()
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 137, in _fix_source
    modified_lines = fix(result)
  File "/var/tmp/portage/dev-python/autopep8-0.5.1/work/autopep8-0.5.1/autopep8.py", line 484, in fix_w602
    ast_body = ast.parse(line[indent_offset:]).body[0]
  File "/usr/lib64/python3.2/ast.py", line 36, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "", line 1
    raise ValueError, "info", traceback  # comment
                    ^
SyntaxError: invalid syntax
F........test/test_autopep8.py:544: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(f.read(), fixed)
.........
======================================================================
FAIL: test_w602_raise_argument_triple (__main__.TestFixPEP8Warning)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/test_autopep8.py", line 455, in test_w602_raise_argument_triple
    self.assertEqual(self.result, fixed)
AssertionError: '' != 'raise ValueError("info"), None, traceback\n'
+ raise ValueError("info"), None, traceback


======================================================================
FAIL: test_w602_raise_argument_triple_with_comment (__main__.TestFixPEP8Warning)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/test_autopep8.py", line 461, in test_w602_raise_argument_triple_with_comment
    self.assertEqual(self.result, fixed)
AssertionError: '' != 'raise ValueError("info"), None, traceback  # comment\n'
+ raise ValueError("info"), None, traceback  # comment

autopep8 occasionally gives invalid syntax for E501 (80+ character lines) errors

Note the following example:

mydict = {
    'longkey': {
        'key2': {
            'longkey3': 1,
        }
    }
}
mydict['longkey']['key2']['longkey3'] = 'my long string goes here that goes well past line 80'

For which autopep8 gives the following output:

mydict = {
    'longkey': {
        'key2': {
            'longkey3': 1,
        }
    }
}
mydict['longkey']['key2']['longkey3']
    = 'my long string goes here that goes well past line 80'

This is invalid syntax and should put a backslash at the end of the first part of the broken line.

test/example.py missing

autopep8-0.8.3 introduced test_fix_file() test, which requires test/example.py file, which is absent in autopep8-0.8.3.tar.gz available on PyPI.

$ python test/test_autopep8.py
..............................................................................................................................................................................................................E..................
======================================================================
ERROR: test_fix_file (__main__.TestUtils)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test/test_autopep8.py", line 229, in test_fix_file
    filename=os.path.join(ROOT_DIR, 'test', 'example.py')))
  File "/tmp/autopep8-0.8.3/autopep8.py", line 1694, in fix_file
    tmp_source = normalize_line_endings(read_from_filename(filename))
  File "/tmp/autopep8-0.8.3/autopep8.py", line 104, in read_from_filename
    encoding=detect_encoding(filename)) as input_file:
  File "/tmp/autopep8-0.8.3/autopep8.py", line 77, in detect_encoding
    with open(filename, 'rb') as input_file:
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/autopep8-0.8.3/test/example.py'

----------------------------------------------------------------------
Ran 225 tests in 13.518s

FAILED (errors=1)

space character into variable name inserted

I just got a case where autopep8 produces invalid python code by inserting a single space character in a variable name.

The file on where I noticed this problem is https://github.com/geops/pg_routejoin/blob/cbaca86b3a6d37869ff1b3e3edba027f0db52e71/routejoin/table.py with the relevant line being line 46.

After reformating the file with autopep8 the line

    return "%s %s on %s" % (self.jointype if self.jointype!=None else "join", self.fullname, ' and '.join(joined_columns))

gets converted to

   return "%s %s on %s" % (self.jointype if self.join type != None else "join", self.fullname, ' and '.join(joined_columns))

I tried to create a simpler testcase, but could only reproduce the problem with the original file.

I used the current autopep8 version from Pypi (autopep8-0.6.tar.gz). Feel free to include the table.py file in your testcases if you want to.

performance seems bad

I tried running 'autopep8 -d' on file sphinx/sphinx/environment.py (1762 lines) and here are the timings on an imac with 2.7G core i5 and 8G ram:

real    0m6.042s
user    0m5.981s
sys 0m0.058s

I am using python 2.7.3 release (built from source).

autopep8 0.6 corrupts multi-line string content

Consider this tiny program:

text = """line one
    line two indented by <tab>
  line three indented by <space><space>
line four"""
lines = text.split('\n')
text = '\n'.join('>' + l for l in lines)
print text
print 'length:', len(text)

When run it produces this output:

# python multiline-string.py 
>line one
>   line two indented by <tab>
>  line three indented by <space><space>
>line four
length: 90

After running it through autopep8 0.6 the output changes to:

# python multiline-string.py 
>line one
>        line two indented by <tab>
>  line three indented by <space><space>
>line four
length: 97

as <tab> has been changed to 8*<space>.

To be fair, pep8 is broken in that regard, too:

# pep8 multiline-string.py 
multiline-string.py:2:1: W191 indentation contains tabs
multiline-string.py:3:1: E101 indentation contains mixed spaces and tabs

Failed to wrap long line at column 79 (--max-line-length)

$ python -c 'print("#" * 79)'; cat w79.py
###############################################################################
if condition_foo and something_long_object_name(plus, its, many, arguments, here):
    pass

$ autopep8 --max-line-length=79 -vv w79.py
[file:w79.py]
--->  1 issue(s) to fix {'E501': set([1])}
--->  Not fixing E501 on line 1
if condition_foo and something_long_object_name(plus, its, many, arguments, here):
    pass

I am expecting output:

if condition_foo and something_long_object_name(plus, its, many, arguments,                                                                                   
                                                here):                          
    pass

By the way, really nice tool!

Incorrect output with E231 and E225

test_broken.py:

0,11/2

Running autopep8 on test_broken.py results in incorrect output:

$ autopep8 test_broken.py
0, 1 1 /2

Instead I would expect:

0, 11 / 2

Here is the output of pep8 for reference:

$ pep8 test_broken.py
test_broken.py:1:2: E231 missing whitespace after ','
test_broken.py:1:5: E225 missing whitespace around operator

Shorten long lines (multi-line)

i'd like to be able to run autopep8 to get the django migration files pep8 compliant, but it cant handle these files at all.

autopep8 AssertionError

autopep8 (version f682f7e) produces an AssertionError when processing an UTF8 encoded with with a byte order mark (BOM). The same file is processed just fine when the BOM is removed.

$ file foo.py 
foo.py: HTML document, UTF-8 Unicode (with BOM) text, with CR, LF line terminators
$ autopep8 -i foo.py                                                                                                                                               

Traceback (most recent call last):
  File "/usr/local/bin/autopep8", line 9, in 
    load_entry_point('autopep8==0.8.2', 'console_scripts', 'autopep8')()
  File "/usr/local/lib/python2.7/dist-packages/autopep8-0.8.2-py2.7.egg/autopep8.py", line 1828, in main
    fix_file(name, opts, output)
  File "/usr/local/lib/python2.7/dist-packages/autopep8-0.8.2-py2.7.egg/autopep8.py", line 1670, in fix_file
    fixed_source = fix.fix()
  File "/usr/local/lib/python2.7/dist-packages/autopep8-0.8.2-py2.7.egg/autopep8.py", line 234, in fix
    results = _execute_pep8(pep8_options, self.source)
  File "/usr/local/lib/python2.7/dist-packages/autopep8-0.8.2-py2.7.egg/autopep8.py", line 1054, in _execute_pep8
    checker.check_all()
  File "/usr/local/lib/python2.7/dist-packages/pep8-1.3.3-py2.7.egg/pep8.py", line 1340, in check_all
    self.check_logical()
  File "/usr/local/lib/python2.7/dist-packages/pep8-1.3.3-py2.7.egg/pep8.py", line 1269, in check_logical
    self.build_tokens_line()
  File "/usr/local/lib/python2.7/dist-packages/pep8-1.3.3-py2.7.egg/pep8.py", line 1263, in build_tokens_line
    assert self.logical_line.strip() == self.logical_line
AssertionError

only space around the first parameter is fixed in a function call

Only the first parameter in a list of many, perhaps continuing for several lines, is fixed:

 setup(
-      name = 'sympy', version = sympy.__version__,
+      name= 'sympy', version = sympy.__version__,
       description = 'Computer algebra system (CAS) in Python',

If the suggested change is made, no other change (e.g. to the space around the equal sign after version nor to the space after description) is corrected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.