1
1
from __future__ import division
2
-
3
2
# pylint: disable-msg=W0402
4
3
5
4
import random
5
+ import re
6
6
import string
7
7
import sys
8
8
import tempfile
11
11
import os
12
12
13
13
from datetime import datetime
14
- from functools import wraps
14
+ from functools import wraps , partial
15
15
from contextlib import contextmanager
16
16
from distutils .version import LooseVersion
17
17
@@ -130,27 +130,38 @@ def assert_isinstance(obj, class_type_or_tuple):
130
130
"Expected object to be of type %r, found %r instead" % (
131
131
type (obj ), class_type_or_tuple ))
132
132
133
- def assert_equal (actual , expected , msg = "" ):
134
- assert expected == actual , "%s: %r != %r" % (msg , actual , expected )
133
+ def assert_equal (a , b , msg = "" ):
134
+ """asserts that a equals b, like nose's assert_equal, but allows custom message to start.
135
+ Passes a and b to format string as well. So you can use '{0}' and '{1}' to display a and b.
136
+
137
+ Examples
138
+ --------
139
+ >>> assert_equal(2, 2, "apples")
140
+ >>> assert_equal(5.2, 1.2, "{0} was really a dead parrot")
141
+ Traceback (most recent call last):
142
+ ...
143
+ AssertionError: 5.2 was really a dead parrot: 5.2 != 1.2
144
+ """
145
+ assert a == b , "%s: %r != %r" % (msg .format (a ,b ), a , b )
146
+
135
147
136
148
def assert_index_equal (left , right ):
137
149
if not left .equals (right ):
138
150
raise AssertionError ("[index] left [{0} {1}], right [{2} {3}]" .format (left .dtype ,
139
151
left ,
140
152
right ,
141
153
right .dtype ))
154
+
155
+
142
156
def assert_attr_equal (attr , left , right ):
143
- left_attr = getattr (left , attr , None )
144
- right_attr = getattr (right , attr , None )
157
+ """checks attributes are equal. Both objects must have attribute."""
158
+ left_attr = getattr (left , attr )
159
+ right_attr = getattr (right , attr )
145
160
assert_equal (left_attr ,right_attr ,"attr is not equal [{0}]" .format (attr ))
146
161
147
162
def isiterable (obj ):
148
163
return hasattr (obj , '__iter__' )
149
164
150
- def assert_isinstance (obj , class_type_or_tuple ):
151
- """asserts that obj is an instance of class_type_or_tuple"""
152
- assert isinstance (obj , class_type_or_tuple ), (
153
- "Expected object to be of type %r, found %r instead" % (type (obj ), class_type_or_tuple ))
154
165
155
166
156
167
def assert_almost_equal (a , b , check_less_precise = False ):
@@ -221,7 +232,6 @@ def assert_dict_equal(a, b, compare_keys=True):
221
232
222
233
def assert_series_equal (left , right , check_dtype = True ,
223
234
check_index_type = False ,
224
- check_index_freq = False ,
225
235
check_series_type = False ,
226
236
check_less_precise = False ):
227
237
if check_series_type :
@@ -238,8 +248,6 @@ def assert_series_equal(left, right, check_dtype=True,
238
248
assert_isinstance (left .index , type (right .index ))
239
249
assert_attr_equal ('dtype' , left .index , right .index )
240
250
assert_attr_equal ('inferred_type' , left .index , right .index )
241
- if check_index_freq :
242
- assert_attr_equal ('freqstr' , left .index , right .index )
243
251
244
252
245
253
def assert_frame_equal (left , right , check_dtype = True ,
@@ -261,7 +269,7 @@ def assert_frame_equal(left, right, check_dtype=True,
261
269
assert_index_equal (left .index , right .index )
262
270
263
271
for i , col in enumerate (left .columns ):
264
- assert ( col in right )
272
+ assert col in right
265
273
lcol = left .icol (i )
266
274
rcol = right .icol (i )
267
275
assert_series_equal (lcol , rcol ,
@@ -282,44 +290,36 @@ def assert_frame_equal(left, right, check_dtype=True,
282
290
assert_attr_equal ('names' , left .columns , right .columns )
283
291
284
292
285
- def assert_panel_equal (left , right ,
286
- check_panel_type = False ,
287
- check_less_precise = False ):
293
+ def assert_panelnd_equal (left , right ,
294
+ check_panel_type = False ,
295
+ check_less_precise = False ,
296
+ assert_func = assert_frame_equal ):
288
297
if check_panel_type :
289
298
assert_isinstance (left , type (right ))
290
299
291
300
for axis in ['items' , 'major_axis' , 'minor_axis' ]:
292
- assert_index_equal (
293
- getattr (left , axis , None ), getattr (right , axis , None ))
301
+ left_ind = getattr (left , axis )
302
+ right_ind = getattr (right , axis )
303
+ assert_index_equal (left_ind , right_ind )
294
304
295
305
for col , series in compat .iteritems (left ):
296
- assert (col in right )
297
- # TODO strangely check_names fails in py3 ?
298
- assert_frame_equal (
299
- series , right [col ], check_less_precise = check_less_precise , check_names = False )
306
+ assert col in right , "non-matching column '%s'" % col
307
+ assert_func (series , right [col ], check_less_precise = check_less_precise )
300
308
301
309
for col in right :
302
- assert (col in left )
303
-
304
-
305
- def assert_panel4d_equal (left , right ,
306
- check_less_precise = False ):
307
- for axis in ['labels' , 'items' , 'major_axis' , 'minor_axis' ]:
308
- assert_index_equal (
309
- getattr (left , axis , None ), getattr (right , axis , None ))
310
-
311
- for col , series in compat .iteritems (left ):
312
- assert (col in right )
313
- assert_panel_equal (
314
- series , right [col ], check_less_precise = check_less_precise )
310
+ assert col in left
315
311
316
- for col in right :
317
- assert (col in left )
312
+ # TODO: strangely check_names fails in py3 ?
313
+ _panel_frame_equal = partial (assert_frame_equal , check_names = False )
314
+ assert_panel_equal = partial (assert_panelnd_equal ,
315
+ assert_func = _panel_frame_equal )
316
+ assert_panel4d_equal = partial (assert_panelnd_equal ,
317
+ assert_func = assert_panel_equal )
318
318
319
319
320
320
def assert_contains_all (iterable , dic ):
321
321
for k in iterable :
322
- assert ( k in dic )
322
+ assert k in dic , "Did not contain item: '%r'" % k
323
323
324
324
325
325
def getCols (k ):
@@ -986,7 +986,45 @@ def stdin_encoding(encoding=None):
986
986
sys .stdin = _stdin
987
987
988
988
989
- def assertRaisesRegexp (exception , regexp , callable , * args , ** kwargs ):
989
+ def assertRaises (_exception , _callable = None , * args , ** kwargs ):
990
+ """assertRaises that is usable as context manager or in a with statement
991
+
992
+ Exceptions that don't match the given Exception type fall through::
993
+
994
+ >>> with assertRaises(ValueError):
995
+ ... raise TypeError("banana")
996
+ ...
997
+ Traceback (most recent call last):
998
+ ...
999
+ TypeError: banana
1000
+
1001
+ If it raises the given Exception type, the test passes
1002
+ >>> with assertRaises(KeyError):
1003
+ ... dct = dict()
1004
+ ... dct["apple"]
1005
+
1006
+ If the expected error doesn't occur, it raises an error.
1007
+ >>> with assertRaises(KeyError):
1008
+ ... dct = {'apple':True}
1009
+ ... dct["apple"]
1010
+ Traceback (most recent call last):
1011
+ ...
1012
+ AssertionError: KeyError not raised.
1013
+
1014
+ In addition to using it as a contextmanager, you can also use it as a
1015
+ function, just like the normal assertRaises
1016
+
1017
+ >>> assertRaises(TypeError, ",".join, [1, 3, 5]);
1018
+ """
1019
+ manager = _AssertRaisesContextmanager (exception = _exception )
1020
+ # don't return anything if usedin function form
1021
+ if _callable is not None :
1022
+ with manager :
1023
+ _callable (* args , ** kwargs )
1024
+ else :
1025
+ return manager
1026
+
1027
+ def assertRaisesRegexp (_exception , _regexp , _callable = None , * args , ** kwargs ):
990
1028
""" Port of assertRaisesRegexp from unittest in Python 2.7 - used in with statement.
991
1029
992
1030
Explanation from standard library:
@@ -997,46 +1035,71 @@ def assertRaisesRegexp(exception, regexp, callable, *args, **kwargs):
997
1035
998
1036
You can pass either a regular expression or a compiled regular expression object.
999
1037
>>> assertRaisesRegexp(ValueError, 'invalid literal for.*XYZ',
1000
- ... int, 'XYZ')
1038
+ ... int, 'XYZ');
1001
1039
>>> import re
1002
- >>> assertRaisesRegexp(ValueError, re.compile('literal'), int, 'XYZ')
1040
+ >>> assertRaisesRegexp(ValueError, re.compile('literal'), int, 'XYZ');
1003
1041
1004
1042
If an exception of a different type is raised, it bubbles up.
1005
1043
1006
- >>> assertRaisesRegexp(TypeError, 'literal', int, 'XYZ')
1044
+ >>> assertRaisesRegexp(TypeError, 'literal', int, 'XYZ');
1007
1045
Traceback (most recent call last):
1008
1046
...
1009
1047
ValueError: invalid literal for int() with base 10: 'XYZ'
1010
- >>> dct = {}
1011
- >>> assertRaisesRegexp(KeyError, 'pear', dct.__getitem__, 'apple')
1048
+ >>> dct = dict()
1049
+ >>> assertRaisesRegexp(KeyError, 'pear', dct.__getitem__, 'apple');
1012
1050
Traceback (most recent call last):
1013
1051
...
1014
1052
AssertionError: "pear" does not match "'apple'"
1015
- >>> assertRaisesRegexp(KeyError, 'apple', dct.__getitem__, 'apple')
1016
- >>> assertRaisesRegexp(Exception, 'operand type.*int.*dict', lambda : 2 + {})
1017
- """
1018
-
1019
- import re
1020
1053
1021
- try :
1022
- callable ( * args , ** kwargs )
1023
- except Exception as e :
1024
- if not issubclass ( e . __class__ , exception ):
1025
- # mimics behavior of unittest
1026
- raise
1027
- # don't recompile
1028
- if hasattr ( regexp , "search" ):
1029
- expected_regexp = regexp
1030
- else :
1031
- expected_regexp = re . compile ( regexp )
1032
- if not expected_regexp . search ( str ( e )) :
1033
- raise AssertionError ( '"%s" does not match "%s"' %
1034
- ( expected_regexp . pattern , str ( e )) )
1054
+ You can also use this in a with statement.
1055
+ >>> with assertRaisesRegexp(TypeError, 'unsupported operand type\(s\)'):
1056
+ ... 1 + {}
1057
+ >>> with assertRaisesRegexp(TypeError, 'banana' ):
1058
+ ... 'apple'[0] = 'b'
1059
+ Traceback (most recent call last):
1060
+ ...
1061
+ AssertionError: "banana" does not match "'str' object does not support \
1062
+ item assignment"
1063
+ """
1064
+ manager = _AssertRaisesContextmanager ( exception = _exception , regexp = _regexp )
1065
+ if _callable is not None :
1066
+ with manager :
1067
+ _callable ( * args , ** kwargs )
1035
1068
else :
1036
- # Apparently some exceptions don't have a __name__ attribute? Just
1037
- # aping unittest library here
1038
- name = getattr (exception , "__name__" , str (exception ))
1039
- raise AssertionError ("{0} not raised" .format (name ))
1069
+ return manager
1070
+
1071
+
1072
+ class _AssertRaisesContextmanager (object ):
1073
+ """handles the behind the scenes work for assertRaises and assertRaisesRegexp"""
1074
+ def __init__ (self , exception , regexp = None , * args , ** kwargs ):
1075
+ self .exception = exception
1076
+ if regexp is not None and not hasattr (regexp , "search" ):
1077
+ regexp = re .compile (regexp )
1078
+ self .regexp = regexp
1079
+
1080
+ def __enter__ (self ):
1081
+ return self
1082
+
1083
+ def __exit__ (self , exc_type , exc_value , traceback ):
1084
+ expected = self .exception
1085
+ if not exc_type :
1086
+ name = getattr (expected , "__name__" , str (expected ))
1087
+ raise AssertionError ("{0} not raised." .format (name ))
1088
+ if issubclass (exc_type , expected ):
1089
+ return self .handle_success (exc_type , exc_value , traceback )
1090
+ return self .handle_failure (exc_type , exc_value , traceback )
1091
+
1092
+ def handle_failure (* args , ** kwargs ):
1093
+ # Failed, so allow Exception to bubble up
1094
+ return False
1095
+
1096
+ def handle_success (self , exc_type , exc_value , traceback ):
1097
+ if self .regexp is not None :
1098
+ val = str (exc_value )
1099
+ if not self .regexp .search (val ):
1100
+ raise AssertionError ('"%s" does not match "%s"' %
1101
+ (self .regexp .pattern , str (val )))
1102
+ return True
1040
1103
1041
1104
1042
1105
@contextmanager
0 commit comments