5

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

  • 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 '18 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 '18 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 '18 at 20:04
  • See docs.python.org/3/reference/lexical_analysis.html#indentation for the indentation rules of Python. – Tobias May 4 '18 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 '18 at 20:45
2

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.

0

Try this:

'(indent-tabs-mode nil)
'(org-src-preserve-indentation nil)

With that in my init file (.emacs):

  • my python source blocs are indented according to the org file and they are executable
  • when I edit a python source bloc with C-c ' it is indented starting at the first column. This code is also executable.
  • when I return with C-c ' the indentation in the org file is restored.

Before that you can ensure that your code is clean by selecting it with C-x h and then M-x untabify to replace tabs by spaces.

So I get:

* Test with :session
  #+begin_src python :session :results output :exports results
    def spam():
        try:
            a, b = 1, 2    
        except:
            a, b = 11, 12
        finally:
            a = 'voila'
        return a,b
    print(spam())
  #+end_src

  #+RESULTS:
  : ('voila', 2)
  • This does nothing in itself. You presumably copied it from your ~/.emacs but it only makes sense there within the particular context where it occurs. Please clarify. – Stefan Apr 22 at 3:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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