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

""" 

This plugin provides ``--pdb`` and ``--pdb-failures`` options. The ``--pdb`` 

option will drop the test runner into pdb when it encounters an error. To 

drop into pdb on failure, use ``--pdb-failures``. 

""" 

 

import pdb 

from nose.plugins.base import Plugin 

 

class Pdb(Plugin): 

""" 

Provides --pdb and --pdb-failures options that cause the test runner to 

drop into pdb if it encounters an error or failure, respectively. 

""" 

enabled_for_errors = False 

enabled_for_failures = False 

score = 5 # run last, among builtins 

 

def options(self, parser, env): 

"""Register commandline options. 

""" 

parser.add_option( 

"--pdb", action="store_true", dest="debugBoth", 

default=env.get('NOSE_PDB', False), 

help="Drop into debugger on failures or errors") 

parser.add_option( 

"--pdb-failures", action="store_true", 

dest="debugFailures", 

default=env.get('NOSE_PDB_FAILURES', False), 

help="Drop into debugger on failures") 

parser.add_option( 

"--pdb-errors", action="store_true", 

dest="debugErrors", 

default=env.get('NOSE_PDB_ERRORS', False), 

help="Drop into debugger on errors") 

 

def configure(self, options, conf): 

"""Configure which kinds of exceptions trigger plugin. 

""" 

self.conf = conf 

self.enabled_for_errors = options.debugErrors or options.debugBoth 

self.enabled_for_failures = options.debugFailures or options.debugBoth 

self.enabled = self.enabled_for_failures or self.enabled_for_errors 

 

def addError(self, test, err): 

"""Enter pdb if configured to debug errors. 

""" 

if not self.enabled_for_errors: 

return 

self.debug(err) 

 

def addFailure(self, test, err): 

"""Enter pdb if configured to debug failures. 

""" 

if not self.enabled_for_failures: 

return 

self.debug(err) 

 

def debug(self, err): 

import sys # FIXME why is this import here? 

ec, ev, tb = err 

stdout = sys.stdout 

sys.stdout = sys.__stdout__ 

try: 

pdb.post_mortem(tb) 

finally: 

sys.stdout = stdout