7

mac 10.13.4 / emacs 25.3 (9.0) / org-version 9.1.12 / python 3.5.2

I am trying to understand why C-c C-c generate an IndentationError: unexpected indent when executing a simple code like the example below as a code block:

#+BEGIN_SRC python :session :exports results
  def spam():
      try:
          a, b = 1, 2    
      except:
          a, b = 11, 12
      finally:
          a = 'voila'
#+END_SRC

my init.el is as follows:

    ;; Set org mode
    (eval-after-load "org"
      '(org-babel-do-load-languages
        'org-babel-load-languages
        '((sh . t)
          (python . t)
          (emacs-lisp . t)
          (ditaa . t)
          ))
      )
    (setq org-src-tab-acts-natively t)

I have actually written this python code in a python buffer (C-c') and it works everywhere else except in the org-mode. I would really appreciate any lead

7
  • Please do not post the same question to StackOverflow and emacs.SE. Choose one site or the other. Please delete one of these posts. Thx.
    – Drew
    May 4, 2018 at 19:19
  • 1
    It is just because there is unexpected indent in the source block. It is best if you edit the source block with org-edit-src-code (bound to C-c ' within the source block). In the OrgSrc buffer you see that def spam() is indented. Pityingly, indentation is syntactically relevant for python and not allowed at that point. If you correct all indentation in the Python OrgSrc buffer you don't get that error anymore. When you are done you can leave the OrgSrc edit buffer with C-c '.
    – Tobias
    May 4, 2018 at 20:00
  • 1
    @Tyler For me the *Python* comint buffer is buried and the error is only visible in that buffer. Maybe that is the case for you too.
    – Tobias
    May 4, 2018 at 20:04
  • See docs.python.org/3/reference/lexical_analysis.html#indentation for the indentation rules of Python.
    – Tobias
    May 4, 2018 at 20:27
  • 2
    So, - removed: (setq org-src-tab-acts-natively nil) and replaced with (setq org-src-preserve-indentation t) so i remove the 2 spaces indents that come with block code. - Have edited the code with C-c', making sure all indents are correct. Same problem. However if I remove the :session in the header, it works. The issue is, that I need to work in a session
    – Cy Bu
    May 4, 2018 at 20:45

1 Answer 1

4

What's happening is that org-babel-python-evaluate-session sends an extra newline when the indentation level goes down, this causes the interpreter to close out the top-level block.

What I've done is just commented out that bit (forgive the wonky indentation, my file as received from elpa mixes tabs and spaces)

ob-python.el

(defun org-babel-python-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Python process in SESSION.
If RESULT-TYPE equals `output' then return standard output as a
string.  If RESULT-TYPE equals `value' then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
     ...
     (input-body (lambda (body)
       (dolist (line (split-string body "[\r\n]"))
             ;; Insert a blank line to end an indent
             ;; block.
             (let ((curr-indent (string-match "\\S-" line)))
               (if curr-indent
                   (progn
                 (when (< curr-indent last-indent)
                   (insert "")
                   ;(funcall send-wait) <- comment this out
                   ) ; move the closing paren to the next line
                 ...

The result is that top-level blocks are sent as one unit which may have implications if you're evaluating a large block (e.g. a god class). I haven't tested it extensively but it's been working for me.

Hope that helps.

2
  • I put the edited function in my .spacemacs file (similar to init.el) to prevent its being overwritten next time ob-python.el is automatically updated.
    – Reb.Cabin
    Nov 22, 2019 at 18:20
  • Does it helps? I tried it but it doesn't change anything for me.
    – Navidot
    May 26, 2020 at 9:14

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.