Improper indentation allowed in Python IDLE?

1.1k Views Asked by At

While looking at an answer given by wwii, I commented on his indentation saying it was wrong. However, after running his code in my IDLE, I discovered that it ran without a hitch.

I tried a few examples, just to make sure I was getting correct results:

>>> def foo():
    return 0

>>> foo()
0
>>> def bar():
    return foo() + 5

>>> bar()
5
>>> def foobar():
    return foo() + bar()

>>> foobar()
5
>>> 

As you can see, all of them ran fine. If I try the same in a regular script, Python will raise an error before my program even runs, telling me I forget to indent a block:

enter image description here

How come this kind of indentation is allowed in the interactive IDLE, but not in regular scripts? I looked over the documentation for the IDLE, more specifically section 25.5.2.1 Automatic indentation, which was unhelpful in finding an answer.

Furthermore, the Python documenation on functions states that function bodies must be indented:

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.

(emphasis mine)

Why is this kind of indentation allowed in the IDLE, but completely shut down in a regular script? Is this on purpose? And if so, is this behavior documented somewhere?

3

There are 3 best solutions below

0
On BEST ANSWER

The >>> that you see in IDLE is just a prompt. It's sheer coincidence that this prompt happens to be four characters long and you happen to be indenting your code with four spaces too.

To see and think about how the code really works, let's remove all of the >>> prompts. For clarity, we'll remove the printed results too.

Now it looks like perfectly normal Python code:

def foo():
    return 0

foo()

def bar():
    return foo() + 5

bar()

def foobar():
    return foo() + bar()

foobar()

So IDLE is no different from any other Python interpreter, it's just the way it puts the >>> prompt on the first line only that makes it confusing. If you think about how the code would look with those four characters removed, it will all make more sense.

2
On

The code is right but the IDLE REPL is not like Python:

>>> def foo():
    return 0

IDLE prints that whereas Python:

>>> def foo():
...     return 0

See that the four spaces before return are there, but as they are aligned with the leftmost column rather than prefixed with three dots and a space, the spaces appear to not exist, if you expected the code to be indented more.

0
On

You have correct indentation in the IDLE and wrong in your script.

In the IDLE there is 4 spaces before return 0. And in your script there is not.

Your script should be looking like that:

def foo():
    return 0

def bar():
    return foo() + 5

def foobar():
    return foo() + bar()

print(foo())
print(bar())
print(foobar())

Answer to "Why IDLE indentation is correct?"

It uses the >>> mark as the beginning of the next command input. This is the standard method. It (in variations) is used everywhere.

>>> <-start of the line. Zero spaces.
<-start of the line. Zero spaces.

So next code will have wrong indentation:

>>> def foo():
return 0

Because it is an equivalent to next code written in the script file:

def foo():
return 0

But

>>> <-start of the line. Zero spaces.
    <-start of the block. Indent 4 spaces.

So next code will have correct indentation:

>>> def foo():
    return 0

Because it is an equivalent to next code written in the script file:

def foo():
    return 0