Code Monkey home page Code Monkey logo

pep8radius's Introduction

pep8radius

PEP8 clean only the parts of the files touched since the last commit, a previous commit or (the merge-base of) a branch.

Current PyPi Version MIT licensed Travis CI Status Coverage Status PyPi Monthly Downloads

Fixing the entire project of PEP8 infractions ("PEP8 storms") can lead to merge conflicts, add noise to merges / pull requests and break (git) blame. pep8radius solves this problem by fixing only those PEP8 infractions incontained on the lines of the project which you've been working, leaving these sections "better than you found it" whilst keeping your commits focused on the areas of the codebase you were actually working on.

Requirements

pep8radius uses autopep8, and in turn pep8. The docformatter option, to fix docstrings, uses docformatter.

You can also use yapf as an alternative back-end.

Installation

From pip:

$ pip install pep8radius

Usage

Usage gif of pep8radius

  • Move to project directory
  • Make some changes to the project
  • Run pep8radius --diff # view a diff of proposed fixed
  • Run pep8radius --in-place # apply the fixes
  • Commit your changes

Against a branch you can use the same syntax as with git diff:

$ pep8radius master   # branch name to compare against (compares against merge-base)
$ pep8radius c12166f  # commit hash

$ pep8radius master --in-place  # these work with other options too

You can also fix docstrings (PEP257) using the docformatter option:

$ pep8radius --docformatter --diff

Note: can also use btyfi alias for pep8radius.


It can be nice to pipe the diff to cdiff (which makes diffs pretty and has lots of options):

$ pep8radius --diff --no-color | cdiff
$ pep8radius --diff --no-color | cdiff --side-by-side

You can get strange results if you don't use no-color.
I actually use the following git alias (which allows git rad and git rad -i):

[alias]
    rad = !pep8radius master --diff --no-color $@ | cdiff --side-by-side

which outputs the corrections as follows:

git rad


You can pipe in a diff directly, to fix the lines modified in it with --from-diff (this is somewhat experimental, please report failing diffs!).
For example:

$ git diff master | pep8radius --diff --from-diff=-

yapf

To use yapf as an alternative back-end, you can pass the --yapf option:

$ pep8radius master --diff --yapf

$ pep8radius master --diff --yapf --style=google

Note: This ignores autopep8 and docformatter specific arguments.

Config Files

pep8radius looks for configuration files as described in the pep8 docs.

At the project level, you may have a setup.cfg which includes a pep8 section, you can use this to define defaults for pep8radius and autopep8:

[pep8]
rev = master
ignore = E226,E302,E41
max-line-length = 160

By default, this will look for a user level default, you can suppress this by passing a blank to global_config:

[pep8]
rev = staging
global_config =

or perhaps you want to use yapf with google style:

[pep8]
rev = master
yapf = True
style = google

Note: style can also be a config file, or a dict (see the yapf docs).

VCS Support

Git, Mecurial (hg), (tentatively) Bazaar. Please request support for other version control systems on github.

Options

$ pep8radius --help

usage: pep8radius [-h] [--version] [-d] [-i] [--no-color] [-v]
                  [--from-diff DIFF] [-p n] [-a] [--experimental]
                  [--exclude globs] [--list-fixes] [--ignore errors]
                  [--select errors] [--max-line-length n] [--indent-size n]
                  [-f] [--no-blank] [--pre-summary-newline] [--force-wrap]
                  [--global-config GLOBAL_CONFIG] [--ignore-local-config]
                  [rev]

PEP8 clean only the parts of the files which you have touched since the last
commit, a previous commit or (the merge-base of) a branch.

positional arguments:
  rev                   commit or name of branch to compare against

optional arguments:
  -h, --help            show this help message and exit
  --version             print version number and exit
  -d, --diff            print the diff of fixed source vs original
  -i, --in-place        make the fixes in place; modify the files
  --no-color            do not print diffs in color (default is to use color)
  -v, --verbose         print verbose messages; multiple -v result in more
                        verbose messages (one less -v is passed to autopep8)
  --from-diff DIFF      Experimental: rather than calling out to version
                        control, just pass in a diff; the modified lines will
                        be fixed

pep8:
  Pep8 options to pass to autopep8.

  -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 and exit; used by --ignore and
                        --select
  --ignore errors       do not fix these errors/warnings (default: E24)
  --select errors       fix only these errors/warnings (e.g. E4,W)
  --max-line-length n   set maximum allowed line length (default: 79)
  --indent-size n       number of spaces per indent level (default 4)

docformatter:
  Fix docstrings for PEP257.

  -f, --docformatter    Use docformatter
  --no-blank            Do not add blank line after description
  --pre-summary-newline
                        add a newline before the summary of a multi-line
                        docstring
  --force-wrap          force descriptions to be wrapped even if it may result
                        in a mess

