Indentation --- the secrets behind and how to recover

Created by RaiMan
Keywords:
Last updated by:
RaiMan

*** the basic Python indentation rules

--- statements like while, for, if/elif/else, try/except, def, class, ... start a block of code whose statements belong together (block starter). the statement is terminated with a colon.

example with if/else:

if a > b:
    print "a > b"
else:
    print "not a > b"

--- to tell Python, that a statement following such a block starter belongs to the block, it is indented one level with respect to the indentation level of the block starter

--- indentation is a bunch of whitespace characters preceding the statement's first non-whitespace character. It is a convention to use either tabs or spaces.

--- a block starter must be followed by at least one indented valid statement. There might be situations while developing, that you are designing your block structure, but do not yet know, what will be the exact statements in the block. In this case, you can use the statement pass, which does nothing, but assures indentation.

example:

if a > b:
    pass
else:
    print "not a > b"

In this case, you have not yet decided what to do in the True case.

--- statements belonging to one block need to have the same pattern of whitespace at the beginning of the line

--- blocks can be nested

--- the first line of a script is indentation level 0 with no preceding white space characters

--- the next statement, that does not belong any more to the current block has to match a preceding indentation (have the same whitespace pattern), which might be level 0 (reducing the indentation level is sometimes called dedentation)

--- comments generally are ignored with respect to indentation and do not count as statements

*** Sikuli's indentation support (with reference to rc3)

--- pressing tab is used, to insert one indentation level (indent whitespace inserted at cursor position)

--- pressing shift-tab is used to dedent one level (current indentation level -1)

--- tab (indent) and shift-tab (dedent) can be used with more than one line selected, which operates on all lines

--- Sikuli's standard behavior is to replace one tab with 4 spaces (can be changed in the preferences)

--- block starters are recognized automatically when pressing enter on a line:
- a missing colon is added
- a correct indentation is added at the beginning of the new line (might be a dedentation)

*** Recommendations

--- ALWAYS use tab to indent and shift-tab to dedent. NEVER enter spaces yourself to indent nor use backspace/delete to dedent.

--- NEVER mix indentation concepts in one script. This may lead to error situations that are hard to troubleshoot (see: How to recover)

--- avoid comments on the same line as a block starter. This might irritate the automatics depending on the comment's content

--- do not use single line blocks like
if a > b: print "error"; exit(1)
with rc3 there is a nasty bug with these statements, which will be fixed in the next release (fixed with r930).

--- as with all recommendations: as long as you know, what you are doing, you might ignore them ;-)

*** How to recover

--- If you get error messages, that talk about indentation, missing or expected stuff, you might have an indentation problem.

--- If it is impossible to solve it with some edits and you are just before break down, this is the total restart:
- select all lines in the script (or at least all lines in doubt)
- press shift-tab until all lines are left justified
- use tab on one line or blocks of lines one after the other until correct indentation is restored

--- Alternative: Until the Sikuli IDE will have some support for recovering indentation errors, it is a good idea to have a language aware editor at hand, that is able to show whitespace characters and might support changing spaces to tabs and vice versa.
Open the .py file contained in the .sikuli folder with this editor, examine your code and repair it.