3

I'm trying to allow for evaluation of code blocks within a trusted Org mode document (following instructions at https://orgmode.org/manual/Evaluating-Code-Blocks.html) but can't seem to dodge the prompt. Minimal examples:

#+PROPERTY: header-args: :eval yes

#+begin_src python :results output
print("Hello World")
#+end_src
#+header: :eval yes
#+begin_src python :results output
print("Hello World")
#+end_src
#+begin_src python :results output :eval yes
print("Hello World")
#+end_src

It seems that in each case, :eval yes is ignored and I am prompted:

Evaluate this python code block on your system? (yes or no)

I would prefer not to use

(setq org-confirm-babel-evaluate nil)

(https://orgmode.org/manual/Code-Evaluation-Security.html).

Code evaluation works OK if I answer yes, but I'd prefer not to have to do that when the source is trusted.

I assume I must have the syntax wrong, but am not sure how to fix it.

In init.el:

...
(org-babel-do-load-languages
    'org-babel-load-languages
    '((emacs-lisp . t)
      (python . t)))
...

Emacs 28.2

1 Answer 1

5

There is one mistake in the syntax: the name of the property should not end with a colon, so the #+PROPERTY line should read:

#+PROPERTY: header-args :eval yes

However, that only affects the first of your examples; the other two blocks are unaffected by the syntax error. The fact is that if org-confirm-babel-evaluate is at its default value of t, they all pop the question. Assuming that you are interpreting the doc correctly, it seems like a bug to me.

Here's the doc of the :eval header:

The ‘eval’ header argument can limit evaluation of specific code blocks
and ‘CALL’ keyword.  It is useful for protection against evaluating
untrusted code blocks by prompting for a confirmation.

‘yes’
     Org always evaluates the source code without asking permission.
...

It seems pretty unequivocal that if the header is :eval yes then Org evaluates the block with no questions asked (whatever the value of org-confirm-babel-evaluate is). That's the way you interpreted it and I agree with your interpretation.

Unfortunately, the code does not agree:

  (let* ((headers (nth 2 info))
     (eval (or (cdr  (assq :eval headers))
           (when (assq :noeval headers) "no")))
     ...
     (query (or (equal eval "query")
                (and export (equal eval "query-export"))
                (if (functionp org-confirm-babel-evaluate)
                    (funcall org-confirm-babel-evaluate
                    ;; Language, code block body.
                    (nth 0 info)
                    (org-babel--expand-body info))
                   org-confirm-babel-evaluate))))

Even though the value of the eval variable is "yes", the query variable is set to whatever org-confirm-babel-evaluate is set (in the simplest case where it is either t or nil - but that's the only case we are interested in here). So in the default case where org-config-babel-evaluate is t, then the query value will be t as well.

The subsequent cond then:

    (cond
     (noeval nil)
     (query 'query)
     (t t))))

finds query to be t and returns the symbol query which makes the caller of this function (org-babel-confirm-evaluate) pop the dreaded question.

It seems to me that the query variable in org-babel-check-confirm-evaluate is calculated incorrectly (assuming that the doc means what it says) and that's a bug that should be reported to the Org mode ML.

One possible workaround is to modify the cond in org-babel-check-confirm-evaluate to check if eval is "yes" before going on to the query case:


    ...
    (cond
     (noeval nil)
     ((equal eval "yes") t)   ; add case to check `eval`
     (query 'query)
     (t 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.