config:
  Change default options based on global or local (project) config files.

  --global-config filename
                        path to 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 dir

yapf:
  Options for yapf, alternative to autopep8. Currently any other options are
  ignored.

  -y, --yapf            Use yapf rather than autopep8. This ignores other
                        arguments outside of this group.
  --style               style either pep8, google, name of file with
                        stylesettings, or a dict

Run before you commit, against a previous commit or branch before merging.

For more information about these options see autopep8.

As a module

Pep8radius also exports lightweight wrappers around autopep8 so that you can fix line ranges of your code with fix_code or fix_file.

Here's the example "bad code" from autopep8's README:

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)

You can pep8 fix just the line ranges 1-1 (the imports) and 12-21 (the Example3class) with pep8radius.fix_code(code, [(1, 1), (12, 21)]) (where code is a string of the above), which returns the code fixed within those ranges:

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 {'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)

You can use fix_file to do this directly on a file, which gives you the option of doing this in place.

pep8radius.fix_code('code.py', [(1, 1), (12, 21)], in_place=True)

You can also pass the same arguments to pep8radius script itself using the parse_args. For example ignoring long lines (E501) and use the options from your global config files:

args = pep8radius.parse_args(['--ignore=E501', '--ignore-local-config'],
                             apply_config=True)
pep8radius.fix_code(code, [(1, 1), (12, 21)], options=args)

pep8radius's People

Contributors

hayd avatar kstark avatar schodge avatar underyx avatar

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

pep8radius's Issues

use cdiff for colored diffs

ATM I've rolled my own diff printer, should probably use cdiff - which also allows for paging and side-by-side which would be pretty neat.

Note: I don't think cdiff existed when pep8radius started (I recall looking), I had been considering breaking out my diff printer to a sep lib...

Cannot uninstall pep8radius from pip --user install

Steps to reproduce:

  • pip install --user pep8radius
  • pip uninstall pep8radius

What should happen:

pep8radius is installed then uninstalled.

What happens instead:

pep8radius is installed. When attempting uninstallation:

Can't uninstall 'pep8radius'. No files were found to uninstall.

Notes:

  • This also prevents upgrade attempts but I can't reproduce this at the moment.
  • This procedure works with other Python packages (e.g. youtube-dl)
  • This procedure works in a virtualenv.

Workaround:

Manually delete files listed in .local/lib/python2.7/site-packages/pep8radius-0.9.1-py2.7.egg-info/installed-files.txt

Drop autopep8

Just use yapf. At some point critical parts of autopep8 were removed (due to IMO a minor edge case/bug). It's probably easiest to either

  1. drop autopep8 completely.
  2. make yapf the default (and set the version of autopep8 to when it worked)
  3. make yapf the default and vendorize the earlier version / extract the relevant removed code.

I'm loathe to do 3, and 1. is easiest.

Personally, I've been using yapf exclusively for some time.

Coverage no longer including check_output calls

Calls like:

python pep8radius.py --version

are no longer counted against coverage. Changed when I moved around project structure. This seems strange! (tried, but failed to fix in #45)

Thoughts: maybe this is the sys.argv thing, could use argparse() rather than argparse(sys.argv[1:])... and/or optionally pass args into main, not sure what normal/correct play is here.

possible bugs in autopep8 (to file)

Note: autopep8 is safe (conservative), these "bugs" are to make it more aggressive in what it can fix.

Should confirm these/provide tests and pass upstream/fix:

  • indentation fixes hhatto/autopep8#133
  • line changing fixes hhatto/autopep8#131
  • currently adds a blank line at end of file for line_range (should it?) - perhaps it's better for us just to ignore radius around an end of line file change?
  • super edge case for comment only line_range (related to below?) low prio
  • indenting comments in multi-indented lines hhatto/autopep8#169

Note: we'll obviously need to require a later version if/once these are fixed!

Consider copying some of my examples in the unittests for range there here.

deleted file

Atm returns a Call Process Error if checked in file is deleted.

landscape (codeclimate)

https://landscape.io/github/hayd/pep8radius/

There's a couple of easy fixes here.

* issue is that the python 2 and 3 syntax is different, see http://stackoverflow.com/a/18513858/1240268 but loath to add six as requirement (could plop into compat module in a refactor - the file is getting stupidly long!)

Ah ha, trick could be just to create class AbstractMethodError(NotImplementedError).

Update: meh on the remaining things... just meh.

Windows test failures

Sorry for being AWOL lately. Here's the current output of tests on one Windows box. Accidentally reverted to an older verison of git (1.8.x), not sure if that's the cause of anything:

λ nosetests .\tests
.F........FSSSSSSSS......F.SSSSSSSS.S.
======================================================================
FAIL: test_autopep8_args (tests.test_main.TestMain)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\GitHub\pep8radius\tests\test_main.py", line 27, in test_autopep8_args
    self.assertEqual(us.ignore, them.ignore)
AssertionError: set(['E24']) != [u'E24']

======================================================================
FAIL: test_from_diff (tests.test_radius.TestRadiusFromDiff)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\GitHub\pep8radius\tests\test_radius.py", line 181, in test_from_diff
    self.assertEqual(out.getvalue(), exp_diff)
AssertionError: '' != '--- original\\foo.py\n+++ fixed\\foo.py\n@@ -4,7 +4,9 @@\n   return a + b\n \n foo = 1; bar = 2; print(foo * bar)\n-a=1; b=42; c=3\n+a = 1\n+b = 42\n+c = 3\n d=7\n \n def f(x = 1, y = 2):\n'

======================================================================
FAIL: test_one_line_from_subdirectory (tests.test_vcs.TestRadiusGit)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\GitHub\pep8radius\tests\test_radius.py", line 92, in test_one_line_from_subdirectory
    cwd=SUBTEMP_DIR)
  File "c:\GitHub\pep8radius\tests\test_radius.py", line 50, in check
    self.assert_equal(out.getvalue(), exp_diff, test_name)
  File "c:\GitHub\pep8radius\tests\test_radius.py", line 74, in assert_equal
    'expected', 'result'))
