You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让IPython的stdout输出纳入%history -o以生成doctest?

Great questions! Let's tackle both of them since they're tied directly to your core goal of generating doctests from your IPython session—where you need to capture not just expression return values, but also stdout/stderr output from print() statements and other writes to standard output.

First: Can we capture all stdout output in IPython's history?

Absolutely. By default, IPython's %history -o only tracks return values of expressions (like the result of 1+2), not content written directly to stdout (like print("hello")). But we can fix this with either a quick magic command or a persistent configuration tweak.

Second: Making print() output show up in %history -o (for doctests)

Your main need is getting stdout into the output history so you can generate valid doctest cases. Here are two reliable approaches:

Approach 1: Quick and dirty with %logstart (ideal for one-off sessions)

If you just need this for a single session, use IPython's built-in logging to capture everything—input, return values, and stdout:

  1. Start your IPython session.
  2. Run this command:
    %logstart -o -r doctest_session.log
    
    • -o tells IPython to log output (including stdout)
    • -r logs all input commands
    • doctest_session.log is the file where everything gets saved

Now every print() statement, expression result, and input command will be logged in the file. The log will look exactly like your IPython session:

In [1]: print("Hello, doctest!")
Hello, doctest!

In [2]: 5 * 4
Out[2]: 20

This format is perfect for copying directly into doctests—just replace In [x]: with >>> and you're good to go.

Approach 2: Persistent configuration (for all future sessions)

If you want this behavior every time you launch IPython, add a custom hook to your IPython startup script:

  1. Create a startup script file at ~/.ipython/profile_default/startup/00-capture-stdout.py (create the startup folder if it doesn't exist).
  2. Paste this code into the file:
    import sys
    from io import StringIO
    from IPython import get_ipython
    
    class StdoutCapture:
        def __init__(self, original_stdout):
            self.original = original_stdout
            self.buffer = StringIO()
    
        def write(self, data):
            self.buffer.write(data)
            self.original.write(data)  # Keep output visible in the terminal
    
        def flush(self):
            self.original.flush()
    
        def get_output(self):
            return self.buffer.getvalue()
    
    original_stdout = sys.stdout
    ip = get_ipython()
    
    def pre_execute():
        sys.stdout = StdoutCapture(original_stdout)
    
    def post_execute(result):
        captured = sys.stdout.get_output()
        sys.stdout = original_stdout
    
        # Update the output history with captured stdout + return value
        if captured:
            if result is not None:
                combined = captured + str(result)
            else:
                combined = captured
            ip.user_ns['_oh'][ip.execution_count] = combined
    
    ip.events.register('pre_execute', pre_execute)
    ip.events.register('post_execute', post_execute)
    
  3. Restart IPython. Now every print() output will be merged with the return value (if any) in the output history. When you run %history -o, you'll see the stdout content included.

A quick note on doctest generation

Once you have the output captured (either via log file or modified history), you can easily convert it to doctest format. For example, using the log file, you can run a simple script to replace In [x]: with >>> and strip any unnecessary lines.

内容的提问来源于stack exchange,提问作者Tonis F. Piip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:07:04