Since we know the problem lies in digits(), let's set an explicit breakpoint in there using the pdb.set_trace() function mentioned earlier:
def digits(x):
"""Convert an integer into a list of digits.
Args:
x: The number whose digits we want.
Returns: A list of the digits, in order, of ``x``.
>>> digits(4586378)
[4, 5, 8, 6, 3, 7, 8]
"""
import pdb; pdb.set_trace()
digs = []
while x != 0:
div, mod = divmod(x, 10)
digs.append(mod)
x = mod
return digs
Remember that the set_trace() function will halt execution and enter the debugger.
So now we can just execute our script without specifying the PDB module:
% python palindrome.py
> /Users/sixty_north/examples/palindrome.py(8)digits()
-> digs = []
(Pdb)
And we see that we almost immediately go to a PDB prompt with execution halted at the beginning of our digits() function.
To verify that we know where we are, let's use where to see our call stack:
(Pdb) where
/Users/sixty_north/examples/palindrome.py(35)<module>()
-> unittest.main()
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/un
ittest/main.py(95)__init__()
-> self.runTests()
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/main.py(229)runTests()
-> self.result = testRunner.run(self.test)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/runner.py(151)run()
-> test(result)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/suite.py(70)__call__()
-> return self.run(*args, **kwds)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/suite.py(108)run()
-> test(result)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/suite.py(70)__call__()
-> return self.run(*args, **kwds)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/suite.py(108)run()
-> test(result)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/case.py(391)__call__()
-> return self.run(*args, **kwds)
/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/uni
ttest/case.py(327)run()
-> testMethod()
/Users/sixty_north/examples/palindrome.py(25)test_negative()
-> self.assertFalse(is_palindrome(1234))
/Users/sixty_north/examples/palindrome.py(17)is_palindrome()
-> digs = digits(x)
> /Users/sixty_north/examples/palindrome.py(8)digits()
-> digs = []
Remember that the most recent frames are at the end of this listing. After a lot of unittest functions, we see that we are indeed in the digits() function, and that it was called by is_palindrome(), just as we expected.