5 from test
.test_support
import run_unittest
, catch_warning
7 from platform
import system
as platform_system
9 def ignore_message_warning():
10 """Ignore the DeprecationWarning for BaseException.message."""
11 warnings
.resetwarnings()
12 warnings
.filterwarnings("ignore", "BaseException.message",
16 class ExceptionClassTests(unittest
.TestCase
):
18 """Tests for anything relating to exception objects themselves (e.g.,
19 inheritance hierarchy)"""
21 def test_builtins_new_style(self
):
22 self
.failUnless(issubclass(Exception, object))
24 def verify_instance_interface(self
, ins
):
26 ignore_message_warning()
27 for attr
in ("args", "message", "__str__", "__repr__",
29 self
.failUnless(hasattr(ins
, attr
),
30 "%s missing %s attribute" %
31 (ins
.__class
__.__name
__, attr
))
33 def test_inheritance(self
):
34 # Make sure the inheritance hierarchy matches the documentation
35 exc_set
= set(x
for x
in dir(exceptions
) if not x
.startswith('_'))
36 inheritance_tree
= open(os
.path
.join(os
.path
.split(__file__
)[0],
37 'exception_hierarchy.txt'))
39 superclass_name
= inheritance_tree
.readline().rstrip()
41 last_exc
= getattr(__builtin__
, superclass_name
)
42 except AttributeError:
43 self
.fail("base class %s not a built-in" % superclass_name
)
44 self
.failUnless(superclass_name
in exc_set
)
45 exc_set
.discard(superclass_name
)
46 superclasses
= [] # Loop will insert base exception
48 for exc_line
in inheritance_tree
:
49 exc_line
= exc_line
.rstrip()
50 depth
= exc_line
.rindex('-')
51 exc_name
= exc_line
[depth
+2:] # Slice past space
53 paren_index
= exc_name
.index('(')
54 platform_name
= exc_name
[paren_index
+1:-1]
55 exc_name
= exc_name
[:paren_index
-1] # Slice off space
56 if platform_system() != platform_name
:
57 exc_set
.discard(exc_name
)
60 left_bracket
= exc_name
.index('[')
61 exc_name
= exc_name
[:left_bracket
-1] # cover space
63 exc
= getattr(__builtin__
, exc_name
)
64 except AttributeError:
65 self
.fail("%s not a built-in exception" % exc_name
)
66 if last_depth
< depth
:
67 superclasses
.append((last_depth
, last_exc
))
68 elif last_depth
> depth
:
69 while superclasses
[-1][0] >= depth
:
71 self
.failUnless(issubclass(exc
, superclasses
[-1][1]),
72 "%s is not a subclass of %s" % (exc
.__name
__,
73 superclasses
[-1][1].__name
__))
74 try: # Some exceptions require arguments; just skip them
75 self
.verify_instance_interface(exc())
78 self
.failUnless(exc_name
in exc_set
)
79 exc_set
.discard(exc_name
)
83 inheritance_tree
.close()
84 self
.failUnlessEqual(len(exc_set
), 0, "%s not accounted for" % exc_set
)
86 interface_tests
= ("length", "args", "message", "str", "unicode", "repr",
89 def interface_test_driver(self
, results
):
90 for test_name
, (given
, expected
) in zip(self
.interface_tests
, results
):
91 self
.failUnlessEqual(given
, expected
, "%s: %s != %s" % (test_name
,
94 def test_interface_single_arg(self
):
95 # Make sure interface works properly when given a single argument
99 ignore_message_warning()
100 results
= ([len(exc
.args
), 1], [exc
.args
[0], arg
],
102 [str(exc
), str(arg
)], [unicode(exc
), unicode(arg
)],
103 [repr(exc
), exc
.__class
__.__name
__ + repr(exc
.args
)], [exc
[0],
105 self
.interface_test_driver(results
)
107 def test_interface_multi_arg(self
):
108 # Make sure interface correct when multiple arguments given
110 args
= tuple(range(arg_count
))
111 exc
= Exception(*args
)
112 with
catch_warning():
113 ignore_message_warning()
114 results
= ([len(exc
.args
), arg_count
], [exc
.args
, args
],
115 [exc
.message
, ''], [str(exc
), str(args
)],
116 [unicode(exc
), unicode(args
)],
117 [repr(exc
), exc
.__class
__.__name
__ + repr(exc
.args
)],
119 self
.interface_test_driver(results
)
121 def test_interface_no_arg(self
):
122 # Make sure that with no args that interface is correct
124 with
catch_warning():
125 ignore_message_warning()
126 results
= ([len(exc
.args
), 0], [exc
.args
, tuple()],
128 [str(exc
), ''], [unicode(exc
), u
''],
129 [repr(exc
), exc
.__class
__.__name
__ + '()'], [True, True])
130 self
.interface_test_driver(results
)
133 def test_message_deprecation(self
):
134 # As of Python 2.6, BaseException.message is deprecated.
135 with
catch_warning():
136 warnings
.resetwarnings()
137 warnings
.filterwarnings('error')
140 BaseException().message
141 except DeprecationWarning:
144 self
.fail("BaseException.message not deprecated")
146 exc
= BaseException()
149 except DeprecationWarning:
152 self
.fail("BaseException.message assignment not deprecated")
154 class UsageTests(unittest
.TestCase
):
156 """Test usage of exceptions"""
158 def raise_fails(self
, object_
):
159 """Make sure that raising 'object_' triggers a TypeError."""
163 return # What is expected.
164 self
.fail("TypeError expected for raising %s" % type(object_
))
166 def catch_fails(self
, object_
):
167 """Catching 'object_' should raise a TypeError."""
175 except StandardError:
176 self
.fail("TypeError expected when catching %s" % type(object_
))
185 except StandardError:
186 self
.fail("TypeError expected when catching %s as specified in a "
187 "tuple" % type(object_
))
189 def test_raise_classic(self
):
190 # Raising a classic class is okay (for now).
198 self
.fail("unable to raise classic class")
204 self
.fail("unable to raise class class instance")
206 def test_raise_new_style_non_exception(self
):
207 # You cannot raise a new-style class that does not inherit from
208 # BaseException; the ability was not possible until BaseException's
209 # introduction so no need to support new-style objects that do not
211 class NewStyleClass(object):
213 self
.raise_fails(NewStyleClass
)
214 self
.raise_fails(NewStyleClass())
216 def test_raise_string(self
):
217 # Raising a string raises TypeError.
218 self
.raise_fails("spam")
220 def test_catch_string(self
):
221 # Catching a string should trigger a DeprecationWarning.
222 with
catch_warning():
223 warnings
.resetwarnings()
224 warnings
.filterwarnings("error")
231 except DeprecationWarning:
233 except StandardError:
234 self
.fail("catching a string exception did not raise "
235 "DeprecationWarning")
236 # Make sure that even if the string exception is listed in a tuple
237 # that a warning is raised.
241 except (AssertionError, str_exc
):
243 except DeprecationWarning:
245 except StandardError:
246 self
.fail("catching a string exception specified in a tuple did "
247 "not raise DeprecationWarning")
251 run_unittest(ExceptionClassTests
, UsageTests
)
255 if __name__
== '__main__':