Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 68 lines (60 sloc) 1.733 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
import sys
import inspect
import traceback
import copy

_current_frame = None

_watched_expr = None
_watched_locals = None
_watched_globals = None

_value_id = None
_value_dump = None

def watch(expr):
    global _watched_expr, _watched_locals, _watched_globals
    frame = sys._getframe(1)
    _watched_expr = expr
    _watched_locals = frame.f_locals
    _watched_globals = frame.f_globals
    _record()
    sys.settrace(_instrument)

def tag(val):
    try:
        return hash(val)
    except TypeError:
        pass
    return copy.copy(val)

def _record():
    global _value_id, _value_dump
    try:
        obj = eval(_watched_expr, _watched_locals, _watched_globals)
        _value_id = id(obj)
        _value_dump = tag(obj)
    except NameError:
        _value_id = None
        _value_dump = None

def _instrument(frame, event, arg):
    global _current_frame
    old_value_id = _value_id
    old_value_dump = _value_dump
    #traceback.print_stack(frame)
    _record()
    if old_value_id is None and _value_id is None:
        pass
    elif old_value_id is None and _value_id is not None:
        print "Initialized by:"
        traceback.print_stack(_current_frame)
    else:
        id_eq = old_value_id == _value_id
        dump_eq = old_value_dump == _value_dump
        if id_eq and dump_eq:
            pass
        elif id_eq and not dump_eq:
            print "Mutated by:"
            traceback.print_stack(_current_frame)
        elif not id_eq and dump_eq:
            print "Replaced with equivalent object by:"
            traceback.print_stack(_current_frame)
        else:
            print "Replaced by:"
            traceback.print_stack(_current_frame)
    _current_frame = frame
    return _instrument
Something went wrong with that request. Please try again.