AssertionError: --- expected\test_one_line
+++ result\test_one_line
@@ -1,5 +1,5 @@
---- c:\GitHub\pep8radius\tests\temp\subtemp\temp.py
-+++ c:\GitHub\pep8radius\tests\temp\subtemp\temp.py
+--- c:\GitHub\pep8radius\tests\temp\subtemp/temp.py
++++ c:\GitHub\pep8radius\tests\temp\subtemp/temp.py
 @@ -4,7 +4,9 @@
    return a + b



----------------------------------------------------------------------
Ran 38 tests in 11.170s

FAILED (SKIP=17, failures=3)

config file

This is critical / would make a great feature. Very eager to do this.

either project-wise or global for setting ignores etc. I don't think autopep8 does this either so maybe worth adding one there at the same time (so we can share a config). Idea from discussion in #28.

refactor code more oo

should make it cleaner to add other vcs (emphasise which bits are vc specific, rather than vc arg everywhere).

Something like Radius(vc=optional) get vc then return RadiusGit() (subclass). Radius has those impl specific bits raise NotImplemented. Note: udiff parser should probably be there too (hg and git are the same but potentially not all (?) ).

rev should find last shared commit

When I do pep8radius master --diff I almost always want to compare the last shared commit of master and the current_branch.

(At the moment it uses git diff master to get lines changed from the tip of master. I'm suggesting making a decision on whether to choose the/a branch-point to diff against, or at least have this as an option.)

See http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git

Does this concept only makes sense in the rebase model, rather than merging? ...not sure whether something like this would make a good API...

add colour

esp. nice with diffs, just like you get with git diff.

May be simplest just to create a diff_print function to print each line, colour green if startswith +, red if startswith -, and pink background (?) of trailing whitespace (Note: git does this just for + lines, but seems reasonable to do it for both + and -).

colorama seems like a reasonable choice.

tests todo list

The new file structure is now much less of a mess (not just one file), so should be able to more trivially tick a couple of these off / be clear where to put things.

  • test udiff functions (extracting line numbers and removed lines) + *.
  • test diff output
  • test dry-run in-place (idea: just do a dry run in check as first thing, or alternatively do a little for loop of different configurations of diff and dry-run and ... ?)
  • example tests with * (update/note to self: wtf is *?)
  • tests for more edge cases in autopep8 line range (off topic if already in their tests?)
  • excludes and other options (?) not passed on to autopep8
  • version number
  • list-fixes
  • bad rev
  • specific rev (idea: perhaps successfully_commit... could return commit hash)
  • test against branches (not convinced there is a need to do this, as git/hg diff is doing the work here, but should confirm this ? :S ) specifically bazaar (I skip a test atm)
  • test with bad syntax
  • bad vc (passed to new)
  • no vc in directory (which_version_control raises) ... no cover ;)
  • be able to run tests (safely) without being in test directory #27
  • Potentially delete .git and .hg on tearDown (seems kindof wasteful to do this for each test, would prefer if could do on just the init setup and final tearDown?).

* udiffs with lines combined and distinct lines in multiple files.

cannot decode byte

This happened when I tried to use pep8radius:

