Exemple #1
0
 def test_callee_throws(self, collector):
     with trace_calls(collector):
         try:
             throw(should_recover=False)
         except Exception:
             pass
     assert collector.traces == [CallTrace(throw, {'should_recover': bool})]
Exemple #2
0
 def test_generator_trace(self, collector):
     with trace_calls(collector):
         for _ in squares(3):
             pass
     assert collector.traces == [
         CallTrace(squares, {'n': int}, NoneType, int)
     ]
Exemple #3
0
 def test_nested_callee_throws_recovers(self, collector):
     with trace_calls(collector):
         nested_throw(should_recover=True)
     expected = [
         CallTrace(throw, {'should_recover': bool}, NoneType),
         CallTrace(nested_throw, {'should_recover': bool}, str),
     ]
     assert collector.traces == expected
Exemple #4
0
 def __enter__(Logger):
     global __name__
     Logger.name = __name__
     if __name__ == '__main__':
         __name__ = 'main'
     Logger.ctx = trace_calls(Logger)
     Logger.ctx.__enter__()
     return Logger
Exemple #5
0
 def test_caller_handles_callee_exception(self, collector):
     with trace_calls(collector):
         recover_from_nested_throw()
     expected = [
         CallTrace(throw, {'should_recover': bool}),
         CallTrace(recover_from_nested_throw, {}, str),
     ]
     assert collector.traces == expected
Exemple #6
0
 def test_access_property(self, collector):
     """Check that we correctly trace functions decorated with @property"""
     o = Oracle()
     with trace_calls(collector):
         o.meaning_of_life
     assert collector.traces == [
         CallTrace(Oracle.meaning_of_life.fget, {'self': Oracle}, int)
     ]
Exemple #7
0
 def test_simple_call(self, collector):
     with trace_calls(collector):
         simple_add(1, 2)
     assert collector.traces == [
         CallTrace(simple_add, {
             'a': int,
             'b': int
         }, int)
     ]
Exemple #8
0
def test_round_trip(logger):
    with patch.object(main_func, '__module__', '__main__'):
        with trace_calls(logger):
            main_func(int, str)
            assert not logger.traces
            normal_func(int, str)
            assert logger.traces

    assert not logger.store.filter('__main__')
    assert logger.store.filter(normal_func.__module__)
Exemple #9
0
 def test_return_none(self, collector):
     """Ensure traces have a return_type of NoneType for functions that return a value of None"""
     with trace_calls(collector):
         implicit_return_none()
         explicit_return_none()
     expected = [
         CallTrace(implicit_return_none, {}, NoneType),
         CallTrace(explicit_return_none, {}, NoneType),
     ]
     assert collector.traces == expected
Exemple #10
0
 def test_filtering(self, collector):
     """If supplied, the code filter should decide which code objects are traced"""
     with trace_calls(collector, lambda code: code.co_name == 'simple_add'):
         simple_add(1, 2)
         explicit_return_none()
     assert collector.traces == [
         CallTrace(simple_add, {
             'a': int,
             'b': int
         }, int)
     ]
Exemple #11
0
    def test_cython_wrapper(self, collector):
        """Check that we can dig through Cython wrappers in looking for methods.

        As long as the Cython decorator sets __wrapped__ correctly, anyway.
        """
        cython_test_obj = CythonTest()
        with trace_calls(collector, max_typed_dict_size=0):
            cython_test_obj.cython_testfunc()

        trace = CallTrace(cython_test_obj.cython_testfunc.__wrapped__, {'self': CythonTest}, int)
        assert trace in collector.traces
Exemple #12
0
 def test_nested_callee_throws_caller_doesnt_recover(self, collector):
     with trace_calls(collector):
         try:
             nested_throw(should_recover=False)
         except Exception:
             pass
     expected = [
         CallTrace(throw, {'should_recover': bool}),
         CallTrace(nested_throw, {'should_recover': bool}),
     ]
     assert collector.traces == expected
Exemple #13
0
def trace(config: Optional[Config] = None) -> ContextManager:
    """Context manager to trace and log all calls.

    Simple wrapper around `monkeytype.tracing.trace_calls` that uses trace
    logger, code filter, and sample rate from given (or default) config.
    """
    if config is None:
        config = get_default_config()
    return trace_calls(
        logger=config.trace_logger(),
        code_filter=config.code_filter(),
        sample_rate=config.sample_rate(),
    )
Exemple #14
0
    def test_lazy_value(self, collector):
        """Check that function lookup does not invoke custom descriptors.

        LazyValue is an interesting corner case. Internally, LazyValue stores a
        function and its arguments. When LazyValue.value is accessed for the
        first time, the stored function will be invoked, and its return value
        will be set as the value of LazyValue.value. Additionally, and this is
        important, the reference to the stored function and its arguments are
        cleared.

        When tracing, accessing LazyValue.value generates a 'call' event for a
        function named 'value'.  At the point where we receive the call event,
        the LazyValue.value function is about to begin execution. If we attempt
        to find the called function using getattr, value will be invoked again,
        and the reference to the stored function and its arguments will be
        cleared.  At this point the original call to LazyValue.value will
        resume execution, however, the stored arguments will have been cleared,
        and the attempt to invoke the stored function will fail.
        """
        lazy_val = LazyValue(explicit_return_none)
        with trace_calls(collector):
            lazy_val.value
Exemple #15
0
    def test_flushes(self, collector):
        with trace_calls(collector, max_typed_dict_size=0):
            pass

        assert collector.flushed
Exemple #16
0
 def test_callee_throws_recovers(self, collector):
     with trace_calls(collector):
         throw(should_recover=True)
     assert collector.traces == [
         CallTrace(throw, {'should_recover': bool}, NoneType)
     ]
Exemple #17
0
    def test_flushes(self, collector):
        with trace_calls(collector):
            pass

        assert collector.flushed