aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_pyrepl/test_interact.py
blob: df97b1354a168ea950827374c5554b422b8e49bb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import contextlib
import io
import unittest
from unittest.mock import patch
from textwrap import dedent

from test.support import force_not_colorized

from _pyrepl.console import InteractiveColoredConsole


class TestSimpleInteract(unittest.TestCase):
    def test_multiple_statements(self):
        namespace = {}
        code = dedent("""\
        class A:
            def foo(self):


                pass

        class B:
            def bar(self):
                pass

        a = 1
        a
        """)
        console = InteractiveColoredConsole(namespace, filename="<stdin>")
        f = io.StringIO()
        with (
            patch.object(InteractiveColoredConsole, "showsyntaxerror") as showsyntaxerror,
            patch.object(InteractiveColoredConsole, "runsource", wraps=console.runsource) as runsource,
            contextlib.redirect_stdout(f),
        ):
            more = console.push(code, filename="<stdin>", _symbol="single")  # type: ignore[call-arg]
        self.assertFalse(more)
        showsyntaxerror.assert_not_called()


    def test_multiple_statements_output(self):
        namespace = {}
        code = dedent("""\
        b = 1
        b
        a = 1
        a
        """)
        console = InteractiveColoredConsole(namespace, filename="<stdin>")
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            more = console.push(code, filename="<stdin>", _symbol="single")  # type: ignore[call-arg]
        self.assertFalse(more)
        self.assertEqual(f.getvalue(), "1\n")

    def test_empty(self):
        namespace = {}
        code = ""
        console = InteractiveColoredConsole(namespace, filename="<stdin>")
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            more = console.push(code, filename="<stdin>", _symbol="single")  # type: ignore[call-arg]
        self.assertFalse(more)
        self.assertEqual(f.getvalue(), "")

    def test_runsource_compiles_and_runs_code(self):
        console = InteractiveColoredConsole()
        source = "print('Hello, world!')"
        with patch.object(console, "runcode") as mock_runcode:
            console.runsource(source)
            mock_runcode.assert_called_once()

    def test_runsource_returns_false_for_successful_compilation(self):
        console = InteractiveColoredConsole()
        source = "print('Hello, world!')"
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            result = console.runsource(source)
        self.assertFalse(result)

    @force_not_colorized
    def test_runsource_returns_false_for_failed_compilation(self):
        console = InteractiveColoredConsole()
        source = "print('Hello, world!'"
        f = io.StringIO()
        with contextlib.redirect_stderr(f):
            result = console.runsource(source)
        self.assertFalse(result)
        self.assertIn('SyntaxError', f.getvalue())

    def test_runsource_shows_syntax_error_for_failed_compilation(self):
        console = InteractiveColoredConsole()
        source = "print('Hello, world!'"
        with patch.object(console, "showsyntaxerror") as mock_showsyntaxerror:
            console.runsource(source)
            mock_showsyntaxerror.assert_called_once()
        source = dedent("""\
        match 1:
            case {0: _, 0j: _}:
                pass
        """)
        with patch.object(console, "showsyntaxerror") as mock_showsyntaxerror:
            console.runsource(source)
            mock_showsyntaxerror.assert_called_once()

    def test_no_active_future(self):
        console = InteractiveColoredConsole()
        source = "x: int = 1; print(__annotations__)"
        f = io.StringIO()
        with contextlib.redirect_stdout(f):
            result = console.runsource(source)
        self.assertFalse(result)
        self.assertEqual(f.getvalue(), "{'x': <class 'int'>}\n")