A feature of the doctest module can be useful when people copy and paste their idle window in the python forum: the ability to transform an example from the python interpreter into python code without the prompts >>>, ... and the output messages. The script below permits to use this function from the command line.

Edited 5 Years Ago by Gribouillis: n/a

Comments
neat
Handy
# script_from_examples.py
""" Script to convert python interpreter examples into python code

    Usage:
        python script_from_examples.py <file>
        
        read a file containing python interpreter examples and outputs
        the python code without the prompt. For example if <file> contains

        >>> L = range(3)
        >>> for x in L:
        ...  print x
        ... 
        0
        1
        2
        >>> 

        
        the output of the command in stdout will be the python code
        
        L = range(3)
        for x in L:
         print x
        # Expected:
        ## 0
        ## 1
        ## 2

"""
import doctest
import sys

if __name__ == "__main__":
    assert len(sys.argv) == 2
    filename = sys.argv[-1]
    print doctest.script_from_examples(open(filename).read())

Looks like the doctest can not handle def statements from log of IDLE command prompt.

C:\py>script_from_examples.py ex2.txt
def sum(a,b):
# Expected:
##         return a+b


C:\py>type ex2.txt
>>> def sum(a,b):
        return a+b

Plain CMD Python prompt shows it differently:

>>> def sum(a,b):
...     return a+b
...

Edited 5 Years Ago by pyTony: n/a

Comments
indeed

Looks like the doctest can not handle def statements from log of IDLE command prompt.

It is true, but I finally found a solution for idle. There is an improved idle in pypi called idlex. This idlex can be used with a normal idle shell or with an ipython shell (I had issues with the ipython shell, probably due to a version mismatch). Used with a normal shell, one can use the Paste from Shell tool to handle idle shell output !

The source code for this tool is in the file PastePyShell.py in the idlex module.

Install with

pip install idlex

Edited 2 Years Ago by Gribouillis

Following the previous remark, here is the new version of script_from_example.py, which should work for standard console output and also for idle output, and even ipython output (but you must install idlex first)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on Sat Aug  9 21:55:07 2014
@author: Gribouillis, for the python forum at www.daniweb.com
@lisense: Public Domain
Use this code freely
"""
from __future__ import (absolute_import, division,
                        print_function, unicode_literals)
__version__ = '0.2'
import argparse
import codecs
from idlexlib.extensions.PastePyShell import PastePyShellProcessor

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description="""transform a python shell example into python code

        """,
        formatter_class=argparse.RawTextHelpFormatter,)
    parser.add_argument('filename',
        action='store',
        help='file containing a python shell example (with >>> and results)',
        metavar='FILE',
        )
    parser.add_argument('-e', '--encoding',
        help='encoding (eg latin1), defaults to utf8.',
        metavar='ENCODING',
        dest='encoding',
        default='utf8')
    args = parser.parse_args()
    pc = PastePyShellProcessor()
    res = pc._paste_process(codecs.open(
        args.filename, encoding=args.encoding).read())
    for i in res.split('\n'):
        print(i)

It was tested with this text file, for python 2 and 3

>>> L = range(3)
>>> for x in L:
...  print x
... 
0
1
2
>>> def foo(x):
...     print('hello')
... 
>>> foo
<function foo at 0x7f50e99905f0>
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 argument (0 given)
>>> foo(2)
hello
>>> def sum(a,b):
        return a+b


In [1]: L = range(5)

In [2]: def foo(x):
   ...:     print x
   ...:     print 'foo'
   ...:     if x is None:
   ...:         x = "bar"
   ...:         

In [3]: foo(5)
5
foo

and produces the following

#
L = range(3)
for x in L:
 print x

#0
#1
#2
def foo(x):
    print('hello')

foo
#<function foo at 0x7f50e99905f0>
foo()
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: foo() takes exactly 1 argument (0 given)
foo(2)
#hello
def sum(a,b):
        return a+b

L = range(5)
def foo(x):
    print x
    print 'foo'
    if x is None:
        x = "bar"

foo(5)
#5
#foo
#
# 

Edited 2 Years Ago by Gribouillis

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.