This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: TabError behavior doesn't match documentation
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Mikko Rantalainen, abacabadabacaba, facundobatista, martin.panter, r.david.murray, serhiy.storchaka
Priority: low Keywords:

Created on 2015-05-21 21:45 by abacabadabacaba, last changed 2022-04-11 14:58 by admin.

Messages (15)
msg243794 - (view) Author: Evgeny Kapun (abacabadabacaba) Date: 2015-05-21 21:45
In the documentation, it is said:

    Indentation is rejected as inconsistent if a source file mixes tabs and spaces in a way that makes the meaning dependent on the worth of a tab in spaces; a TabError is raised in that case.

But that's not true. For example, Python thinks that these two indentations are "consistent":

<tab><8 spaces>
<8 spaces><tab>

However, their width would be different for any tab width except 1, 2, 4, and 8.

Actually, it's not easy to check that indentation is "consistent" as it is defined currently, so I think that it is the documentation that should be changed. So, I think that the paragraph that I quoted above should be changed to match the actual behavior.
msg243906 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2015-05-23 10:16
I would go further and forbid tabs after spaces entirely. Tabs
used for indentation with spaces following for formatting are
okay (though unusual in Python).
msg243907 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2015-05-23 10:26
From https://www.python.org/dev/peps/pep-0008/

<quote>
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 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!
</quote>
msg243908 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2015-05-23 10:40
Then pep-008 is wrong, too, since the implementation *does* allow
Evgeny's example.

The current implementation just checks if the same INDENT/DEDENT
tokens are generated for tab widths 1 and 8.
msg243991 - (view) Author: Evgeny Kapun (abacabadabacaba) Date: 2015-05-24 16:41
Prohibiting tabs after spaces is not enough. For example, Python rejects this code:

    if 1:
    <space>if 1:
    <tab>pass

because its indentation is invalid if tab width is 1. However, it accepts this code:

    if 1:
    <tab>if 1:
    <10 spaces>pass

despite its indentation being invalid if tab width is 10 or more.
msg243995 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-05-24 18:27
We should probably just introduce a new error mode (-ttt?) that makes it an error to use tabs at all for semantic indentation.
msg244007 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-05-24 23:27
I would be in favour of making the existing indentation behaviour more strict by default, or at least outputting some sort of warning for Evgeny’s examples. I.e. no reason to supply a special -ttt option.

But prohibiting tabs entirely might not go down well. I never use tabs in my own code, but I wouldn’t want to convert other people’s code to spaces just to run it in a future Python release, especially when the tab usage is universal.

I don’t exactly know Python’s rules for intentation, but my model for “consistent indentation” would work something like:

* Remember the exact sequence of spaces and tabs for each level of indentation
* Ignore blank and commented lines, even if their indentation is inconsistent
* If a line begins with the highest level of indentation, but continues with more spaces or tabs, it starts a new indentation level
* If a line’s indentation exactly matches any of the saved sequences, it jumps back to that level (or stays at the highest level)
* Otherwise, the indentation is inconsistent, and it should be an error or warning

Yet another option could be to say indentation is allowed to be only tabs or only spaces, and the use of tabs or spaces must match the rest of the file, or at least the rest of the indented block. But I still prefer my model above :)
msg244009 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2015-05-24 23:37
So when does Python 3 generate this "TabError: inconsistent use of tabs and spaces in indentation" and when doesn't it?
msg244097 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2015-05-26 11:10
> Prohibiting tabs after spaces is not enough.

No, I really meant that once a new block is started with tabs,
all following nested blocks must use tabs for indentation.

The only place where spaces would be allowed is for aligment
in logical lines that extend over multiple physical lines.


Basically, just tab-oblivious formatting (which is generally
nice for other languages).
msg306416 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-11-17 09:23
My model is the same as the Martin's one. I know how to implement this, but the code isn't simple. I'm going to do this after fixing other bugs in the tokenizer.
msg306417 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-11-17 09:30
I'm now in the camp of forbidding tabs.  When I wrote my own parser a couple of years ago, I tested it on a huge body of Python files that were present on my system. Tabs always looked accidental.

Is there any *known* code base that deliberately uses tabs?
msg306421 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-11-17 09:42
Lets not continue a holy war here. I'm in the camp of tab-indenters.
msg306422 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-11-17 09:51
python-dev is becoming insufferable.
msg354840 - (view) Author: Mikko Rantalainen (Mikko Rantalainen) Date: 2019-10-17 11:07
As I wrote in duplicate issue38496 (with emphasis added):

I'd prefer python3 to require that *all whitespace* at the start of the all the lines is *tabs for the whole file*, or *spaces for the whole file*. And first indented line sets the preference for the whole file.

That way python3 would really disallow mixing spaces and tabs. And the people who like to use tabs for indent (e.g. me) are happy because they can adjust the amount of indent up to their own taste. I'm in the Allman-8 camp for all languages I use.
msg388639 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2021-03-13 23:58
Found this after seeing (once again) somebody asking for help in Python Argentina after having a file mixing tabs and spaces.

This tends to catch new people.

I'm +1 to just raise an error if the file mixes tabs and spaces for indentation. I've never seen a real usage case where it was not an accident, even if the mix was in different blocks, so it actually worked "fine" (and even in those cases, then the user copies lines around, and the program starts to behave weirdly).
History
Date User Action Args
2022-04-11 14:58:17adminsetgithub: 68448
2021-03-13 23:58:50facundobatistasetnosy: + facundobatista
messages: + msg388639
2019-10-18 11:08:16vstinnersetnosy: - vstinner
2019-10-17 11:07:56Mikko Rantalainensetnosy: + Mikko Rantalainen
messages: + msg354840
2019-10-16 11:32:00eric.smithlinkissue38496 superseder
2017-11-17 14:34:34vstinnersetnosy: + vstinner
2017-11-17 12:20:29BreamoreBoysetnosy: - BreamoreBoy
2017-11-17 09:53:01skrahsetnosy: - skrah
2017-11-17 09:51:20skrahsetnosy: r.david.murray, skrah, abacabadabacaba, BreamoreBoy, martin.panter, serhiy.storchaka
messages: + msg306422
2017-11-17 09:42:44serhiy.storchakasetmessages: + msg306421
2017-11-17 09:30:52skrahsetmessages: + msg306417
2017-11-17 09:23:36serhiy.storchakasetpriority: normal -> low
versions: + Python 3.7, - Python 3.4
nosy: + serhiy.storchaka

messages: + msg306416
2017-11-17 09:14:38skrahlinkissue32053 superseder
2015-05-26 11:10:51skrahsetmessages: + msg244097
2015-05-24 23:37:51BreamoreBoysetmessages: + msg244009
2015-05-24 23:27:49martin.pantersetnosy: + martin.panter
messages: + msg244007
2015-05-24 18:27:10r.david.murraysetnosy: + r.david.murray
messages: + msg243995
2015-05-24 16:41:34abacabadabacabasetmessages: + msg243991
2015-05-23 10:40:08skrahsetmessages: + msg243908
2015-05-23 10:26:04BreamoreBoysetnosy: + BreamoreBoy
messages: + msg243907
2015-05-23 10:16:19skrahsetnosy: + skrah
messages: + msg243906
2015-05-21 21:45:51abacabadabacabacreate