4 from test
.support
import run_unittest
6 from platform
import system
as platform_system
9 class ExceptionClassTests(unittest
.TestCase
):
11 """Tests for anything relating to exception objects themselves (e.g.,
12 inheritance hierarchy)"""
14 def test_builtins_new_style(self
):
15 self
.failUnless(issubclass(Exception, object))
17 def verify_instance_interface(self
, ins
):
18 for attr
in ("args", "__str__", "__repr__"):
19 self
.assertTrue(hasattr(ins
, attr
),
20 "%s missing %s attribute" %
21 (ins
.__class
__.__name
__, attr
))
23 def test_inheritance(self
):
24 # Make sure the inheritance hierarchy matches the documentation
26 for object_
in builtins
.__dict
__.values():
28 if issubclass(object_
, BaseException
):
29 exc_set
.add(object_
.__name
__)
33 inheritance_tree
= open(os
.path
.join(os
.path
.split(__file__
)[0],
34 'exception_hierarchy.txt'))
36 superclass_name
= inheritance_tree
.readline().rstrip()
38 last_exc
= getattr(builtins
, superclass_name
)
39 except AttributeError:
40 self
.fail("base class %s not a built-in" % superclass_name
)
41 self
.failUnless(superclass_name
in exc_set
,
42 '%s not found' % superclass_name
)
43 exc_set
.discard(superclass_name
)
44 superclasses
= [] # Loop will insert base exception
46 for exc_line
in inheritance_tree
:
47 exc_line
= exc_line
.rstrip()
48 depth
= exc_line
.rindex('-')
49 exc_name
= exc_line
[depth
+2:] # Slice past space
51 paren_index
= exc_name
.index('(')
52 platform_name
= exc_name
[paren_index
+1:-1]
53 exc_name
= exc_name
[:paren_index
-1] # Slice off space
54 if platform_system() != platform_name
:
55 exc_set
.discard(exc_name
)
58 left_bracket
= exc_name
.index('[')
59 exc_name
= exc_name
[:left_bracket
-1] # cover space
61 exc
= getattr(builtins
, exc_name
)
62 except AttributeError:
63 self
.fail("%s not a built-in exception" % exc_name
)
64 if last_depth
< depth
:
65 superclasses
.append((last_depth
, last_exc
))
66 elif last_depth
> depth
:
67 while superclasses
[-1][0] >= depth
:
69 self
.failUnless(issubclass(exc
, superclasses
[-1][1]),
70 "%s is not a subclass of %s" % (exc
.__name
__,
71 superclasses
[-1][1].__name
__))
72 try: # Some exceptions require arguments; just skip them
73 self
.verify_instance_interface(exc())
76 self
.failUnless(exc_name
in exc_set
)
77 exc_set
.discard(exc_name
)
81 inheritance_tree
.close()
82 self
.failUnlessEqual(len(exc_set
), 0, "%s not accounted for" % exc_set
)
84 interface_tests
= ("length", "args", "str", "repr")
86 def interface_test_driver(self
, results
):
87 for test_name
, (given
, expected
) in zip(self
.interface_tests
, results
):
88 self
.assertEqual(given
, expected
, "%s: %s != %s" % (test_name
,
91 def test_interface_single_arg(self
):
92 # Make sure interface works properly when given a single argument
95 results
= ([len(exc
.args
), 1], [exc
.args
[0], arg
],
97 [repr(exc
), exc
.__class
__.__name
__ + repr(exc
.args
)])
98 self
.interface_test_driver(results
)
100 def test_interface_multi_arg(self
):
101 # Make sure interface correct when multiple arguments given
103 args
= tuple(range(arg_count
))
104 exc
= Exception(*args
)
105 results
= ([len(exc
.args
), arg_count
], [exc
.args
, args
],
106 [str(exc
), str(args
)],
107 [repr(exc
), exc
.__class
__.__name
__ + repr(exc
.args
)])
108 self
.interface_test_driver(results
)
110 def test_interface_no_arg(self
):
111 # Make sure that with no args that interface is correct
113 results
= ([len(exc
.args
), 0], [exc
.args
, tuple()],
115 [repr(exc
), exc
.__class
__.__name
__ + '()'])
116 self
.interface_test_driver(results
)
118 class UsageTests(unittest
.TestCase
):
120 """Test usage of exceptions"""
122 def raise_fails(self
, object_
):
123 """Make sure that raising 'object_' triggers a TypeError."""
127 return # What is expected.
128 self
.fail("TypeError expected for raising %s" % type(object_
))
130 def catch_fails(self
, object_
):
131 """Catching 'object_' should raise a TypeError."""
140 self
.fail("TypeError expected when catching %s" % type(object_
))
150 self
.fail("TypeError expected when catching %s as specified in a "
151 "tuple" % type(object_
))
153 def test_raise_new_style_non_exception(self
):
154 # You cannot raise a new-style class that does not inherit from
155 # BaseException; the ability was not possible until BaseException's
156 # introduction so no need to support new-style objects that do not
158 class NewStyleClass(object):
160 self
.raise_fails(NewStyleClass
)
161 self
.raise_fails(NewStyleClass())
163 def test_raise_string(self
):
164 # Raising a string raises TypeError.
165 self
.raise_fails("spam")
167 def test_catch_non_BaseException(self
):
168 # Tryinng to catch an object that does not inherit from BaseException
170 class NonBaseException(object):
172 self
.catch_fails(NonBaseException
)
173 self
.catch_fails(NonBaseException())
175 def test_catch_BaseException_instance(self
):
176 # Catching an instance of a BaseException subclass won't work.
177 self
.catch_fails(BaseException())
179 def test_catch_string(self
):
180 # Catching a string is bad.
181 self
.catch_fails("spam")
184 run_unittest(ExceptionClassTests
, UsageTests
)
186 if __name__
== '__main__':