Traceback (most recent call last):
  File "c:\program files\python36\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\program files\python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Program Files\Python36\Scripts\pep8radius.exe\__main__.py", line 9, in <module>
  File "c:\program files\python36\lib\site-packages\pep8radius\main.py", line 275, in _main
    return sys.exit(main(args=args, vc=vc, cwd=cwd, apply_config=True))
  File "c:\program files\python36\lib\site-packages\pep8radius\main.py", line 65, in main
    args = parse_args(args, apply_config=apply_config)
  File "c:\program files\python36\lib\site-packages\pep8radius\main.py", line 211, in parse_args
    parser = apply_config_defaults(parser, args, root=root)
  File "c:\program files\python36\lib\site-packages\pep8radius\main.py", line 243, in apply_config_defaults
    root = VersionControl.which().root_dir()
  File "c:\program files\python36\lib\site-packages\pep8radius\vcs.py", line 84, in which
    if k.startswith('using_') and using_vc(cwd=cwd):
  File "c:\program files\python36\lib\site-packages\pep8radius\vcs.py", line 24, in using_git
    git_log = shell_out(["git", "log"], cwd=cwd)
  File "c:\program files\python36\lib\site-packages\pep8radius\shell.py", line 58, in shell_out
    out = check_output(cmd, cwd=cwd, stderr=stderr, universal_newlines=True)
  File "c:\program files\python36\lib\subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "c:\program files\python36\lib\subprocess.py", line 405, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "c:\program files\python36\lib\subprocess.py", line 825, in communicate
    stdout = self.stdout.read()
  File "c:\program files\python36\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 937662: character maps to <undefined>

should be quiet if not making changes

related to #13, if there are no pep8 violations maybe it should say so / print less. Or say the number of changes made in each / over all line range:

  • 9-7 (3), 5-5 (0), 3-2 (2) or just 9-7(3), 3-2 (2)
  • 5 changes (==passes?) made in file...

Not sure.

rename project page pep8radius

  • rename main and testing file #32
  • rename github project page
  • grepping should find two instances of btyfi (setup.py alias and note of alias)

think I was tired/excited when came up with this name (and thought it was a good idea), pep8radius is just much better/more discriptive, will keep btyfi alias.

Will change github url immediately before next release (waiting on autopep8 release).

Feedback on config

At the moment it looks at default (home config) then updates with local configs (.pep8 etc) then updates with passed in arguments. See #71.

Was hoping for feedback before pushing release...

Concerns:

  • This may raise if there are bad config files. Personally I think this is a good thing.
  • If you are using a projects config perhaps you don't want to dirty it with your own? (currently if configs are not set locally then defaults are from the user's config). I'm unsure about this behaviour.

E231 Optional?

Thoughts on refraining from auto-correcting E231, whitespace required after ','?

I ask because the actual PEP8 document doesn't seem to comment on the appropriateness or lack thereof A[(i,j)] vs. A[(i, j)] for arrays, and while I generally agree the space should be there, I prefer the look without it for the case of indices.

add a jobs argument

autopep8 has a jobs argument:

-j n, --jobs n        number of parallel jobs; match CPU count if value is less than 1

This would be great to have, if someone wanted to pick this up. Presumably you'd deal with each file separately (i.e. where it iterates over filenames_diff).

This is less useful than autopep8's as by definition (?) we ought to be acting on a smaller set of fixes (and it should usually take less time than a full autopep8 pass).

python 3 printing only when line complete

when printing the line changes python 2 prints immediately, python 3 waits til end of line.

9-7 <prints> 6-5 <prints>
9-7, 6-5 <prints>

I think you can just flush, or maybe even option in print function.

Windows support?

Need to test this, atm using subprocess/command line so could be an issue here.

Potentially could be fixed with #3 ?

Current Build Windows Errors, Part II

The last thread is long enough, and I propose dedicating it to the problem with Hg errors not propogating up far enough to see easily.

With a username set in Hg, here's the current status:

