I am using orgmode and Babel to run Python source code blocks.
I noticed that if I define a function that returns a value, and if this function has a for loop inside it, then evaluating it with Babel leads to an IdentationError: unexpected indent
.
For example, in org-mode write the following:
#+BEGIN_SRC python :results silent :session pysession
def foo():
for _ in range(1):
pass
return 1
print(foo())
#+END_SRC
Then calling C-c C-c
sends the code to the pysession
buffer running the Python session, and it results in the error IdentationError: unexpected indent
.
However, if we remove the for loop from the function definition, then things just work (prints 1):
#+BEGIN_SRC python :results silent :session pysession
def foo():
return 1
print(foo())
#+END_SRC
Question: How to fix this behavior so that I can define functions with loops and have them work with babel?
Edit 1: The print
can be removed from the code and the error still arises. The :results silent
option is necessary since I do not want results in my org-file.
Edit 2: I noticed that when :results silent
is selected and C-c C-c
, it appears that Babel is sending the code line by line to the session, but when the line that contains the pass
is send, Babel for some reason sends another RET
, which makes the python REPL finish defining the function foo
without any return statement. Then, when the line containing return 1
is sent, it is evaluated out of the scope of the function and causes the indentation error!!!
At this doc page it says:
Session mode in python is slightly different from non-session mode ... blank lines are special: they indicate the end of an indented block
But in this case it is not working at all: there is no line between pass
and return 1
, but Babel is treating as if there was, since it is thinking the indented block is ended after pass
.
It seems there is some bug with the backend.
When we use :results output
, Babel actually saves the contents of the code block as is in a temporary file. It then reads the file and evaluates it in Python with exec
. Since Python gets the entire code at once it works.
Thanks for helping!
:results silent
is changed to:results output
or:results value
, the indentation error is not thrown.:results output
or with:results silent
.pysession
buffer? Seems that the variable_
is not generated, and in your case is shadowed by theIndentationError:
- in my configuration, when using:results silent
I get the messageNameError: '_' is not defined
.