Matching indentation level according to PEP8/flake8 - python

The question is how to properly break lines according to PEP8 while using TABs.
So here is a related question How to break a line in a function definition in Python according to PEP8. But the issue is that this only works properly when the length of the definition header def dummy( is an integer multiple of the tab length.
def tes(para1=x,
--->--->para2=y)
Otherwise I end up with a new error and flake8 complains about Error E127 or E128 because the its either over- or under-indented like this:
Under-indented E128
def test(para1=x,
--->--->para2=y)
Over-indented
def te(para1=x,
--->--->para2=y)
A solution where flake8 does not complain is to do:
def test(
--->--->para1=x,
--->--->para2=y
--->--->)
However, when I am programming I don't necessarily know in advance how many parameters I'm gonna use in that test() function. So once I hit the line limit I have rearrange quite a bit.
This obviously does apply to all continuations. Does this mean the cleanest solution is to break the line as soon as possible for every line which final length cannot be said by the time of first writing, or is there another solution.
Tab and space shall not be mixed for the solution.
So now I ask myself what is the legis artis to deal with line continuations?

I'm turning my original comment into an official answer.
The PEP-0008 has a section about whether to use Tabs or Spaces, quoted below (with my emphasis):
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is
already indented with tabs.
Python 3 disallows mixing the use of tabs and spaces for indentation.
Python 2 code indented with a mixture of tabs and spaces should be
converted to using spaces exclusively.
When invoking the Python 2 command line interpreter with the -t
option, it issues warnings about code that illegally mixes tabs and
spaces. When using -tt these warnings become errors. These options are
highly recommended!
You're running into issues with tabs, and you don't say whether you're using Python2 or 3, but I'd suggest you stick to the PEP-0008 guidelines.
You should replace tab chars in the file/module with 4 spaces and use spaces exclusively when indenting.
WARNING: Be very careful if you plan to use shell commands to do this for you, as some commands can be dangerous and mangle intended tab chars within strings (i.e. not only indentation tabs) and can break other things, such as repositories -especially if the command is recursive.

PEP8 is very clear:
Tabs or Spaces?
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is already indented with tabs.
Python 3 disallows [emphasis added] mixing the use of tabs and spaces for indentation.
Reference: python.org.
So if you're writing new code and want to adhere to standards, just use spaces.

Related

pep8 "mixed spaces and tabs" error conflicts with "under-indented for visual indent"

The following function is throwing an error no matter which way I write it.
#staticmethod
def _generate_clone_spec(param1=None,
param2=None,
param3=None,
param4=False,
param5=False):
According to PEP8 the code above is an acceptable way to align parameters in a function.
But the code show above throws the following error:
Indentation contains mixed spaces and tabs
If I convert all the spaces to tabs, then it looks like this:
#staticmethod
def _generate_clone_spec(param1=None,
param2=None,
param3=None,
param4=False,
param5=False):
In the code above, the mixed spaces and tabs error disappears, but then I violate a new error: Continuation line over-indented for visual indent (E127)
From what I can tell if i write the function in the following way, it conforms to both rules, but is there another way?
#staticmethod
def _generate_clone_spec(
param1=None,
param2=None,
param3=None,
param4=False,
param5=False):
Answer
Use spaces. Then use the first example, but with only, and only spaces. Stop religiously following pep8. We don't have 80 character wide monitors anymore, nor is making code look a bit nicer such a horrible thing to do, especially when it's syntactically correct and whitespace in that case is irrelevant.
Reasoning
Disclaimer: I've come up with this, and essentially, this is my personal opinion.
I have never seen a better "rule" on deciding whether to use tabs or spaces in any kind of programming project but this:
If you format code by padding code with spaces, it objectively is the best decision to use only spaces no matter how you look at it.
Otherwise, it is whatever you prefer.
Not only does this avoid "mIxEd tAbS n sPaCeS" error in Python, it avoids confusion as to why pressing return on your keyboard makes the cursor jump erratically random amount of spaces.
If padded by spaces, and using spaces, you will always have... Spaces.
If you don't pad by spaces, and use tabs... You will always have return button jump back n spaces.
Everything else is insanity.
Forget pep8. Just be consistent in your own code, we could go on all day about this and never come up with how to indent properly.
Align the code exactly as in your first example, but ensure that all your whitespaces consist of space characters only (i.e. no tab characters).
#staticmethod
def _generate_clone_spec(param1=None,
param2=None,
param3=None,
param4=False,
param5=False):
Note: most modern code editor applications offer the setting to automatically write multiple space characters (instead of a tab character) when pressing the tab key on your keyboard. This is a reliable way to avoid ending up with mixed spaces and tabs.

PEP8 - Contradiction between E129 and E127/E128

According to the PEP standards, indents should come before binary operators. Furthermore, multiline conditions should be enclosed within parentheses to avoid using backslashes before newlines. These two conventions lead to the following situation
if (long_condition_1
or long_condition_2):
do_some_function()
This code in turn breaks E129 visually indented line with same indent as next logical line in PEP8. However, the second line must be indented exactly four spaces, as otherwise it breaks E128 or E127 for under-indented or over-indented lines.
How should one format the above so that it confirms to PEP8 standards?
This should work properly
if (long_condition_1 or
long_condition_2):
do_some_function()
The answer to this question has changed over time. Due to a change in stance from PEP8, W503 is now widely regarded to go against PEP8.
PEP8 now says it's fine to break before OR after, but to keep it consistent locally.
For newer code, Knuth-style is preferred (which I think refers to breaking before the operator).
if (
long_condition_1
or long_condition_2
or (
long_condition_3
and long_condition4
)
):
do_some_function()
if any((long_condition_1,
long_condition_2)):
do_some_function()
it's better to read when both conditions aligned too ...

Pygame Error: TabError [duplicate]

This question already has answers here:
I'm getting an IndentationError. How do I fix it?
(6 answers)
Closed last month.
The following python code throws this error message, and I can't tell why, my tabs seem to be in line:
File "test.py", line 12
pass
^
TabError: inconsistent use of tabs and spaces in indentation
class eightPuzzle(StateSpace):
StateSpace.n = 0
def __init__(self, action, gval, state, parent = None):
StateSpace.__init__(self, action, gval, parent)
self.state = state
def successors(self) :
pass
You cannot mix tabs and spaces, according the PEP8 styleguide:
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is already indented with tabs.
Python 3 disallows mixing the use of tabs and spaces for indentation.
Python 2 code indented with a mixture of tabs and spaces should be converted to using spaces exclusively.
When invoking the Python 2 command line interpreter with the -t option, it issues warnings about code that illegally mixes tabs and spaces. When using -tt these warnings become errors. These options are highly recommended!
Using Visual Studio 2019
I was using tabs but the editor was inserting spaces and it would result in errors.
To avoid getting the spaces and tabs mixed up , set your preferences
Go to Edit->Advanced->Set Leading Whitespace->Tabs (or Whitespaces)
After I set it to Tabs, my tabs stop being represented as spaces and it worked fine thereafter
For linux nano users:
if your code includes 4 spaces instead of a tab, you should keep using 4 spaces or change all of them to a tab. If you use mixed it gives an error.
open your code in a text editor, highlight all of it (ctr+a) and go to format and select either "Tabify region" or "Untabify region". It'll just make all the indents have the same format.
not using the backspace also is important (especially in the Leafpad editor). If you want to decrease indent, use only Alt_key + TAB.
This should be done when you delete a line in a Python code.

Indentation error when using subprocess in Python 2.7

I have tried using a function defined using subprocess but I get an indentation error depending on where I put it on my code. A minimal example of my code is:
import subprocess
def runsafe(job,args):
jobs=[job];
for arg in args:
jobs.append(arg)
proc=subprocess.Popen(jobs,stdout=subprocess.PIPE)
return proc.stdout.readlines()
if __name__=="__main__":
runsafe("mkdir","Try")
A=0
B=7
This works and gives me the correct input (this code just creates three new folders called T, r, y where it's executed) but the indentation seems weird to me. A and B are just two constants that I will use later in the code.
For me the most natural would be to write:
import subprocess
def runsafe(job,args):
jobs=[job];
for arg in args:
jobs.append(arg)
proc=subprocess.Popen(jobs,stdout=subprocess.PIPE)
return proc.stdout.readlines()
if __name__=="__main__":
runsafe("mkdir","Try")
A=0
B=7
If I do this I just get:
IndentationError: 'unexpected indent'
Why is it necessary to indent (again) the line where I call runsafe? Shouldn't it work if I use it like in the second example?
You are very likely mixing tabs and spaces in your indentation. With Python 2 this often leads to weird behavior because mixing tabs and spaces actually works. But it doesn’t work in the way you would maybe expect: For Python 2, a tab is equivalent to 8 spaces. So for evaluating the indentation level, every tab is replaced by 8 spaces.
So when you have an indentation like this (where a . is a space, and ---→ is a tab):
def test():
........pass
---→pass
then it might look weird but it is valid since everything is indented using 8 spaces.
So you should make sure that you are using consistent indentation (it doesn’t matter whether it’s spaces or tabs—as long as it’s consistent).
Btw.: In Python 3 this is no longer allowed and will throw a syntax error (actually a TabError) with an actually helpful message: TabError: inconsistent use of tabs and spaces in indentation.
Your code mixes tabs and spaces for indentation. While this was possible and allowed in Python 2, Python 2 assumes tab size of 8 spaces. If you had an editor that has a setting to turn on visible whitespace, you'd see that one of the lines is indented with 8 spaces, and the other 2 with a single TAB:
if __name__=="__main__":
........runsafe("mkdir","Try")
--->A=0
--->B=7
That is, in your editor you had the tab display default to 4 spaces, while Python 2 expects 8 spaces to match a TAB.
As the tab size cannot be agreed on, yet in Python the indentation is significant, use of tabs for indentation is not considered best practice in either Python 2 or Python 3.
Tabs should be used solely to remain consistent with code that is already indented with tabs:
And mixing tabs and spaces in a way that makes indentation depend on the worth of a tab expressed in spaces is very wrong.
In Python 2 the tab size is 8, so indentation of TAB counts the same as 8 spaces or single TAB. Unfortunately there are many code editors that do not realize this, and instead use a different tab size for Python 2 code. In Python 3 OTOH, a TAB is only matched by another TAB. A good Python 3 editor would then mark inconsistent use of tabs in indent as syntax errors.
Thus the only consistent way of using tabs is using only tabs for indentation. In Python 2 there is a switch for that; you can start your Python interpreter with option -tt, or put it on the #! line after the python command, which will cause Python 2 to throw an error if it ever meets a line which makes the indent depend on tab size.
However, if you're writing new code, please be advised that the Python community almost uniformly follows the PEP 8 coding conventions: indentations are 4 spaces, and no tabs are used. In my experience, it is only the ever so odd legacy project that does not obey this guideline. Nearly all open-source projects these days that have coding conventions also require 4-space indentation, as well as other aspects of PEP 8.

Understanding Python interpreter -t (-tt) option

I'm trying to figure out what the options -t and -tt do.
From the doc:
Issue a warning when a source file mixes tabs and spaces for indentation in a way that makes it depend on the worth of a tab expressed in spaces. Issue an error when the option is given twice (-tt).
I'm not getting it, in particular the bolded sentence, what does it mean? A tab is a tab ('\t') a space is a space (' ') and in ascii table they also have 2 different codes.
I'll ty to make an example to explain better myself. I code:
if True:
print('hello') # here a tab that my editor represents with 4 spaces
print('world') # here just used 4 spaces
Now this code, I tried, doesn't work neither in Python3 nor in Python2, so what does -t do?
Could you give me a clarification?
When used as indentation, tabs must be interpreted as equivalent to a number of spaces. How many spaces depends on how you configured your editor, and how many spaces preceded the tab on the same line. That's because tabs represent a jump to the next tabstop. If you used 2 spaces plus a tab, you have signalled a jump to column 8, as if you inserted 6 spaces.
In addition, some people set their tabstops to be the equivalent of 4 spaces, others set it to be the same as 8 spaces. These people then use tabs in indentation in different ways too. You could use 4 spaces for one indentation level, then use tabs at 8 spaces for the next, then use a tab plus 4 spaces, etc. Or you could use tabs for all indentation levels, having set the tab size to represent 4 spaces.
Python needs to handle mixing of tabs and spaces, and then hope that you used it consistently; e.g. you didn't use 4 spaces first, then a tab to indent to what you thought was an indentation equivalent to 12 spaces. Python can easily get this wrong when you are inconsistent.
The -t and -tt options point out where you may have gotten this wrong by doing more rigorous and thorough testing of all lines.
The ease by which you can produce confusing results, between various tab sizes and mixing tabs and spaces, is the reason why the Python Style Guide (PEP 8) strongly recommends that you use spaces only:
Spaces are the preferred indentation method.
Tabs should be used solely to remain consistent with code that is already indented with tabs.
In Python 3, mixing tabs and spaces for indentation is now an error.
To be precise: Python starts out assuming you used 8 spaces for a tab. See the Indentation documentation, part of the Lexical Analysis specification:
First, tabs are replaced (from left to right) by one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix). The total number of spaces preceding the first non-blank character then determines the line’s indentation. Indentation cannot be split over multiple physical lines using backslashes; the whitespace up to the first backslash determines the indentation.
Python 2 also looks for Emacs and VI-style configuration comments; if the tokenizer finds a comment with tab-width:, :tabstop=, :ts= or set tabsize= in it, followed by digits, like:
# -*- tab-width: 4 -*- (emacs)
# :tabstop=4 (vi)
or similar variants, then Python sets the tabsize from that. This support was removed from Python 3.
If you then mix tabs and spaces that may be inconsistent, and use -t, the text <filename>: inconsistent use of tabs and spaces in indentation is written to sys.stderr once for that file. If you used -tt, a TabError exception is raised instead.
The error will be thrown when a source file depends on tabs expanding to a certain number of spaces.
For example, a file like this would be problematic:
def function():
print 'hello'
\tprint 'goodbye'
The above code would work if a tab was 4 spaces, but would fail if it was anything else (except 0, which is nonsensical).
The -t option attempts to highlight such issues.

Categories