Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Python wrapper around C functions.
4"""
5from typing import Tuple
6from io import StringIO
7from contextlib import redirect_stdout, redirect_stderr
8from .stdchelper import begin_capture, end_capture, get_capture # pylint: disable=E0611
11def capture_output_c(function_to_call) -> Tuple:
12 """
13 Capture the standard output and error for
14 function *function_to_call*, it wraps C code which
15 catches information from the command line.
17 :param function_to_call: function to call
18 :return: output, error
20 This function must not be called in parallel with another
21 call of the same function.
23 .. warning:: *error* is always empty. Both streams are merged.
24 """
25 if not callable(function_to_call): # pragma no cover
26 raise TypeError("function_to_call must be callable.")
27 begin_capture()
28 fout = function_to_call()
29 end_capture()
30 res = get_capture()
31 if res is None: # pragma: no cover
32 return fout, None, None
33 if isinstance(res, bytes): # pragma: no cover
34 return fout, res, None
35 if isinstance(res, tuple): # pragma: no cover
36 return (fout, ) + res
37 raise TypeError( # pragma no cover
38 "Unexpected return type '{0}'.".format(type(res)))
41def capture_output_py(function_to_call) -> Tuple[str, str]:
42 """
43 Capture the standard output and error for
44 function *function_to_call* with function
45 `redirect_stdout <https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout>`_
46 and function
47 `redirect_stderr <https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stderr>`_.
49 :param function_to_call: function to call
50 :return: output, error
52 This function must not be called in parallel with another
53 call of the same function.
55 .. warning:: *error* is always empty. Both streams are merged.
56 """
57 if not callable(function_to_call):
58 raise TypeError("function_to_call must be callable.")
59 out, err = StringIO(), StringIO()
60 with redirect_stdout(out):
61 with redirect_stderr(err):
62 fout = function_to_call()
63 return fout, out.getvalue(), err.getvalue()
66def capture_output(function_to_call, lang="py"):
67 """
68 Catch standard output and error for function
69 *function_to_call*. If lang is *'py'*, calls
70 @see fn capture_output_py or @see fn capture_output_c
71 if lang is *'c'*.
73 :param function_to_call: function to call
74 :return: output, error
75 """
76 if lang == "py":
77 return capture_output_py(function_to_call)
78 elif lang == "c":
79 return capture_output_c(function_to_call)
80 raise ValueError("lang must be 'py' or 'c' not '{0}'".format(lang))