c:\github\pep8radius (master)
λ nosetests --verbose
test_bad_rev (test_pep8radius.TestRadiusBzr) ... ERROR
test_earlier_revision (test_pep8radius.TestRadiusBzr) ... SKIP
test_one_line (test_pep8radius.TestRadiusBzr) ... SKIP: bzr not available
test_one_line_from_subdirectory (test_pep8radius.TestRadiusBzr) ... SKIP: bzr not available
test_with_docformatter (test_pep8radius.TestRadiusBzr) ... SKIP: bzr not available
test_bad_rev (test_pep8radius.TestRadiusGit) ... ok
test_earlier_revision (test_pep8radius.TestRadiusGit) ... ERROR
test_one_line (test_pep8radius.TestRadiusGit) ... ok
test_one_line_from_subdirectory (test_pep8radius.TestRadiusGit) ... ok
test_with_docformatter (test_pep8radius.TestRadiusGit) ... ok
test_bad_rev (test_pep8radius.TestRadiusHg) ... ok
test_earlier_revision (test_pep8radius.TestRadiusHg) ... ok
test_one_line (test_pep8radius.TestRadiusHg) ... ok
test_one_line_from_subdirectory (test_pep8radius.TestRadiusHg) ... ok
test_with_docformatter (test_pep8radius.TestRadiusHg) ... ok
test_autopep8_args (test_pep8radius.TestRadiusNoVCS) ... ok
test_bad_vc (test_pep8radius.TestRadiusNoVCS) ... ok
test_list_fixes (test_pep8radius.TestRadiusNoVCS) ... ok
test_no_vc (test_pep8radius.TestRadiusNoVCS) ... ok
test_unknown_vc (test_pep8radius.TestRadiusNoVCS) ... ok
test_using_vc (test_pep8radius.TestRadiusNoVCS) ... ok
test_version_number (test_pep8radius.TestRadiusNoVCS) ... ok

======================================================================
ERROR: test_bad_rev (test_pep8radius.TestRadiusBzr)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 278, in test_bad_rev
    'random_junk_sha')
  File "C:\Anaconda\lib\unittest\case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 277, in <lambda>
    lambda x: Radius.new(rev=x, vc=self.vc),
  File "c:\github\pep8radius\pep8radius.py", line 256, in new
    return r(rev=rev, options=options)
  File "c:\github\pep8radius\pep8radius.py", line 223, in __init__
    self.rev = self._branch_point(rev)
  File "c:\github\pep8radius\pep8radius.py", line 408, in _branch_point
    current = self.current_branch()
  File "c:\github\pep8radius\pep8radius.py", line 542, in current_branch
    "--custom", "--template={revision_id}"])
  File "c:\github\pep8radius\pep8radius.py", line 55, in shell_out
    out = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  File "C:\Anaconda\lib\subprocess.py", line 566, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "C:\Anaconda\lib\subprocess.py", line 710, in __init__
    errread, errwrite)
  File "C:\Anaconda\lib\subprocess.py", line 958, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

======================================================================
ERROR: test_earlier_revision (test_pep8radius.TestRadiusGit)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 286, in test_earlier_revision
    self.checkout('ter', create=True)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 340, in checkout
    shell_out(["git", "checkout", '-b', branch])
  File "c:\github\pep8radius\pep8radius.py", line 55, in shell_out
    out = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  File "C:\Anaconda\lib\subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command '['git', 'checkout', '-b', 'ter']' returned non-zero exit status 128

----------------------------------------------------------------------
Ran 22 tests in 15.859s

FAILED (SKIP=4, errors=2)

require autopep8 version 1.0.1

waiting on its release.

At the same time, should tweak (switch? or keep both?) allowable failures on travis (git and pypi)... also pip install git docformatter in the same way.

add tests

don't need to check all features of autopep8, just that it is only working on part of the file...

I was thinking:

  • have a mini git repo
  • echo something bad into the file
  • pep8-radius it
  • check output still has some badness

Will need to add script (for travis) to create git (and hg) repos in test dir and commit the original_ files, to use pep8radius against. Then ensure that travis is "in" the correct directory, I'm hoping this will "just work". Should test against autopep8 master as well as latest release.

coverage

For 100%:

  • coveralls #33
  • which_version_control (um, no idea how to hit using_hg... mock?)
  • autopep8 args (idea: check output of out parse_args vs theirs) one line: default ignore
  • exclude
  • diff and dry-run
  • verbosity
  • Radius.new with unknown vc string (and with None)
  • CLI: list fixes (just compare to autopep8) and version number from command line
  • CLI: run main, perhaps pragma no cover the NotImplemented
  • add purtty (green) badge
  • color diffs, use mock on coloram call (e.g. colorama.Fore.RED = '')
  • check_output calls (used to be working?) #46
  • stoopid AbstractMethodErrors
  • Bzr merge-base (test against earlier revisions)

see also #25

Currently coverage

autopep8 options which don't work yet

Ensure all options actually make sense (or are recognised), specifically:

  • --exclude globs won't work as we use fix_code (rather than file_file) now. Same is probably true for others. (Possible fix for those two is to check off in the files list comprehension... other option is to do it in git/hg command, but tbh I think that is going to be more complicated / unnecessary.)
  • --list-fixes should be special cased to call autopep8 --list-fixes and exit.

Testing on windows

Tried this just now on my work computer, which has various IT restrictions on it. I've gotten to FFFsss.E.E.EF., which clearly means the paths aren't being picked up right for Git and mercurial. No surprise there, but not my question.

