2

Since default value for :result header is value print statement will only show with :result output

#+BEGIN_SRC python :results output
  print('  hello')
#+END_SRC

#+RESULTS:
:   hello

but same thing in session is trimming whitespace trailing and preciding like python str.strip() method.

#+BEGIN_SRC python :results output :session test
  print('  hello')
#+END_SRC

#+RESULTS:
: hello

according to manual in Results-of-Evaluation verbatim which should Interpret literally seem only to work with value as stated in manual's usage example: ‘:results value verbatim’ will not show output of print. How to stop the output being trimmed in session.

#+BEGIN_SRC python :results value verbatim :session test
  print('  hello')
#+END_SRC

#+RESULTS:
  • I don't know how to fix this, but using value won't work: For languages like Python, an explicit return statement is mandatory when using ‘:results value’. Result is the value returned by the last statement in the code block – Swedgin Apr 28 at 7:23
  • s = " hello" and putting s on the last line with :results value does work though, but not a desirable solution – Swedgin Apr 28 at 7:26
  • Quick question - Why did you choose to use :session header? – Melioratus Apr 28 at 19:28
  • 1
    @Melioratus because i needed to carry my session around in many code blocks, above is the showing root cause of inconstant behavior. – rho Apr 29 at 2:48
  • Thanks! I thought this was the reason. Just to clarify, the problem is created due org-trim and you're using :session to share and/or combine code from seperate blocks that are not using #+NAME: or :noweb-ref headers correct? If the only reason for using :session is to combine code from separate blocks then using literate programming features instead of :session might also be a viable alternative solution. – Melioratus Apr 29 at 18:09
3

Editorial comment: Session handling (at least with python) is very much a hack: there are markers inserted to signal where the current output ends, the code has to wait to make sure that all the output has been... ahem ... output, any errors that creep through somehow may be reported as part of the output, etc.

That said, you might want to try the following "fix": in the file ob-python.el, lines 332ff, you will see a block of code that looks something like this:

      (mapconcat
        #'org-trim
        (butlast
         (org-babel-comint-with-output
             (session org-babel-python-eoe-indicator t body)
           (funcall input-body body)
           (funcall send-wait) (funcall send-wait)
           (insert org-babel-python-eoe-indicator)
           (funcall send-wait))
         2) "\n")))

Try replacing that org-trim with identity and reloading with M-x load-file RET ob-python.el RET (you might want to byte-compile it, but try it before doing so: you might want to beat a hasty retreat first to the original code).

There is no warranty, not even implied, on either the original code or the modified code. If you get errors, try deleting the session and starting it up again. If you still get errors, maybe change it back and live with the current problems.

| improve this answer | |
  • i edited ob-python.el and byte-complie it, works! – rho Apr 29 at 3:22
1

An alternative to NickD's answer is to not use :session header to share code between blocks but instead use :noweb-ref syntax to combine code blocks.

How does this literate programming answer even work?

  • The first three python blocks have the :noweb-ref my-code header added.
  • The python code from the first three python blocks are combined in top to bottom order and assigned to the noweb reference named my-code.
  • The fourth python block headers are :noweb yes :results output thereby bypassing org-trim issue by not using :session header.
  • When the fourth code block is executed, the :noweb yes header tells org-mode to substitute the «my-code» string for lines of code named in my-code noweb reference and then executes the updated code block.

Answer

  • Example code to bypass org-trim issue in ob-python.el by not using :session header but still combining and/or sharing code between seperate code blocks:

    Save the following code example into an new org-mode file and then close and open the new file in emacs.

    Note: When you open the new org-mode file, you will be prompted to accept the new values for org-babel-noweb-wrap-start: "«"; org-babel-noweb-wrap-end: "»";. Please type y to accept new values temporarily. Otherwise the example code will try to use the default values of << and >> instead.

    # -*- mode: org; org-babel-noweb-wrap-start: "«"; org-babel-noweb-wrap-end: "»"; -*-
    # 
    # To prevent syntax highlighting conflicts with "<<" and ">>" in your source code I recommend setting variables org-babel-noweb-wrap-start to "«" and org-babel-noweb-wrap-end to "»" in your default emacs configuration.
    #
    # TIP: To create the "«" character use the key chord C-x 8 <
    # TIP: To create the "»" character use the key chord C-x 8 >
    # TIP: Add "-*- mode: org; org-babel-noweb-wrap-start: "«"; org-babel-noweb-wrap-end: "»"; -*-" to top of your org file just in case another user doesn't want to reset their default values.
    
    * Learning Python Syntax with Literate Programming in org-mode
    
    In your python script do the following:
    
    1. Define a variable named ~the_message~ in python syntax.
    
       #+BEGIN_SRC python :noweb-ref my-code
         the_message='  hello'
       #+END_SRC
    
    2. Define a function named ~greeting~ which takes a single parameter named ~msg~ and prints the ~msg~ in python syntax.
    
       #+BEGIN_SRC python :noweb-ref my-code
         #
         # Define greeting function
         #
         def greeting(msg):
             print msg
       #+END_SRC
    
    3. Call the ~greeting~ function using the ~the_message~ variable in python syntax.
    
       #+BEGIN_SRC python :noweb-ref my-code
         #
         # Call greeting function
         #
         greeting(the_message)
       #+END_SRC
    
    4. Execute your python script and you should see the following output.
    
       #+BEGIN_SRC python :noweb yes :results output
         «my-code»
       #+END_SRC
    
       #+RESULTS:
       :   hello
    

The code in this answer was tested using:

emacs version: GNU Emacs 25.2.1 (x86_64-unknown-cygwin, GTK+ Version 3.22.10)
org-mode version: 9.1.2
python version: 2.7.13

| improve this answer | |
  • Very nice answer (but why not python3?) – NickD Apr 29 at 22:24
  • @NickD - LOL - Good point! Unfortunately, I don't have python3 installed under cygwin64 yet. Unfortunately, I'm waiting to upgrade everything I have running under cygwin64, i.e. emacs, ruby, python, guile, etc... so I only have to get a single sign-off/approval/security audit for cygwin64 installations at work. – Melioratus Apr 29 at 22:32
  • @Melioratus noweb-ref works for small sequence of code blocks. Intermediate state are hard to inspect resulting always to look for final block because tag (<<>>) ref copies block when executing which is quite contrary what session does. Similar to jupyter blocks, ob-ipython might do that in emacs which i haven't explored much. – rho Apr 30 at 1:54
  • 1
    @rho - To inspect the intermediate states I usually do C-c C-v v on last code block to combine the separate blocks and then start the python interpreter and C-c C-c to have buffer evaluated in the interpreter. This provides similar side by side views as session without using the :session header. Please keep in mind the answer uses simplest example of noweb syntax. There other ways to use noweb that easily scale to encompass several hundred of code blocks which contain up to a thousand of lines of code in each block. – Melioratus Apr 30 at 3:38

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.