1

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!

5
  • 1
    An odd thing is that if :results silent is changed to :results output or :results value, the indentation error is not thrown.
    – Win
    Commented Dec 23, 2018 at 2:33
  • @Win I just tested it here and it does work. Unfortunately I have no idea how the code is sent to the python interpreter under the hood. Commented Dec 24, 2018 at 13:28
  • I just tried your code block and it seems that if you remove the 2 spaces at the beginning of each code line it works without throwing an indentation error, with :results output or with :results silent.
    – Lgen
    Commented Jan 22, 2019 at 14:20
  • @Lgen even by removing the 2 spaces at the beginning (keeping the for loop in and :results silent) I still get the error. Commented Feb 13, 2019 at 21:52
  • Do you have some other errors/messages in pysession buffer? Seems that the variable _ is not generated, and in your case is shadowed by the IndentationError: - in my configuration, when using :results silent I get the message NameError: '_' is not defined.
    – Ian
    Commented Feb 15, 2019 at 14:22

3 Answers 3

0

For best results and features edit code blocks by running in a dedicated buffer using org-edit-special.

With pointer in the code block type ctrl-c' org-edit-src-code that will open in your case a python buffer with your hooks, the configured indentations and all.

Use ctrl-c' to return to the org file.

from gnu.org:

C-c ' for editing the current code block. It opens a new major-mode edit buffer containing the body of the ‘src’ code block, ready for any edits. C-c ' again to close the buffer and return to the Org buffer.

C-x C-s saves the buffer and updates the contents of the Org buffer.

Set org-edit-src-auto-save-idle-delay to save the base buffer after a certain idle delay time.

Set org-edit-src-turn-on-auto-save to auto-save this buffer into a separate file using auto-save-mode.

C-c ' to close the major-mode buffer and return back to the Org buffer.

While editing the source code in the major-mode, the org-src-mode minor mode remains active. It provides these customization variables as described below. For even more variables, look in the customization group org-edit-structure.

For more details and how to configure specifically editing-source-code

1
  • Thanks for your reply, but unfortunately that's what I already do to edit source-code blocks and the problem still happens. I also tried changing the default indentation but it also leads to the same problem. Commented Dec 18, 2018 at 21:10
0

I cannot reproduce your error. On my system, the answer is nil. But if you change the header to :results output :session pyssesion the result of evaluating is OK. See this for further explanations.

enter image description here

Of coarse, some other configurations/settings may be needed if the error will be the same.

2
  • The issue is that I do not want results on my org file. For example, if I just define the foo function without the print command, then I still get the same error. Commented Dec 21, 2018 at 17:02
  • :results silent is working for me. To be clear, I'm using the same block as this answer with :results silent. I'm on emacs 27.1 org version 9.4.4 Commented Apr 5, 2021 at 22:46
0

I'm not 100% that the issue you have is the same one I did, but I solved it with:

(setq org-src-preserve-indentation t)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.