The only way I could get that far was to change test_pep8radius.py to use from pep8radius import ... instead of from pep8radius.pep8radius import ..., which gave me a no module named pep8radius error. Forgive me for being dense, but what's the purpose of the import a.a instead of import a?

don't shell out to autopep8

instead use it as a module.

This may help get some additional info about what's fixed (e.g. changesets which we can combine for each file and print nicely). As discussed in #11... that may be trickier/require some changes to autopep8, I'm not sure.

ensure eof newline option

I think atm new line is always added to eof (if missing) potentially this is a bug in autopep8, but we should have this as an option...

This is much less a problem than it was in earlier versions (where this counted as an additional radius to apply autopep8 to on a second iteration... I think it's ok now - should add test)

hg testing on Windows

The good news is that (I think) this is a testing bug, rather than a bug in the actual Hg implementation...

Tests fails atm, I had a play a short while ago.

On Windows there seems to be an inconsistency in how os.chdir works, it seems to work correctly working in the repl but not in the actual code. I tried wrapping functions with (e.g. I think that successfully_commit is not wrapped probably and changes directory), but even fixing that... no avail.

@contextmanager
def in_temp_dir():
    current_dir = os.getcwd()
    os.chdir(TEMP_DIR)
    yield
    os.chdir(current_dir)

This context manager just doesn't work in Windows for me (in the test script, it works as you'd expect in repl/debugging). Maddening.

Will try and dig up full stack trace error when/if I next use Windows.

Current Build Windows Errors

Should the first test be skipping if no Bzr is installed?

λ nosetests
ESSSS.E....EFFF.......
======================================================================
ERROR: test_bad_rev (test_pep8radius.TestRadiusBzr)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 277, in test_bad_rev
    'random_junk_sha')
  File "C:\Anaconda\lib\unittest\case.py", line 473, in assertRaises
    callableObj(*args, **kwargs)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 276, in <lambda>
    lambda x: Radius.new(rev=x, vc=self.vc),
  File "c:\github\pep8radius\pep8radius.py", line 256, in new
    return r(rev=rev, options=options)
  File "c:\github\pep8radius\pep8radius.py", line 223, in __init__
    self.rev = self._branch_point(rev)
  File "c:\github\pep8radius\pep8radius.py", line 408, in _branch_point
    current = self.current_branch()
  File "c:\github\pep8radius\pep8radius.py", line 542, in current_branch
    "--custom", "--template={revision_id}"])
  File "c:\github\pep8radius\pep8radius.py", line 55, in shell_out
    out = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  File "C:\Anaconda\lib\subprocess.py", line 566, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "C:\Anaconda\lib\subprocess.py", line 710, in __init__
    errread, errwrite)
  File "C:\Anaconda\lib\subprocess.py", line 958, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

======================================================================
ERROR: test_earlier_revision (test_pep8radius.TestRadiusGit)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 285, in test_earlier_revision
    self.checkout('ter', create=True)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 339, in checkout
    shell_out(["git", "checkout", '-b', branch])
  File "c:\github\pep8radius\pep8radius.py", line 55, in shell_out
    out = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  File "C:\Anaconda\lib\subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command '['git', 'checkout', '-b', 'ter']' returned non-zero exit status 128

======================================================================
ERROR: test_earlier_revision (test_pep8radius.TestRadiusHg)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 291, in test_earlier_revision
    r = Radius.new(rev=start, options=args, vc=self.vc)
  File "c:\github\pep8radius\pep8radius.py", line 256, in new
    return r(rev=rev, options=options)
  File "c:\github\pep8radius\pep8radius.py", line 223, in __init__
    self.rev = self._branch_point(rev)
  File "c:\github\pep8radius\pep8radius.py", line 412, in _branch_point
    return self.merge_base(rev, current)
  File "c:\github\pep8radius\pep8radius.py", line 516, in merge_base
    output = shell_out(['hg', 'debugancestor', rev1, rev2])
  File "c:\github\pep8radius\pep8radius.py", line 55, in shell_out
    out = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True)
  File "C:\Anaconda\lib\subprocess.py", line 566, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "C:\Anaconda\lib\subprocess.py", line 710, in __init__
    errread, errwrite)
  File "C:\Anaconda\lib\subprocess.py", line 913, in _execute_child
    args = list2cmdline(args)
  File "C:\Anaconda\lib\subprocess.py", line 616, in list2cmdline
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: argument of type 'bool' is not iterable

======================================================================
FAIL: test_one_line (test_pep8radius.TestRadiusHg)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 252, in test_one_line
    self.check(original, modified, expected, 'test_one_line')
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 216, in check
    self.assert_equal(out.getvalue(), exp_diff, test_name)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 241, in assert_equal
    'expected', 'result'))
