autopep8 converts this code
sum_of_two_numbers = first \
+ second
to this
sum_of_two_numbers = first \
+ second
Is it a bug? If so, is it a bug in pycodestyle or autopep8? Are there any error codes I can ignore to prevent this behavior? If I ignore E127 and E128 it also stops indenting all other cases.
I know that if I use brackets instead of backslash it will work correctly, however, there is an existing repository that uses backslashes in some places which I do not want to change.
UPD. Adding another example from pep8 (https://www.python.org/dev/peps/pep-0008/#maximum-line-length)
Backslashes may still be appropriate at times. For example, long,
multiple with-statements cannot use implicit continuation, so
backslashes are acceptable:
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read()) ```
autopep8 does not align this example correctly, too.
To my knowledge, you cannot disable just this feature without disabling other auto-indenting. If you are running autopep8 that implies that you are trying to follow pep8 guidelines, in the case of the example you should really be using implied continuation (no backslash, '+' on the previous line, 4 space indent.) If you are using autopep8 on a project you have to be willing to let autopep8 format the project for you. I'm not sure what the attachment to backslashes is here, but it's probably not the nicest way to format what you're doing.
Related
So here is an example of a multiline string in vscode/python:
Cursor is after the p , and then you press enter, and end up like this:
i.e. the string ends up indented, which seems what you almost never want - why have an arbitratly amount of whitespace on the next line of this string ?
Is there any way change this in vscode, i.e. for multiline strings, it should end up with this:
I think this problem is related to different coding styles of different people.
For example,
def example(x):
if x:
a = '''
This is help
'''
def example(x):
if x:
a = '''This is help
'''
The automatic indenting of vscode line breaks is based on code blocks. If you want Vscode can identify multiline string, I think it would be better to submit future request in github. I've submitted this issue for you.
I am not 100% sure if what OP meant is just to refer to the indentation in the editor (namely, VSC) or if, by this:
i.e. the string ends up indented, which seems what you almost never want - why have an arbitrary amount of white space on the next line of this string?
...they also meant to refer to the actual output of the multi-line string,
(or also, just in case anybody else finds this post looking for a way to avoid this affecting the actual output of the multi-line string), I'd like to add as a complementary answer (cannot comment yet) that this was already beautifully answered here.
If that's the case and you're reading this for that reason, in short, all you want is to import the standard lib 'inspect' and post-process your string with it, using the cleandoc method.
Without breaking the indentation in your IDE, this method makes sure to give you the string output you actually expected:
All leading whitespace is removed from the first line. Any leading whitespace that can be uniformly removed from the second line onwards is removed. Empty lines at the beginning and end are subsequently removed. Also, all tabs are expanded to spaces.
(From the docs link above)
Hope that helps anyone.
In Python 3.8, the following:
import codecs
codecs.decode("hello\\,world", "unicode_escape")
...produces a deprecation warning:
<ipython-input-7-28f185d30178>:1: DeprecationWarning: invalid escape sequence '\,'
codecs.decode("hello\\,", "unicode_escape", errors="strict")
Is this going to become an error in a future version of Python? Where is the reference for this?
If No, is there a way to not display this warning, if Yes, what can I use instead?
Edit: I am (obviously) not interested in fixing this for a string I would have written literally in my Python script. This is purely an example, in my use case strings come from external files, I cannot change them, and some contains invalid escape sequences such as this.
The problem is that you've got two layers of de-escaping occurring here. The first one is the regular string literal escaping, converting "hello\\,world" to a string with raw characters of hello\,world. Then codecs.decode tries to decode it with unicode_escape, which sees it as an attempt to escape , with \, which is an invalid escape.
The fix for your code as written is to use a raw string so the first level of escaping doesn't happen:
codecs.decode(r"hello\\,world", "unicode_escape")
# ^ Now it's a raw string, and both backslashes are in fact backslashes
If your data comes from elsewhere with invalid escapes, you can suppress the warning for now (see the warnings module for details), but it will eventually cause an exception in a future version of Python, so the long term solution is "Don't provide invalid data". Sorry that's not super-helpful.
The reason you get this warning is that, historically, Python has been kind of lax about spurious escapes. So if you wrote, say, a Windows path of "C:\yes" it said "hey, \y doesn't mean anything, so we'll just assume they wanted a literal backslash", while an equivalent path of "C:\no" saw \n and thought "Yup, they want a newline there".
This taught bad habits (not using raw strings when you should, because it usually worked without them) and created confusion when those habits bit you (why isn't it working this time!?!). So in the future, escapes like \y will be treated as errors, so that you end up writing r'C:\yes' and are used to doing so so you don't get bit by r'C:\no'. The warning is reminding you that this is bad code, and will eventually stop working (for good reason; as your own comment notes, you're okay with it ending up with either no backslashes or two backslashes, starting with just one, which is an insane set of options to accept without knowing the single, correct, desired result).
Alternative solution
If your goal is to "fix" bad strings, the best solution is probably to just write your own simple stripping regex, e.g.:
import re
bad_escape_re = re.compile(r'\\(?=[^\n\\\'"abfnrtv0-7xNuU])')
and then use it to strip unrecognized escapes a la:
good_string = bad_escape_re.sub('', bad_string)
which when run like so:
bad_escape_re.sub('', r'\a\b\c\d\e\f\g\,\.\n\t\x12')
produces a string with the repr '\\a\\bcde\\fg,.\\n\\t\\x12'. Note that's it's not perfect, and if you need it to validate the extended escapes to distinguish valid uses from invalid ones (\[0-7], \x, \N, \u and \U), it gets more complicated, but those are also cases where it's invariably heuristic and there is no good solution; without a human to interpret, \xab is legal and \xag is not, but it's entirely likely the former wasn't intended as an escape either.
I'm trying to get autopep8 work to properly indent Python code with 2 spaces instead of 4. I'm using VS Code with Python extension which uses autopep8 for formatting. I found here that autopep8 can be configured to use 2 spaces by
"python.formatting.autopep8Args": ["--indent-size=2"]
But it does not work for me.
My situation is like this. When I press enter, it correctly starts the next line with the same indentation as the previous line. Press enter after an open parenthesis, it correctly starts the new line with 2 more spaces. But when I paste or save (I have "editor.formatOnPaste" and "editor.formatOnSave" set to true), the annoying thing happened: all the 2-space indentation inside the parentheses became 4 (other 2-space indentation are unaffected). Why is it doing this and how can I make it 2 spaces everywhere?
====EDIT====
I found out that the pylint error Wrong hanging indentation (remove 2 spaces). [bad-continuation]. It's because my pylintrc has indent-after-paren=2. I'm wondering if autopep8 or other Python formatter can set this property?
I also had to include this in my array in settings.json, similar to yours.
"--ignore E121"
According to https://pypi.org/project/autopep8/, this setting ensures your indents are a multiple of 4. By not enforcing that, the configured tab size in VSCode is used.
E121 - Fix indentation to be a multiple of four.
That being said, your indentation is still "acceptable" according to pep8, so it actually will not change it to the 4 spaces you are expecting in your parens. I had to outdent mine one level, then when it ran again, it didn't change it.
Unfortunately this is actually just a workaround and it actually negatively affects other indention rules...
You can see in the code for pep8 that they hardcode the default tab size to be the "python way" (4 spaces) in:
https://github.com/hhatto/autopep8/blob/120537a051d7f3cbbb5c4ede19b9e515156bd3d1/autopep8.py#L104
That makes it look like the hanging indent is just not respecting the --indent-size option...
Adding --indent-size=2 --ignore=E121 worked for me.
had the same issue, here is the solution:
Navigate to library directory of your environment
Open autopep8.py
Search for "DEFAULT_INDENT_SIZE" and change it to 2
using re.escape() on this directory:
C:\Users\admin\code
Should theoratically return this, right?
C:\\Users\\admin\\code
However, what I actually get is this:
C\:\\Users\\admin\\code
Notice the backslash immediately after C. This makes the string unusable, and trying to use directory.replace('\', '') just bugs out Python because it can't deal with a single backslash string, and treats everything after it as string.
Any ideas?
Update
This was a dumb question :p
No it should not. It's help says "Escape all the characters in pattern except ASCII letters, numbers and '_'"
What you are reporting you are getting is after calling the print function on the resulting string. In console, if you type directory and press enter, it would give something like: C\\:\\\\Users\\\\admin\\\\code. When using directory.replace('\\','') it would replace all backslashes. For example: directory.replace('\\','x') gives Cx:xxUsersxxadminxxcode. What might work in this case is replacing both the backslash and colon with ':' i.e. directory.replace('\\:',':'). This will work.
However, I will suggest doing something else. A neat way to work with Windows directories in Python is to use forward slash. Python and the OS will work out a way to understand your paths with forward slashes. Further, if you aren't using absolute paths, as far as the paths are concerned, your code will be portable to Unix-style OSes.
It also seems to me that you are calling re.escape unnecessarily. If the printing the directory is giving you C:\Users\admin\code then it's a perfectly fine directory to use already. And you don't need to escape it. It's already done. If it wasn't escaped print('C:\Users\admin\code') would give something like C:\Usersdmin\code since \a has special meaning (beep).
I am writing in python 3.5.1 and I am a programming novice.
I use gedit with a pep8 and pyflakes plugins showing style mistakes according to the python style guide. I do not know whether to follow the style recommendation to the letter or not.
I have, however, three recurring style flaws indicated by E501: line too long (80 > 79 characters), E502: the backslash is redundant between brackets and E128/E127/...: continuation line under-indented for visual indent. Screenshots below.
My two questions are:
How can I adequately make a line break in python in order to avoid E501 and the subsequent style errors E502 and E127/128?
Is it helpful to follow the style guide pep8 to the letter, especially with publication in mind? What do advanced python programmers say?
E501:
E502:
E127/128...:
"How can I adequately make a line break in python in order to avoid E501 and the subsequent style errors E502 and E127/128?"
progress = Utils.ProgressMeter('Source strings separated by white '
'space are automatically concatenated by the '
'interpreter and parenthesis are the natural syntax '
'for line continuation. Remember to use trailing '
'spaces.')
Since error E502 is already inside parentheses, the backslash is redundant. Did you try eliminating it?