Search code examples
pythonpython-3.5python-idlepython-interactiveident

Improper indentation allowed in Python IDLE?


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?


Solution

  • 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.