AssertionError: --- test_one_line\expected
+++ test_one_line\result
@@ -1,13 +1,45 @@
+--- c:\github\pep8radius\tests\temp\AAA.py\original
++++ c:\github\pep8radius\tests\temp\AAA.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
+--- c:\github\pep8radius\tests\temp\BBB.py\original
++++ c:\github\pep8radius\tests\temp\BBB.py\fixed
+@@ -1 +1 @@
+-b=1;
+\ No newline at end of file
++b = 1
+--- c:\github\pep8radius\tests\temp\CCC.py\original
++++ c:\github\pep8radius\tests\temp\CCC.py\fixed
+@@ -1 +1 @@
+-c=1
+\ No newline at end of file
++c = 1
+--- c:\github\pep8radius\tests\temp\a.py\original
++++ c:\github\pep8radius\tests\temp\a.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
 --- c:\github\pep8radius\tests\temp\temp.py\original
 +++ c:\github\pep8radius\tests\temp\temp.py\fixed
-@@ -4,7 +4,9 @@
+@@ -3,9 +3,14 @@
+   b = 2
    return a + b

- foo = 1; bar = 2; print(foo * bar)
+-foo = 1; bar = 2; print(foo * bar)
 -a=1; b=42; c=3
+-d=7
++foo = 1
++bar = 2
++print(foo * bar)
 +a = 1
 +b = 42
 +c = 3
- d=7
++d = 7

- def f(x = 1, y = 2):
+-def f(x = 1, y = 2):
++
++def f(x=1, y=2):
+     return x + y


======================================================================
FAIL: test_one_line_from_subdirectory (test_pep8radius.TestRadiusHg)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 259, in test_one_line_from_subdirectory
    directory=SUBTEMP_DIR)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 216, in check
    self.assert_equal(out.getvalue(), exp_diff, test_name)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 241, in assert_equal
    'expected', 'result'))
AssertionError: --- test_one_line\expected
+++ test_one_line\result
@@ -1,13 +1,45 @@
+--- c:\github\pep8radius\tests\temp\AAA.py\original
++++ c:\github\pep8radius\tests\temp\AAA.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
+--- c:\github\pep8radius\tests\temp\BBB.py\original
++++ c:\github\pep8radius\tests\temp\BBB.py\fixed
+@@ -1 +1 @@
+-b=1;
+\ No newline at end of file
++b = 1
+--- c:\github\pep8radius\tests\temp\CCC.py\original
++++ c:\github\pep8radius\tests\temp\CCC.py\fixed
+@@ -1 +1 @@
+-c=1
+\ No newline at end of file
++c = 1
+--- c:\github\pep8radius\tests\temp\a.py\original
++++ c:\github\pep8radius\tests\temp\a.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
 --- c:\github\pep8radius\tests\temp\temp.py\original
 +++ c:\github\pep8radius\tests\temp\temp.py\fixed
-@@ -4,7 +4,9 @@
+@@ -3,9 +3,14 @@
+   b = 2
    return a + b

- foo = 1; bar = 2; print(foo * bar)
+-foo = 1; bar = 2; print(foo * bar)
 -a=1; b=42; c=3
+-d=7
++foo = 1
++bar = 2
++print(foo * bar)
 +a = 1
 +b = 42
 +c = 3
- d=7
++d = 7

- def f(x = 1, y = 2):
+-def f(x = 1, y = 2):
++
++def f(x=1, y=2):
+     return x + y


======================================================================
FAIL: test_with_docformatter (test_pep8radius.TestRadiusHg)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 265, in test_with_docformatter
    self.check(original, modified, expected, 'test_without_docformatter')
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 216, in check
    self.assert_equal(out.getvalue(), exp_diff, test_name)
  File "c:\github\pep8radius\tests\test_pep8radius.py", line 241, in assert_equal
    'expected', 'result'))
AssertionError: --- test_without_docformatter\expected
+++ test_without_docformatter\result
@@ -1,13 +1,45 @@
+--- c:\github\pep8radius\tests\temp\AAA.py\original
++++ c:\github\pep8radius\tests\temp\AAA.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
+--- c:\github\pep8radius\tests\temp\BBB.py\original
++++ c:\github\pep8radius\tests\temp\BBB.py\fixed
+@@ -1 +1 @@
+-b=1;
+\ No newline at end of file
++b = 1
+--- c:\github\pep8radius\tests\temp\CCC.py\original
++++ c:\github\pep8radius\tests\temp\CCC.py\fixed
+@@ -1 +1 @@
+-c=1
+\ No newline at end of file
++c = 1
+--- c:\github\pep8radius\tests\temp\a.py\original
++++ c:\github\pep8radius\tests\temp\a.py\fixed
+@@ -1 +1 @@
+-a=1;
+\ No newline at end of file
++a = 1
 --- c:\github\pep8radius\tests\temp\temp.py\original
 +++ c:\github\pep8radius\tests\temp\temp.py\fixed
