Skip to content

Commit 68b834d

Browse files
committed
Add tests for issues bpython#108 and bpython#133.
1 parent e2199b7 commit 68b834d

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

bpython/inspection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def fixlongargs(f, argspec):
164164
kwparsed = parsekeywordpairs(signature)
165165

166166
for i, (key, value) in enumerate(zip(keys, values)):
167-
if len(str(value)) != len(kwparsed[key]):
167+
if len(repr(value)) != len(kwparsed[key]):
168168
values[i] = kwparsed[key]
169169

170170
argspec[3] = values

bpython/test/test.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[general]
2+
hist_file = /dev/null
3+
paste_time = 0

bpython/test/test_crashers.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import fcntl
2+
import os
3+
import pty
4+
import struct
5+
import sys
6+
import termios
7+
import textwrap
8+
import unittest
9+
10+
try:
11+
from twisted.internet import reactor
12+
from twisted.internet.defer import Deferred
13+
from twisted.internet.protocol import ProcessProtocol
14+
from twisted.trial.unittest import TestCase as TrialTestCase
15+
except ImportError:
16+
reactor = None
17+
18+
TEST_CONFIG = os.path.join(os.path.dirname(__file__), "test.config")
19+
20+
def set_win_size(fd, rows, columns):
21+
s = struct.pack('HHHH', rows, columns, 0, 0)
22+
fcntl.ioctl(fd, termios.TIOCSWINSZ, s)
23+
24+
class CrashersTest(object):
25+
backend = "cli"
26+
27+
def run_bpython(self, input):
28+
"""
29+
Run bpython (with `backend` as backend) in a subprocess and
30+
enter the given input. Uses a test config that disables the
31+
paste detection.
32+
33+
Retuns bpython's output.
34+
"""
35+
result = Deferred()
36+
37+
class Protocol(ProcessProtocol):
38+
STATES = (SEND_INPUT, COLLECT) = xrange(2)
39+
40+
def __init__(self):
41+
self.data = ""
42+
self.delayed_call = None
43+
self.states = iter(self.STATES)
44+
self.state = self.states.next()
45+
46+
def outReceived(self, data):
47+
self.data += data
48+
if self.delayed_call is not None:
49+
self.delayed_call.cancel()
50+
self.delayed_call = reactor.callLater(0.5, self.next)
51+
52+
def next(self):
53+
self.delayed_call = None
54+
if self.state == self.SEND_INPUT:
55+
index = self.data.find(">>> ")
56+
if index >= 0:
57+
self.data = self.data[index + 4:]
58+
self.transport.write(input)
59+
self.state = self.states.next()
60+
else:
61+
self.transport.closeStdin()
62+
if self.transport.pid is not None:
63+
self.delayed_call = None
64+
self.transport.signalProcess("TERM")
65+
66+
def processExited(self, reason):
67+
if self.delayed_call is not None:
68+
self.delayed_call.cancel()
69+
result.callback(self.data)
70+
71+
(master, slave) = pty.openpty()
72+
set_win_size(slave, 25, 80)
73+
reactor.spawnProcess(Protocol(), sys.executable,
74+
(sys.executable, "-m", "bpython." + self.backend,
75+
"-c", TEST_CONFIG),
76+
env=dict(TERM="vt100"),
77+
usePTY=(master, slave, os.ttyname(slave)))
78+
return result
79+
80+
def test_issue108(self):
81+
input = textwrap.dedent(
82+
"""\
83+
def spam():
84+
u"y\\xe4y"
85+
\b
86+
spam(""")
87+
deferred = self.run_bpython(input)
88+
return deferred.addCallback(self.check_no_traceback)
89+
90+
def test_issue133(self):
91+
input = textwrap.dedent(
92+
"""\
93+
def spam(a, (b, c)):
94+
pass
95+
\b
96+
spam(1""")
97+
return self.run_bpython(input).addCallback(self.check_no_traceback)
98+
99+
def check_no_traceback(self, data):
100+
tb = data[data.find("Traceback"):]
101+
self.assertTrue("Traceback" not in data, tb)
102+
103+
if reactor is not None:
104+
class CursesCrashersTest(TrialTestCase, CrashersTest):
105+
backend = "cli"
106+
107+
class UrwidCrashersTest(TrialTestCase, CrashersTest):
108+
backend = "urwid"
109+
110+
if __name__ == "__main__":
111+
unittest.main()

bpython/test/test_inspection.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import inspect
12
import unittest
23

34
from bpython import inspection
@@ -42,5 +43,15 @@ def fails(spam=['-a', '-b']):
4243
defaults = argspec[1][3]
4344
self.assertEqual(str(defaults[0]), default_arg_repr)
4445

46+
def test_fixlongargs(self):
47+
def spam(a, b=1, c="y\xc3\xa4y"):
48+
pass
49+
50+
argspec = list(inspect.getargspec(spam))
51+
print argspec[3],
52+
inspection.fixlongargs(spam, argspec)
53+
print argspec[3], [type(a) for a in argspec[3]]
54+
self.assertFalse(argspec)
55+
4556
if __name__ == '__main__':
4657
unittest.main()

0 commit comments

Comments
 (0)