creeper-adventure/.venv/lib/python3.8/site-packages/rope/base/oi/runmod.py
2022-03-31 20:20:07 -05:00

240 lines
8.3 KiB
Python

def __rope_start_everything():
import os
import sys
import socket
try:
import cPickle as pickle
except ImportError:
import pickle
import marshal
import inspect
import types
import threading
import rope.base.utils.pycompat as pycompat
import base64
import hashlib
import hmac
class _MessageSender(object):
def send_data(self, data):
pass
class _SocketSender(_MessageSender):
def __init__(self, port, key):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", port))
self.my_file = s.makefile("wb")
self.key = base64.b64decode(key)
def send_data(self, data):
if not self.my_file.closed:
pickled_data = base64.b64encode(
pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
)
dgst = hmac.new(self.key, pickled_data, hashlib.sha256).digest()
self.my_file.write(base64.b64encode(dgst) + b":" + pickled_data + b"\n")
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[0].isdigit():
port, key = send_info.split(":", 1)
self.sender = _SocketSender(int(port), key)
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:
argvalue = self._object_to_persisted_form(frame.f_locals[argname])
args.append(argvalue)
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_, pycompat.string_types):
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:
# @todo - fix it properly, why is __locals__ being
# duplicated ?
keys = [key for key in object_.keys() if key != "__locals__"][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_, pycompat.string_types + (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]
pycompat.execfile(file_to_run, run_globals)
if send_info != "-":
data_sender.close()
if __name__ == "__main__":
__rope_start_everything()