1

This worked seamlessly, but at some point, I lost the ability to pass string-type variable values between code blocks in Org Babel. Let’s take the following example:

#+begin_src python :session *PY* :exports code :results output
from sympy import *
x = Symbol('x')
f = x+x/2
a = 7

print(f)
print(latex(f))
print(a)
#+end_src

#+RESULTS:
: 3*x/2
: \frac{3 x}{2}
: 7

#+begin_src python :session *PY* :exports code :results output
print(latex(f))
print(f)
print(a)
#+end_src

#+RESULTS:
: \mathtt{\text{<\_io.TextIOWrapper name='/tmp/babel-KrI2mU/python-FVFmyv' mode='r' encoding='UTF-8'>}}
: <_io.TextIOWrapper name='/tmp/babel-KrI2mU/python-FVFmyv' mode='r' encoding='UTF-8'>
: 7

src_python[:session *PY* :results output]{print(x+x)} {{{results(=2*x=)}}}
src_python[:session *PY* :results output]{print(f)} {{{results(=<_io.TextIOWrapper name='/tmp/babel-KrI2mU/python-eN4EFB' mode='r' encoding='UTF-8'>=)}}}

It seems something must have changed in org-babel and now it's trying to read temporary files as strings. What should I do to localize the problem and restore the functionality? Software version: Emacs 30.1, org-mode 9.7.11

3
  • It works here if I change f to e: it seems f has a special meaning for something (although I don't know what). Commented Jun 12 at 0:22
  • Indeed! I don't have much time to test it thoroughly but it seems everything but f works fine. Hmmm... maybe it has something to do with python f-strings? The variable named f could be misinterpreted at some point/ treated as f-string prefix or something...? Commented Jun 12 at 7:19
  • 3
    I’m voting to close this question because the problem was caused by a bug in Org mode that has since been fixed. Commented Jul 21 at 1:33

1 Answer 1

1

As noted, the use of f in the code is triggering the problem (any identifier other than f works fine).

The problem is caused by a bug in org-babel-python-evaluate-session which saves the code in a temporary file and then evaluates it by constructing a string and sending it to the python interpreter:

    ...
    (let ((body (format "\
with open('%s') as f:
    exec(compile(f.read(), f.name, 'exec'))"
                   (org-babel-process-file-name
                    tmp-src-file 'noquote))))
         (org-babel-python-send-string session body))

The problem is the reuse of f as the file handle in the with statement: when the Python interpreter evaluates the code, the value of f is the file handle instead of the original string. Ideally, org-babel-python-evaluate-session should use, instead of f, an identifier that is not used by the user code that was squirreled into the temp file - that may be difficult to arrange, but an easy, and almost foolproof, workaround would be to construct a random identifier that would, in all likelihood, avoid the collision.[1]

Please report this (and reference this question) with M-x org-submit-bug-report.

The obvious workaround is to not use f for now, until the bug is fixed.


[1] Something like a concatenation of __file__handle__ with a UUID produced by org-id-uuid (with underscores instead of dashes) should work pretty well in virtually all cases.

2
  • 1
    Bug reported here Commented Jun 13 at 8:32
  • The ob-python maintainer has pushed a fix into the bugfix branch and to the main branch. Commented Jun 15 at 1:39

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.