Path: blob/master/elisp/emacs-for-python/rope-dist/rope/base/oi/runmod.py
1439 views
1def __rope_start_everything():2import os3import sys4import socket5import cPickle as pickle6import marshal7import inspect8import types9import threading1011class _MessageSender(object):1213def send_data(self, data):14pass1516class _SocketSender(_MessageSender):1718def __init__(self, port):19s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)20s.connect(('127.0.0.1', port))21self.my_file = s.makefile('w')2223def send_data(self, data):24if not self.my_file.closed:25pickle.dump(data, self.my_file)2627def close(self):28self.my_file.close()2930class _FileSender(_MessageSender):3132def __init__(self, file_name):33self.my_file = open(file_name, 'wb')3435def send_data(self, data):36if not self.my_file.closed:37marshal.dump(data, self.my_file)3839def close(self):40self.my_file.close()414243def _cached(func):44cache = {}45def newfunc(self, arg):46if arg in cache:47return cache[arg]48result = func(self, arg)49cache[arg] = result50return result51return newfunc5253class _FunctionCallDataSender(object):5455def __init__(self, send_info, project_root):56self.project_root = project_root57if send_info.isdigit():58self.sender = _SocketSender(int(send_info))59else:60self.sender = _FileSender(send_info)6162def global_trace(frame, event, arg):63# HACK: Ignoring out->in calls64# This might lose some information65if self._is_an_interesting_call(frame):66return self.on_function_call67sys.settrace(global_trace)68threading.settrace(global_trace)6970def on_function_call(self, frame, event, arg):71if event != 'return':72return73args = []74returned = ('unknown',)75code = frame.f_code76for argname in code.co_varnames[:code.co_argcount]:77try:78args.append(self._object_to_persisted_form(frame.f_locals[argname]))79except (TypeError, AttributeError):80args.append(('unknown',))81try:82returned = self._object_to_persisted_form(arg)83except (TypeError, AttributeError):84pass85try:86data = (self._object_to_persisted_form(frame.f_code),87tuple(args), returned)88self.sender.send_data(data)89except (TypeError):90pass91return self.on_function_call9293def _is_an_interesting_call(self, frame):94#if frame.f_code.co_name in ['?', '<module>']:95# return False96#return not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code)9798if not self._is_code_inside_project(frame.f_code) and \99(not frame.f_back or not self._is_code_inside_project(frame.f_back.f_code)):100return False101return True102103def _is_code_inside_project(self, code):104source = self._path(code.co_filename)105return source is not None and os.path.exists(source) and \106_realpath(source).startswith(self.project_root)107108@_cached109def _get_persisted_code(self, object_):110source = self._path(object_.co_filename)111if not os.path.exists(source):112raise TypeError('no source')113return ('defined', _realpath(source), str(object_.co_firstlineno))114115@_cached116def _get_persisted_class(self, object_):117try:118return ('defined', _realpath(inspect.getsourcefile(object_)),119object_.__name__)120except (TypeError, AttributeError):121return ('unknown',)122123def _get_persisted_builtin(self, object_):124if isinstance(object_, (str, unicode)):125return ('builtin', 'str')126if isinstance(object_, list):127holding = None128if len(object_) > 0:129holding = object_[0]130return ('builtin', 'list', self._object_to_persisted_form(holding))131if isinstance(object_, dict):132keys = None133values = None134if len(object_) > 0:135keys = object_.keys()[0]136values = object_[keys]137return ('builtin', 'dict',138self._object_to_persisted_form(keys),139self._object_to_persisted_form(values))140if isinstance(object_, tuple):141objects = []142if len(object_) < 3:143for holding in object_:144objects.append(self._object_to_persisted_form(holding))145else:146objects.append(self._object_to_persisted_form(object_[0]))147return tuple(['builtin', 'tuple'] + objects)148if isinstance(object_, set):149holding = None150if len(object_) > 0:151for o in object_:152holding = o153break154return ('builtin', 'set', self._object_to_persisted_form(holding))155return ('unknown',)156157def _object_to_persisted_form(self, object_):158if object_ is None:159return ('none',)160if isinstance(object_, types.CodeType):161return self._get_persisted_code(object_)162if isinstance(object_, types.FunctionType):163return self._get_persisted_code(object_.func_code)164if isinstance(object_, types.MethodType):165return self._get_persisted_code(object_.im_func.func_code)166if isinstance(object_, types.ModuleType):167return self._get_persisted_module(object_)168if isinstance(object_, (str, unicode, list, dict, tuple, set)):169return self._get_persisted_builtin(object_)170if isinstance(object_, (types.TypeType, types.ClassType)):171return self._get_persisted_class(object_)172return ('instance', self._get_persisted_class(type(object_)))173174@_cached175def _get_persisted_module(self, object_):176path = self._path(object_.__file__)177if path and os.path.exists(path):178return ('defined', _realpath(path))179return ('unknown',)180181def _path(self, path):182if path.endswith('.pyc'):183path = path[:-1]184if path.endswith('.py'):185return path186187def close(self):188self.sender.close()189190def _realpath(path):191return os.path.realpath(os.path.abspath(os.path.expanduser(path)))192193send_info = sys.argv[1]194project_root = sys.argv[2]195file_to_run = sys.argv[3]196run_globals = globals()197run_globals.update({'__name__': '__main__',198'__builtins__': __builtins__,199'__file__': file_to_run})200if send_info != '-':201data_sender = _FunctionCallDataSender(send_info, project_root)202del sys.argv[1:4]203execfile(file_to_run, run_globals)204if send_info != '-':205data_sender.close()206207208if __name__ == '__main__':209__rope_start_everything()210211212