1
"""
2
@file
3
@brief Python wrapper around C functions.
4
"""
5 1
from typing import Tuple
6 1
from io import StringIO
7 1
from contextlib import redirect_stdout, redirect_stderr
8 1
from .stdchelper import begin_capture, end_capture, get_capture  # pylint: disable=E0611
9

10

11 1
def 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.
16

17
    :param function_to_call: function to call
18
    :return: output, error
19

20
    This function must not be called in parallel with another
21
    call of the same function.
22

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 1
    begin_capture()
28 1
    fout = function_to_call()
29 1
    end_capture()
30 1
    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)))
39

40

41 1
def 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>`_.
48

49
    :param function_to_call: function to call
50
    :return: output, error
51

52
    This function must not be called in parallel with another
53
    call of the same function.
54

55
    .. warning:: *error* is always empty. Both streams are merged.
56
    """
57 1
    if not callable(function_to_call):
58 1
        raise TypeError("function_to_call must be callable.")
59 1
    out, err = StringIO(), StringIO()
60 1
    with redirect_stdout(out):
61 1
        with redirect_stderr(err):
62 1
            fout = function_to_call()
63 1
    return fout, out.getvalue(), err.getvalue()
64

65

66 1
def 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'*.
72

73
    :param function_to_call: function to call
74
    :return: output, error
75
    """
76 1
    if lang == "py":
77 1
        return capture_output_py(function_to_call)
78 1
    elif lang == "c":
79 1
        return capture_output_c(function_to_call)
80 1
    raise ValueError("lang must be 'py' or 'c' not '{0}'".format(lang))

Read our documentation on viewing source code .

Loading