| 1 |  |  | from weakref import ref | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | import re | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | import sys | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | from hamcrest.core.base_matcher import BaseMatcher | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | from hamcrest.core.helpers.wrap_matcher import wrap_matcher | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | from hamcrest.core.compat import is_callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | __author__ = "Per Fagrell" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | __copyright__ = "Copyright 2013 hamcrest.org" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | __license__ = "BSD, see License.txt" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | class Raises(BaseMatcher): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     def __init__(self, expected, pattern=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |         self.pattern = pattern | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |         self.expected = expected | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |         self.actual = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |         self.function = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     def _matches(self, function): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |         if not is_callable(function): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |             return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |         self.function = ref(function) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |         return self._call_function(function) | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 26 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  |     def _call_function(self, function): | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  |         self.actual = None | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |         try: | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |             function() | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |         except Exception: | 
            
                                                                        
                            
            
                                    
            
            
                | 32 |  |  |             self.actual = sys.exc_info()[1] | 
            
                                                                        
                            
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 34 |  |  |             if isinstance(self.actual, self.expected): | 
            
                                                                        
                            
            
                                    
            
            
                | 35 |  |  |                 if self.pattern is not None: | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |                     return re.search(self.pattern, str(self.actual)) is not None | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |                 return True | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     def describe_to(self, description): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |         description.append_text('Expected a callable raising %s' % self.expected) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     def describe_mismatch(self, item, description): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         if not is_callable(item): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             description.append_text('%s is not callable' % item) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |             return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         function = None if self.function is None else self.function() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         if function is None or function is not item: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |             self.function = ref(item) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |             if not self._call_function(item): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                 return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         if self.actual is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |             description.append_text('No exception raised.') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |         elif isinstance(self.actual, self.expected) and self.pattern is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |             description.append_text('Correct assertion type raised, but the expected pattern ("%s") not found.' % self.pattern) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |             description.append_text('\n          message was: "%s"' % str(self.actual)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             description.append_text('%s was raised instead' % type(self.actual)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  | def raises(exception, pattern=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |     """Matches if the called function raised the expected exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |     :param exception:  The class of the expected exception | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |     :param pattern:    Optional regular expression to match exception message. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |     Expects the actual to be wrapped by using :py:func:`~hamcrest.core.core.raises.calling`, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |     or a callable taking no arguments. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |     Optional argument pattern should be a string containing a regular expression.  If provided, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |     the string representation of the actual exception - e.g. `str(actual)` - must match pattern. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     Examples:: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         assert_that(calling(int).with_args('q'), raises(TypeError)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         assert_that(calling(parse, broken_input), raises(ValueError)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |     return Raises(exception, pattern) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  | class DeferredCallable(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     def __init__(self, func): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         self.func = func | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         self.args = tuple() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         self.kwargs = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     def __call__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         self.func(*self.args, **self.kwargs) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     def with_args(self, *args, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |         self.args = args | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         self.kwargs = kwargs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         return self | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  | def calling(func): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     """Wrapper for function call that delays the actual execution so that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |     :py:func:`~hamcrest.core.core.raises.raises` matcher can catch any thrown exception. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |     :param func: The function or method to be called | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     The arguments can be provided with a call to the `with_args` function on the returned | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |     object:: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |            calling(my_method).with_args(arguments, and_='keywords') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     """ | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 108 |  |  |     return DeferredCallable(func) | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |  |