3

I'm trying to figure out how to redirect/catch (in a string) all output from argparse.parse_args() to a upd-socket (server), but not from stdout in general.

Eg when running this code:

import argparse

parser = argparse.ArgumentParser(prog='PROG')

parser.add_argument('-x', nargs=2)

parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))

args = parser.parse_args('-x p g -h'.split())
Himanshu
  • 12,071
  • 7
  • 46
  • 61
RePsEj
  • 93
  • 1
  • 10
  • Which output are you talking about? The `args` namespace? Error messages? help or usage messages? – hpaulj Feb 06 '18 at 22:11
  • All error, help and usage messages output from parser.parse_args('-x p g -h'.split()) .. Either caused by '-h' or because of parameter/syntax error. – RePsEj Feb 07 '18 at 23:29
  • This recent one about logging errors is relevant: https://stackoverflow.com/questions/48633847/python-argparse-errors-to-file. If the output isn't to `stdout` it's to `stderr`. You can redirect either or both. – hpaulj Feb 07 '18 at 23:41

1 Answers1

0

With Python 3.4+, you can use redirect_stdout from contextlib

Here's an example program demonstrating this capture/redirection

#!/usr/bin/env python3
import argparse
import io
from contextlib import redirect_stdout


def argparser(args_external=None):
    parser = argparse.ArgumentParser(description="an example program")
    parser.add_argument(
        "-v", "--verbose", action="store_true",
        help="Enable verbose output")
    arguments = parser.parse_args(args_external)  # None -> sys.argv

    # this string goes to stdout, but is captured by redirect_stdout
    print("verbose=={}".format(arguments.verbose))

    return arguments


def main():
    f = io.StringIO()
    with redirect_stdout(f):
        argparser()
    s = f.getvalue()

    print("this statement occurs after the argparser runs")
    print("string contents from argparser: {}".format(s))


if __name__ == "__main__":
    main()

output

% python3 example.py -v
this statement occurs after the argparser runs
string contents from argparser: verbose==True

Additionally, ArgumentParser().parse_args() will accept a list (defaults to sys.argv) if you want to call the argparser multiple times

ti7
  • 16,375
  • 6
  • 40
  • 68