emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] Proposal and RFC for improving ob-python


From: Kyle Meyer
Subject: Re: [O] Proposal and RFC for improving ob-python
Date: Thu, 10 Dec 2015 22:39:21 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Ondřej Grover <address@hidden> writes:

[...]

>> But what about when :results != value?  Doesn't your proposal only
>> handle returning the last value?
>>
> You mean :results output ? In that case it could just omit the
> "open(...).write(...) " part and capture anything the console prints before
> the primary prompt appears again.
> Or it could capture stdout into a file, but I think that's needlessly
> complicated:
>
> python -i << HEREDOC_END
> import sys
> sys.stdout = open(<TMP FILE or PIPE>)   # replace stdout with some file
> _ = block_eval("""
> <CODE BLOCK BODY>
> """)
> sys.stdout.close()
> sys.stdout = sys.__stdout__  # restore stdout
> HEREDOC_END

(I think you should rely on Org babel's shared utilities,
e.g. org-babel-eval and org-babel-eval-read-file, unless there is a
specific reason they won't do.  At any rate, right now I'm just trying
to get a picture of how block_eval would fit in.)

So these are the main options to consider for Python:

    |             | output | value |
    |-------------+--------+-------|
    | non-session | a      | b     |
    | session     | c      | d     |

a) Using block_eval here seems unhelpful here because the method in
   place is already simple:

   (org-babel-eval org-babel-python-command body)

b) block_eval replaces the need for dumping the code into a function.
   Using block_eval in org-babel-python-wrapper-method would allow you
   to get rid of the odd "return" use.

c) Currently, this is handled by inserting the body lines one at a time
   and then getting the output by splitting on the prompt.  Aside from
   race condition issues, this has limitations with handling blank lines
   in the body.

   block_eval could help here because the whole body could be sent
   through as one line of input to the prompt.  This should resolve most
   issues with prompt splitting, as well as lift the body formatting
   restrictions for sessions.

   However, the main issue I see with this is that I think it would lose
   the main distinction between session and non-session for ":results
   output" that is discussed in (info "(org) Results of evaluation"):

       #+BEGIN_SRC python :results output
        print "hello"
        2
        print "bye"
       #+END_SRC

       #+RESULTS:
       : hello
       : bye

   versus this

       #+BEGIN_SRC python :results output :session
        print "hello"
        2
        print "bye"
       #+END_SRC

       #+RESULTS:
       : hello
       : 2
       : bye

d) The variable _ is assigned the last value by the shell, so the
   current mechanism should work even if block_eval is used as described
   in c.

I've attached a quick-and-dirty patch, just for discussion.  At least
under light testing, it resolves the issues I listed in my previous
response [1].  It does have the change in behavior discussed in c, which
I see as problematic.

It also raises the issue of how to incorporate the block_eval code.  I
think there are two main options.

* Require the user have the module installed and import it.

* Make the module into a snippet to go into the ob-python.el.

The first option is what the current patch does.  The problem is that it
requires users to install an external module.  The second option avoids
that but is uglier and harder to maintain.


[1] There's a remaining issue, which I believe is specific to newer
    versions of python.el, where the first time a session block is
    executed, it doesn't wait for the shell to load up before sending
    input.

Attachment: 0001-WIP-lisp-ob-python.el-Use-block_eval.patch
Description: Text Data

--
Kyle

reply via email to

[Prev in Thread] Current Thread [Next in Thread]