def test_depth_limit(LineMatcher, depth): buff = StringIO() from sample7 import one tracer = hunter.Tracer() predicate = When(Q(depth_lt=depth), CallPrinter(stream=buff)) try: tracer.trace(predicate) one() finally: tracer.stop() output = buff.getvalue() lm = LineMatcher(output.splitlines()) lm.fnmatch_lines([ "* call => one()", "* line for i in range(1): # one", "* line two()", "* call => two()", "* return <= two: None", "* line for i in range(1): # one", "* return <= one: None", ]) if depth < 3: assert 'three' not in output if depth < 4: assert 'four' not in output if depth < 5: assert 'five' not in output
def tracing_wrapper(*args, **kwargs): # create the Tracer manually to avoid spending time in likely useless things like: # - loading PYTHONHUNTERCONFIG # - setting up the clear_env_var or thread_support options # - atexit cleanup registration with hunter.Tracer().trace( hunter.When(hunter.Query(**filters), *actions)): return func(*args, **kwargs)
def mockevent(): return hunter.Event(sys._getframe(0), 'line', None, hunter.Tracer())
def probe_wrapper(*args, **kwargs): now = datetime.datetime.utcnow() hotspots = HotspotsFinder() instruments_by_event = {"call": [], "return": [], "end": []} for I in self.instruments.itervalues(): if I.expires and now > I.expires: continue if I.check_call(self, *args, **kwargs): instruments_by_event[I.event].append(I) if I.event in ("call", "return"): if "hotspots" in I.value or "hotspots" in ( I.custom.get("tags") or "" ): hotspots.enabled = True target_obj, target_func_name = self.target.rsplit(".", 1) is_unwrapped = base.__code__.co_name == target_func_name if instruments_by_event["end"]: # We have instruments that require evaluation in the local # context of the function. Call sys.settrace() to gain access. predicate = hunter.When( hunter.Query( # Only trace returns (this will include exceptions!)... kind="return", # ...and only in the given function... function=target_func_name, # ...(no deeper). depth=0, ) if is_unwrapped else hunter.Query( # Only trace returns (this will include exceptions!)... kind="return", # ...and only in the given function... function=target_func_name, # ...but we don't know how many times it's been wrapped. # Use the module instead as an approximate match. # This may catch other functions with the same name # in the same module, but not much we can do about # that without a custom Cython Query. module_in=target_obj, ), TraceHandler(self, instruments_by_event["end"]), ) tracer = hunter.Tracer( # There's no need to call threading.settrace() because # a) we're targeting a function we're about to call # in the same thread, # b) we're going to undo it immediately after, and # c) it would collide with other threads if they did # the same concurrently. threading_support=False ).trace(predicate) elif hotspots.enabled: # We have instruments that require timing internal lines. # Call sys.settrace() to gain access. predicate = hunter.When( hunter.Query( # Only trace lines... kind="line", # ...and only in the given function... function=target_func_name, # ...(no deeper). depth=1, ) if is_unwrapped else hunter.Query( # Only trace lines... kind="line", # ...and only in the given function... function=target_func_name, # ...but we don't know how many times it's been wrapped. # Use the module instead as an approximate match. # This may catch other functions with the same name # in the same module, but not much we can do about # that without a custom Cython Query. module_in=target_obj, ), hotspots, ) tracer = hunter.Tracer( # There's no need to call threading.settrace() because # a) we're targeting a function we're about to call # in the same thread, # b) we're going to undo it immediately after, and # c) it would collide with other threads if they did # the same concurrently. threading_support=False ).trace(predicate) else: tracer = None try: if instruments_by_event["call"] or instruments_by_event["return"]: start = time.time() _locals = { "start": start, "now": now, "args": args, "kwargs": kwargs, "frame": sys._getframe(), } # Add positional args to locals by name. for i, argname in enumerate(varnames[: len(args)]): if argname not in ("args", "kwargs"): _locals[argname] = args[i] # Add kwargs to locals _locals.update(kwargs) for instrument in instruments_by_event["call"]: try: instrument.fire(instrument.mgr.global_namespace, _locals) except: try: instrument.handle_error(self) except: traceback.print_exc() # Execute the base function and obtain its result. try: result = base(*args, **kwargs) except: result = sys.exc_info()[1] raise finally: if hotspots.enabled: hotspots.finish() _locals["hotspots"] = hotspots if instruments_by_event["return"]: end = time.time() elapsed = end - start _locals.update( {"result": result, "end": end, "elapsed": elapsed} ) for instrument in instruments_by_event["return"]: try: instrument.fire(instrument.mgr.global_namespace, _locals) except: try: instrument.handle_error(self) except: traceback.print_exc() return result finally: if tracer is not None: tracer.stop()
def mockevent(): return hunter.Event(sys._getframe(0), 2 if '_event' in hunter.Event.__module__ else 'line', None, hunter.Tracer())