-@@ -7,7 +7,9 @@
+@@ -5,10 +5,14 @@
+   return a + b


- foo = 1; bar = 2; print(foo * bar)
--a=1; b=42; c=3
++foo = 1
++bar = 2
++print(foo * bar)
 +a = 1
 +b = 42
 +c = 3
- d=7
++d = 7

- def f(x = 1, y = 2):
+-foo = 1; bar = 2; print(foo * bar)
+-a=1; b=42; c=3
+-d=7
+
+-def f(x = 1, y = 2):
++def f(x=1, y=2):
+     return x + y


----------------------------------------------------------------------
Ran 22 tests in 11.973s

FAILED (SKIP=4, errors=3, failures=3)

add a radius argument

seems strange not to have.

Atm fixes lines which are already touch, this would fixes likes within radius of touched lines (but default would remain 0). Simply pass line_range as min(1, start - radius) and end + radius.

Correct Indentation Marked as Wrong

I have a file with a few changes. pep8, autopep8 and flake8 are all happy:

$ pep8 voicepoll.py
$ autopep8 --diff voicepoll.py
$ flake8 voicepoll.py
$

Still, pep8radius complains:

$ pep8radius --diff devel
--- voicepoll.py
+++ voicepoll.py
…
             "question": views_voice.dict_to_messages(
-                language)[0],
+                    language)[0],

If I fix the indentation as suggested, pep8, autopep8 and flake8 start complaining, and pep8radius is still not happy:

             "question": views_voice.dict_to_messages(
-                    language)[0],
+                        language)[0],

Any idea what the problem is? First thought it might be related to #2, but then autopep8 is happy.

Thanks for the tool! I'd love to plug it into our CI to support the Boyscout Principle in our team! :)

Support for other version control

Please add requests for other VC support here:

  • git
  • hg
  • bzr (this wasn't very cleanly implemented!, see PR #53).
  • svn
    ...

I had hoped that PR #37 would act as a "guide" to adding additional VCS support...

syntax errors

Not sure what should happen with syntax errors, atm files with bad syntax are left unchanged, and no message is shown. Maybe check autopep8._find_logical doesn't raise (SyntaxError, tokenize.TokenError) if verbose?

Get precise lines

Rather than the range the diff shows, this means applying btyfi ^ n = btfyi (atm it's not).

This could be as simple as using start+3, end-3 (udiff uses 3 lines by default)?

pep8radius --yapf crashes with "AttributeError: 'tuple' object has no attribute 'splitlines'"

pep8radius 0.9.2

$ pip install --user --upgrade pep8radius
Requirement already up-to-date: pep8radius in /home/jeremysalwen/.local/lib/python2.7/site-packages
Requirement already up-to-date: autopep8>=1.0.4 in /home/jeremysalwen/.local/lib/python2.7/site-packages (from pep8radius)
Requirement already up-to-date: colorama in /home/jeremysalwen/.local/lib/python2.7/site-packages (from pep8radius)
Requirement already up-to-date: docformatter>=0.7 in /home/jeremysalwen/.local/lib/python2.7/site-packages (from pep8radius)
Requirement already up-to-date: yapf>=0.1.5 in /home/jeremysalwen/.local/lib/python2.7/site-packages (from pep8radius)
Requirement already up-to-date: pep8>=1.5.7 in /home/jeremysalwen/.local/lib/python2.7/site-packages (from autopep8>=1.0.4->pep8radius)
Requirement already up-to-date: untokenize in /home/jeremysalwen/.local/lib/python2.7/site-packages (from docformatter>=0.7->pep8radius)

$pep8radius --yapf
Traceback (most recent call last):
  File "/home/jeremysalwen/.local/bin/pep8radius", line 11, in <module>
    sys.exit(_main())
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/main.py", line 275, in _main
    return sys.exit(main(args=args, vc=vc, cwd=cwd, apply_config=True))
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/main.py", line 82, in main
    r.fix()
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/radius.py", line 95, in fix
    p_diff = self.fix_file(file_name)
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/radius.py", line 129, in fix_file
    verbose=self.verbose, cwd=self.cwd)
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/radius.py", line 192, in fix_file
    return get_diff(original, fixed, file_name) if diff else fixed
  File "/home/jeremysalwen/.local/lib/python2.7/site-packages/pep8radius/diff.py", line 37, in get_diff
    original, fixed = original.splitlines(True), fixed.splitlines(True)
AttributeError: 'tuple' object has no attribute 'splitlines'

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.