4

I had been successfully using python code blocks with the :session header argument when I noticed that upon export no result was given.

I then simplified my example to the following two:

    #+begin_src python :python ~/anaconda3/bin/python3 :session :results output
    import random
    if random.randint(0,10) % 2 == 0:
        ret = "even"
    else:
        ret = "odd"
    print(ret)
    #+end_src

    #+RESULTS:
    #+name: session_init
    #+BEGIN_SRC python :results value :session example
    str='Hello, World'
    str
    #+END_SRC

    #+RESULTS: session_init

but found that neither yielded any results.

I'm quiet confused about this since it had been working until suddenly it wasn't.

I tried removing cache, tmp files and rebuilding my emacs packages (I'm using doom emacs) but all to no avail

I'm using org-version 9.5 and my emacs version is as such

GNU Emacs 28.0.50
Copyright (C) 2021 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

If anyone can help that'd be much appreciated.

1 Answers1

6

The python implementation in Org babel has a couple of long-standing problems:

  • If you specify :results value, then the body is implicitly wrapped in a function and you have to add a return statement to indicate the value of the block - but only if you are not using a session.

  • If you specify :`:results value but you use a session, you have to wrap the body in your own function and call the function as the last thing of the block.

That makes it awkward to switch a block from session to no-session (and vice versa) and from :results output to :results value (and vice versa): you have to modify the code to switch.

In addition to that, when using sessions and an error occurs in a code block, then subsequent evaluations of the same or a different code block can fail, not because of the code, but because the session output got out of sync and Org babel can no longer parse it. When that happens, I kill the session buffer and start anew; and for that reason, I always name my sessions.

I deal with these problems in a couple of different ways: for a session, I use :results output exclusively and add print(...) statements in order to produce the output I want.

For non-session evaluation, I usually use :results value and I try to remember to add a return statement with the result that the block is supposed to produce.


EDIT: For your specific case, you seem to need a python interpreter from a non-standard place. In order not to have to specify it for every code block, I would add the header as a file property:

#+PROPERTY: header-args:python :python ~/anaconda3/bin/python3

(Don't forget to refresh the buffer by pressing C-c C-c on the added line above).


In accordance with the guidelines above, here's how I would write your blocks:

#+begin_src python :session foo :results output
    import random
    if random.randint(0,10) % 2 == 0:
        ret = "even"
    else:
        ret = "odd"
    print(ret)
#+end_src

#+RESULTS:
: odd


#+name: session_output
#+BEGIN_SRC python :results output :session foo
  str='Hello, World'
  print(str)
#+END_SRC

#+RESULTS: session_output
: Hello, World

If you really want to combine a session with :results value, use something like this, where you define a function and call it - that lets Org babel figure out what the result should be:

#+name: session_value
#+BEGIN_SRC python :results value :session foo
  def hello():
    str='Hello, World'
    return str

  hello()
#+END_SRC

and finally for :results value outside a session, use something like this:

#+name: non-session_value
#+BEGIN_SRC python :results value
  str='Hello, World'
  return str
#+END_SRC

#+RESULTS: non-session_value
: Hello, World

Remember, in this last case, the body of the code block is implicitly wrapped in a function, the function is called and the return value of the function is the result of the block.

NickD
  • 27,023
  • 3
  • 23
  • 42
  • Thanks for the answer. This all looks like it should be correct but non of your session code blocks produce a result for me. Is there anything further I can debug? I don't get any errors and if I change the code block to not use `:session` it works fine. – Reginald Marr Apr 22 '21 at 12:56
  • All I can think of atm is that you seem to require a python interpreter coming from a non-standard place. I didn't include that in my original answer but I've edited to add a convenient way to specify that. Try it and see if that solves the problem. – NickD Apr 22 '21 at 14:08