Index: tools/telemetry/third_party/rope/rope/base/oi/runmod.py |
diff --git a/tools/telemetry/third_party/rope/rope/base/oi/runmod.py b/tools/telemetry/third_party/rope/rope/base/oi/runmod.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..666df74cec14d1519e80ff3189c327d7208f423b |
--- /dev/null |
+++ b/tools/telemetry/third_party/rope/rope/base/oi/runmod.py |
@@ -0,0 +1,227 @@ |
+try: |
+ execfile |
+except NameError: |
+ def execfile(fn, global_vars, local_vars): |
+ with open(fn) as f: |
+ code = compile(f.read(), fn, 'exec') |
+ exec(code, global_vars, local_vars) |
+ |
+ |
+def __rope_start_everything(): |
+ import os |
+ import sys |
+ import socket |
+ try: |
+ import pickle |
+ except ImportError: |
+ import cPickle as pickle |
+ import marshal |
+ import inspect |
+ import types |
+ import threading |
+ |
+ class _MessageSender(object): |
+ |
+ def send_data(self, data): |
+ pass |
+ |
+ class _SocketSender(_MessageSender): |
+ |
+ def __init__(self, port): |
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
+ s.connect(('127.0.0.1', port)) |
+ self.my_file = s.makefile('w') |
+ |
+ def send_data(self, data): |
+ if not self.my_file.closed: |
+ pickle.dump(data, self.my_file) |
+ |
+ def close(self): |
+ self.my_file.close() |
+ |
+ class _FileSender(_MessageSender): |
+ |
+ def __init__(self, file_name): |
+ self.my_file = open(file_name, 'wb') |
+ |
+ def send_data(self, data): |
+ if not self.my_file.closed: |
+ marshal.dump(data, self.my_file) |
+ |
+ def close(self): |
+ self.my_file.close() |
+ |
+ def _cached(func): |
+ cache = {} |
+ |
+ def newfunc(self, arg): |
+ if arg in cache: |
+ return cache[arg] |
+ result = func(self, arg) |
+ cache[arg] = result |
+ return result |
+ return newfunc |
+ |
+ class _FunctionCallDataSender(object): |
+ |
+ def __init__(self, send_info, project_root): |
+ self.project_root = project_root |
+ if send_info.isdigit(): |
+ self.sender = _SocketSender(int(send_info)) |
+ else: |
+ self.sender = _FileSender(send_info) |
+ |
+ def global_trace(frame, event, arg): |
+ # HACK: Ignoring out->in calls |
+ # This might lose some information |
+ if self._is_an_interesting_call(frame): |
+ return self.on_function_call |
+ sys.settrace(global_trace) |
+ threading.settrace(global_trace) |
+ |
+ def on_function_call(self, frame, event, arg): |
+ if event != 'return': |
+ return |
+ args = [] |
+ returned = ('unknown',) |
+ code = frame.f_code |
+ for argname in code.co_varnames[:code.co_argcount]: |
+ try: |
+ args.append(self._object_to_persisted_form( |
+ frame.f_locals[argname])) |
+ except (TypeError, AttributeError): |
+ args.append(('unknown',)) |
+ try: |
+ returned = self._object_to_persisted_form(arg) |
+ except (TypeError, AttributeError): |
+ pass |
+ try: |
+ data = (self._object_to_persisted_form(frame.f_code), |
+ tuple(args), returned) |
+ self.sender.send_data(data) |
+ except (TypeError): |
+ pass |
+ return self.on_function_call |
+ |
+ def _is_an_interesting_call(self, frame): |
+ #if frame.f_code.co_name in ['?', '<module>']: |
+ # return False |
+ #return not frame.f_back or |
+ # not self._is_code_inside_project(frame.f_back.f_code) |
+ |
+ if not self._is_code_inside_project(frame.f_code) and \ |
+ (not frame.f_back or |
+ not self._is_code_inside_project(frame.f_back.f_code)): |
+ return False |
+ return True |
+ |
+ def _is_code_inside_project(self, code): |
+ source = self._path(code.co_filename) |
+ return source is not None and os.path.exists(source) and \ |
+ _realpath(source).startswith(self.project_root) |
+ |
+ @_cached |
+ def _get_persisted_code(self, object_): |
+ source = self._path(object_.co_filename) |
+ if not os.path.exists(source): |
+ raise TypeError('no source') |
+ return ('defined', _realpath(source), str(object_.co_firstlineno)) |
+ |
+ @_cached |
+ def _get_persisted_class(self, object_): |
+ try: |
+ return ('defined', _realpath(inspect.getsourcefile(object_)), |
+ object_.__name__) |
+ except (TypeError, AttributeError): |
+ return ('unknown',) |
+ |
+ def _get_persisted_builtin(self, object_): |
+ if isinstance(object_, (str, unicode)): |
+ return ('builtin', 'str') |
+ if isinstance(object_, list): |
+ holding = None |
+ if len(object_) > 0: |
+ holding = object_[0] |
+ return ('builtin', 'list', |
+ self._object_to_persisted_form(holding)) |
+ if isinstance(object_, dict): |
+ keys = None |
+ values = None |
+ if len(object_) > 0: |
+ keys = object_.keys()[0] |
+ values = object_[keys] |
+ return ('builtin', 'dict', |
+ self._object_to_persisted_form(keys), |
+ self._object_to_persisted_form(values)) |
+ if isinstance(object_, tuple): |
+ objects = [] |
+ if len(object_) < 3: |
+ for holding in object_: |
+ objects.append(self._object_to_persisted_form(holding)) |
+ else: |
+ objects.append(self._object_to_persisted_form(object_[0])) |
+ return tuple(['builtin', 'tuple'] + objects) |
+ if isinstance(object_, set): |
+ holding = None |
+ if len(object_) > 0: |
+ for o in object_: |
+ holding = o |
+ break |
+ return ('builtin', 'set', |
+ self._object_to_persisted_form(holding)) |
+ return ('unknown',) |
+ |
+ def _object_to_persisted_form(self, object_): |
+ if object_ is None: |
+ return ('none',) |
+ if isinstance(object_, types.CodeType): |
+ return self._get_persisted_code(object_) |
+ if isinstance(object_, types.FunctionType): |
+ return self._get_persisted_code(object_.__code__) |
+ if isinstance(object_, types.MethodType): |
+ return self._get_persisted_code(object_.__func__.__code__) |
+ if isinstance(object_, types.ModuleType): |
+ return self._get_persisted_module(object_) |
+ if isinstance(object_, (str, unicode, list, dict, tuple, set)): |
+ return self._get_persisted_builtin(object_) |
+ if isinstance(object_, type): |
+ return self._get_persisted_class(object_) |
+ return ('instance', self._get_persisted_class(type(object_))) |
+ |
+ @_cached |
+ def _get_persisted_module(self, object_): |
+ path = self._path(object_.__file__) |
+ if path and os.path.exists(path): |
+ return ('defined', _realpath(path)) |
+ return ('unknown',) |
+ |
+ def _path(self, path): |
+ if path.endswith('.pyc'): |
+ path = path[:-1] |
+ if path.endswith('.py'): |
+ return path |
+ |
+ def close(self): |
+ self.sender.close() |
+ sys.settrace(None) |
+ |
+ def _realpath(path): |
+ return os.path.realpath(os.path.abspath(os.path.expanduser(path))) |
+ |
+ send_info = sys.argv[1] |
+ project_root = sys.argv[2] |
+ file_to_run = sys.argv[3] |
+ run_globals = globals() |
+ run_globals.update({'__name__': '__main__', |
+ '__builtins__': __builtins__, |
+ '__file__': file_to_run}) |
+ if send_info != '-': |
+ data_sender = _FunctionCallDataSender(send_info, project_root) |
+ del sys.argv[1:4] |
+ execfile(file_to_run, run_globals) |
+ if send_info != '-': |
+ data_sender.close() |
+ |
+ |
+if __name__ == '__main__': |
+ __rope_start_everything() |