0

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?

Community
  • 1
  • 1
Christian Dean
  • 22,138
  • 7
  • 54
  • 87
  • I'm guessing that the prompt, ```>>> ```, is stripped from the first line before processsing. It is annoying though. – wwii Dec 03 '16 at 04:52
  • @wwii Sure is. But its seems more confusing than annoying. – Christian Dean Dec 03 '16 at 04:53
  • 1
    I've been exposed as an idle coder. – wwii Dec 03 '16 at 04:55
  • 1
    Your initial confusion is why IDLE uses 8-space tab indents in shell -- so followup lines look physically indented. I hope someday to put the '>>> ' prompt in a distinct margin, along with other notations. Indents would then be the same space indent as in the editor, and there would be an option to save or copy code without the prompt, so it would be ready to run from an editor window. – Terry Jan Reedy Dec 03 '16 at 18:30

3 Answers3

2

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.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • _"The code is right but the IDLE REPL is not like Python"_ - Sorry, I'm not quite following on that sentence you. Could you explain a bit more? – Christian Dean Dec 03 '16 at 04:54
  • @leaf The standard REPL is line oriented: you submits physical lines to Python and the history mechanism recalls physical lines. IDLE's Shell is statement oriented: you submit complete statements to Python (and can edit entire multiline statements. The history mechanism recalls complete statements. – Terry Jan Reedy Dec 03 '16 at 18:23
1

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
KromviellBlack
  • 908
  • 6
  • 10
1

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.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75