From 4a7ade900ef237c6ffdb90c756cb229518e1042f Mon Sep 17 00:00:00 2001 From: Andy Hayden Date: Sat, 27 Jun 2015 22:50:54 -0700 Subject: [PATCH 1/2] Apply autopep8 to all python files. --- py-src/ltipy.py | 322 +++++++++++++------------ py-src/ltmain.py | 592 ++++++++++++++++++++++++---------------------- py-src/lttools.py | 63 ++--- 3 files changed, 519 insertions(+), 458 deletions(-) diff --git a/py-src/ltipy.py b/py-src/ltipy.py index f3229c5..b8120e0 100644 --- a/py-src/ltipy.py +++ b/py-src/ltipy.py @@ -9,8 +9,9 @@ import pickle import json + def noop(): - pass + pass ipy = None respond = None @@ -18,6 +19,7 @@ def noop(): connected = noop disconnected = noop + def km_from_string(s=''): """create kernel manager from IPKernelApp string such as '--shell=47378 --iopub=39859 --stdin=36778 --hb=52668' for IPython 0.11 @@ -41,14 +43,14 @@ def km_from_string(s=''): s = s.replace('--existing', '') if '--profile' in s: - k,p = s.split('--profile') - k = k.lstrip().rstrip() # kernel part of the string - p = p.lstrip().rstrip() # profile part of the string - fullpath = find_connection_file(k,p) + k, p = s.split('--profile') + k = k.lstrip().rstrip() # kernel part of the string + p = p.lstrip().rstrip() # profile part of the string + fullpath = find_connection_file(k, p) else: fullpath = find_connection_file(s.lstrip().rstrip()) - km = KernelManager(connection_file = fullpath) + km = KernelManager(connection_file=fullpath) km.load_connection_file() km.start_channels() send = km.shell_channel.execute @@ -56,188 +58,204 @@ def km_from_string(s=''): respond(None, "python.client.error.ipython-version", None) return - s = s.replace('--existing', '') if '--profile' in s: - k,p = s.split('--profile') - k = k.lstrip().rstrip() # kernel part of the string - p = p.lstrip().rstrip() # profile part of the string - fullpath = find_connection_file(k,p) + k, p = s.split('--profile') + k = k.lstrip().rstrip() # kernel part of the string + p = p.lstrip().rstrip() # profile part of the string + fullpath = find_connection_file(k, p) else: fullpath = find_connection_file(s.lstrip().rstrip()) - km = KernelManager(connection_file = fullpath) + km = KernelManager(connection_file=fullpath) km.load_connection_file() kc = km.client() kc.start_channels() send = kc.shell_channel.execute return km + def _extract_traceback(traceback): - # strip ANSI color controls - strip = re.compile('\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]') - return [strip.sub('',t) for t in traceback] + # strip ANSI color controls + strip = re.compile('\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]') + return [strip.sub('', t) for t in traceback] + def msgId(m): - if 'parent_header' in m and 'msg_id' in m['parent_header']: - return m['parent_header']['msg_id'] + if 'parent_header' in m and 'msg_id' in m['parent_header']: + return m['parent_header']['msg_id'] + def normalize(m): - mid = msgId(m) - content = m['content'] - - data = {} - if 'data' in content: - data = m['content']['data'] - - if 'image/png' in data: - return {'mid': mid, 'type': 'image', 'data': data['image/png']} - if 'text/plain' in data: - return {'mid': mid, 'type': 'return', 'data': data['text/plain']} - if 'traceback' in content: - return {'mid': mid, 'type': 'ex', 'data': "\n".join(_extract_traceback(content['traceback']))} - if 'name' in content and content['name'] == 'stdout': - return {'mid': mid, 'type': 'out', 'data': data} - if 'name' in content and content['name'] == 'stderr': - return {'mid': mid, 'type': 'err', 'data': data} - if 'execution_state' in content and content['execution_state'] == 'idle': - return {'mid': mid, 'type':'done'} - - content['type'] = "unknown" - content['mid'] = mid - return content + mid = msgId(m) + content = m['content'] + + data = {} + if 'data' in content: + data = m['content']['data'] + + if 'image/png' in data: + return {'mid': mid, 'type': 'image', 'data': data['image/png']} + if 'text/plain' in data: + return {'mid': mid, 'type': 'return', 'data': data['text/plain']} + if 'traceback' in content: + return {'mid': mid, 'type': 'ex', 'data': "\n".join(_extract_traceback(content['traceback']))} + if 'name' in content and content['name'] == 'stdout': + return {'mid': mid, 'type': 'out', 'data': data} + if 'name' in content and content['name'] == 'stderr': + return {'mid': mid, 'type': 'err', 'data': data} + if 'execution_state' in content and content['execution_state'] == 'idle': + return {'mid': mid, 'type': 'done'} + + content['type'] = "unknown" + content['mid'] = mid + return content + def msgs(): - global kc - msgs = kc.iopub_channel.get_msgs() - return [normalize(i) for i in msgs] + global kc + msgs = kc.iopub_channel.get_msgs() + return [normalize(i) for i in msgs] + def handleMsg(m): - if not m['mid']: - return - - try: - orig = requests[m['mid']] - except: - return - - command = None - ret = {'meta': orig['meta']} - - if m['type'] == 'return': - orig['return'] = True - command = 'editor.eval.python.result' - ret['result'] = m['data'] - elif m['type'] == 'ex': - orig['return'] = True - command = 'editor.eval.python.exception' - ret['ex'] = m['data'] - elif m['type'] == 'image': - command = 'editor.eval.python.image' - ret['image'] = m['data'] - elif m['type'] == 'out': - if m['data'][0:7] == "__WATCH": - command = None - try: - res = pickle.loads(m['data'][8:]) - except: - pass - respond(None, "clients.raise-on-object", [res["meta"]["obj"], "editor.eval.python.watch", res]) - else: - command = 'editor.eval.python.print' - ret['file'] = orig['path'] - ret['msg'] = m['data'] - elif m['type'] == 'done' and orig['evaltype'] == 'statement' and 'return' not in orig: - orig['return'] = True - command = 'editor.eval.python.success' - elif m['type'] == 'done' and orig['evaltype'] == 'expression' and 'return' not in orig: - orig['return'] = True - command = 'editor.eval.python.result' - ret['result'] = 'None' - - if command: - respond(orig["client"], command, ret) + if not m['mid']: + return + + try: + orig = requests[m['mid']] + except: + return + + command = None + ret = {'meta': orig['meta']} + + if m['type'] == 'return': + orig['return'] = True + command = 'editor.eval.python.result' + ret['result'] = m['data'] + elif m['type'] == 'ex': + orig['return'] = True + command = 'editor.eval.python.exception' + ret['ex'] = m['data'] + elif m['type'] == 'image': + command = 'editor.eval.python.image' + ret['image'] = m['data'] + elif m['type'] == 'out': + if m['data'][0:7] == "__WATCH": + command = None + try: + res = pickle.loads(m['data'][8:]) + except: + pass + respond(None, "clients.raise-on-object", + [res["meta"]["obj"], "editor.eval.python.watch", res]) + else: + command = 'editor.eval.python.print' + ret['file'] = orig['path'] + ret['msg'] = m['data'] + elif m['type'] == 'done' and orig['evaltype'] == 'statement' and 'return' not in orig: + orig['return'] = True + command = 'editor.eval.python.success' + elif m['type'] == 'done' and orig['evaltype'] == 'expression' and 'return' not in orig: + orig['return'] = True + command = 'editor.eval.python.result' + ret['result'] = 'None' + + if command: + respond(orig["client"], command, ret) + def msgloop(): - global ipy - while not ipy.returncode and not ltmain.stopped(): - for m in msgs(): - handleMsg(m) - time.sleep(0.01) + global ipy + while not ipy.returncode and not ltmain.stopped(): + for m in msgs(): + handleMsg(m) + time.sleep(0.01) + def initIPy(s): - try: - cur = km_from_string(s) + try: + cur = km_from_string(s) + + if not cur: + killIPy() + disconnected() - if not cur: - killIPy() - disconnected() + loc = os.path.dirname(__file__) + send("import sys\nsys.path.append('" + + loc.replace('\\', '\\\\') + "')\nimport lttools") + connected() + msgloop() + disconnected() + except: + disconnected() - loc = os.path.dirname(__file__) - send("import sys\nsys.path.append('" + loc.replace('\\','\\\\') + "')\nimport lttools") - connected() - msgloop() - disconnected() - except: - disconnected() def setNs(path): - send("import lttools\nlttools.switch_ns('" + path.replace('\\', '\\\\') + "')") + send( + "import lttools\nlttools.switch_ns('" + path.replace('\\', '\\\\') + "')") + def IPyOutput(l): - m = re.search('--existing (.*\.json)', l) - if m: - initIPy(m.group(1)) - if re.search('ImportError: IPython.zmq', l): - respond(None, "python.client.error.pyzmq", None) + m = re.search('--existing (.*\.json)', l) + if m: + initIPy(m.group(1)) + if re.search('ImportError: IPython.zmq', l): + respond(None, "python.client.error.pyzmq", None) + def listenIPy(): - global ipy - while True: - #next_line = proc.communicate()[0] - next_line = ipy.stdout.readline().decode('utf-8') - if next_line == '' and ipy.poll() != None: - disconnected() - break - IPyOutput(next_line) + global ipy + while True: + #next_line = proc.communicate()[0] + next_line = ipy.stdout.readline().decode('utf-8') + if next_line == '' and ipy.poll() != None: + disconnected() + break + IPyOutput(next_line) + def startIPy(opts): - global ipy - global respond - global disconnected - global connected - global km - respond = opts["respond"] - connected = opts["connected"] - disconnected = opts["disconnected"] - - try: - if os.environ.get('LT_IPYTHON_PATH'): - cmd = os.environ.get('LT_IPYTHON_PATH') - elif os.path.isfile('bin/ipython'): - cmd = 'bin/ipython' - else: - cmd = 'ipython' - ipy = subprocess.Popen([cmd, 'kernel', '--pylab=inline'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=os.environ) - #Start a thread listening to stdout - t = threading.Thread(target=listenIPy) - t.start() - return True - except: - disconnected() - return None + global ipy + global respond + global disconnected + global connected + global km + respond = opts["respond"] + connected = opts["connected"] + disconnected = opts["disconnected"] + + try: + if os.environ.get('LT_IPYTHON_PATH'): + cmd = os.environ.get('LT_IPYTHON_PATH') + elif os.path.isfile('bin/ipython'): + cmd = 'bin/ipython' + else: + cmd = 'ipython' + ipy = subprocess.Popen([cmd, 'kernel', '--pylab=inline'], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=os.environ) + # Start a thread listening to stdout + t = threading.Thread(target=listenIPy) + t.start() + return True + except: + disconnected() + return None + def killIPy(): - global ipy - try: - send('exit') - os.kill(ipy.pid, signal.SIGTERM) - ipy.terminate() - ipy.returncode = True - except: - pass + global ipy + try: + send('exit') + os.kill(ipy.pid, signal.SIGTERM) + ipy.terminate() + ipy.returncode = True + except: + pass + def request(cur): - id = send(cur["code"]) - requests[id] = cur + id = send(cur["code"]) + requests[id] = cur diff --git a/py-src/ltmain.py b/py-src/ltmain.py index e07f173..47ab7bf 100644 --- a/py-src/ltmain.py +++ b/py-src/ltmain.py @@ -22,84 +22,93 @@ threads = [] currentClient = 0 + class Printer(): - cur = "" + cur = "" - def write(self, text): - self.cur += text - if text == "\n": - self.flush() + def write(self, text): + self.cur += text + if text == "\n": + self.flush() - def flush(self): - send(currentClient, "editor.eval.python.print", {"msg": self.cur, "file": name}) - self.cur = "" + def flush(self): + send(currentClient, "editor.eval.python.print", + {"msg": self.cur, "file": name}) + self.cur = "" - def readlines(self): - return None + def readlines(self): + return None + + def read(self): + return None - def read(self): - return None def asUnicode(s): - try: - return unicode(s) - except: - return str(s) + try: + return unicode(s) + except: + return str(s) + def ensureUtf(s): - if type(s) == unicode: - return s.encode('utf8', 'ignore') - else: - return str(s) + if type(s) == unicode: + return s.encode('utf8', 'ignore') + else: + return str(s) + def findLoc(body, line, total): - for i in range(len(body)): - if body[i].lineno == line: - if i + 1 >= len(body): - return {"start": body[i].lineno, "end":total} - else: - return {"start": body[i].lineno, "end":body[i+1].lineno - 1} - elif body[i].lineno > line and line != 0: - return {"start": body[i-1].lineno, "end":body[i].lineno - 1} - elif body[i].lineno < line and i + 1 == len(body) and line <= total: - return {"start": body[i].lineno, "end":total} - return None + for i in range(len(body)): + if body[i].lineno == line: + if i + 1 >= len(body): + return {"start": body[i].lineno, "end": total} + else: + return {"start": body[i].lineno, "end": body[i + 1].lineno - 1} + elif body[i].lineno > line and line != 0: + return {"start": body[i - 1].lineno, "end": body[i].lineno - 1} + elif body[i].lineno < line and i + 1 == len(body) and line <= total: + return {"start": body[i].lineno, "end": total} + return None + def toForm(lines, loc): - if loc: - end = loc["end"] - 1 - start = loc["start"] - 1 - if start == end: - return [{"start":start, "end":end}, "\n"*start + lines[start]] - else: - while (not re.search("\S", lines[end]) or re.search("^\s*#.*$", lines[end])) and end > start: - end -= 1 - if start == end: - return [{"start":start, "end":end}, "\n"*(start) + lines[start]] - else: - return [{"start":start, "end":end}, "\n"*(start) + "\n".join(lines[start:end + 1])] - return [] + if loc: + end = loc["end"] - 1 + start = loc["start"] - 1 + if start == end: + return [{"start": start, "end": end}, "\n" * start + lines[start]] + else: + while (not re.search("\S", lines[end]) or re.search("^\s*#.*$", lines[end])) and end > start: + end -= 1 + if start == end: + return [{"start": start, "end": end}, "\n" * (start) + lines[start]] + else: + return [{"start": start, "end": end}, "\n" * (start) + "\n".join(lines[start:end + 1])] + return [] + def toModuleNameByPath(path): - cur = [os.path.splitext(os.path.basename(path))[0]] - p = os.path.dirname(path); - while os.path.exists(os.path.join(p, "__init__.py")): - cur.insert(0, os.path.basename(p)) - p = os.path.dirname(p) - return ".".join(cur) + cur = [os.path.splitext(os.path.basename(path))[0]] + p = os.path.dirname(path) + while os.path.exists(os.path.join(p, "__init__.py")): + cur.insert(0, os.path.basename(p)) + p = os.path.dirname(p) + return ".".join(cur) + def toModule(path): - name = toModuleNameByPath(path) - if name in sys.modules: - exec("import sys", sys.modules[name].__dict__) - return sys.modules[name] - else: - parts = name.split(".") - for idx in range(len(parts)): - mname = ".".join(parts[:idx+1]) - __import__(mname) - exec("import sys", sys.modules[name].__dict__) - return sys.modules[name] + name = toModuleNameByPath(path) + if name in sys.modules: + exec("import sys", sys.modules[name].__dict__) + return sys.modules[name] + else: + parts = name.split(".") + for idx in range(len(parts)): + mname = ".".join(parts[:idx + 1]) + __import__(mname) + exec("import sys", sys.modules[name].__dict__) + return sys.modules[name] + def explodeCode(string): lines = string.splitlines() @@ -114,211 +123,230 @@ def explodeCode(string): if i >= totalForms - 1: end = total else: - end = a.body[i+1].lineno - 1 + end = a.body[i + 1].lineno - 1 forms.append(toForm(lines, {"start": start, "end": end})) return forms + def handlePos(string, pos): - lines = string.splitlines() - if len(lines) == 0: + lines = string.splitlines() + if len(lines) == 0: + return [None, None] + a = ast.parse(string) + loc = findLoc(a.body, pos["line"] + 1, len(lines)) + if loc: + return toForm(lines, loc) return [None, None] - a = ast.parse(string) - loc = findLoc(a.body, pos["line"] + 1, len(lines)) - if loc: - return toForm(lines, loc) - return [None, None] + def cleanCode(c): - return re.sub(r'(#.*coding.*)\n?', '\n', c) + return re.sub(r'(#.*coding.*)\n?', '\n', c) + def cleanTrace(t): - return t + return t + def chunks(lst, n): - for i in range(0, len(lst), n): - yield lst[i:i+n] + for i in range(0, len(lst), n): + yield lst[i:i + n] + def send(client, command, info): - tosend = (json.dumps([client, command, info]) + "\n").encode('utf-8') - for chunk in chunks(tosend, 1024): - s.send(chunk); + tosend = (json.dumps([client, command, info]) + "\n").encode('utf-8') + for chunk in chunks(tosend, 1024): + s.send(chunk) + def stopped(): - global stop - return stop + global stop + return stop + def handleEval(data): - result = None - code = cleanCode(data[2]["code"]) - if "meta" in data[2]: - loc = data[2]["meta"] - else: - loc = {"start":1, "end":1} - - toExec = [] - - if "pos" in data[2] and data[2]["pos"]: - try: - toExec.append(handlePos(code, data[2]["pos"])) - except: - e = traceback.format_exc() - return send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta": {"start": data[2]["pos"]["line"], "end": data[2]["pos"]["line"]}}) - else: - try: - exp = code - if "meta" in data[2]: - exp = "\n" * data[2]["meta"]["start"] + code - toExec = explodeCode(exp) - except: - e = traceback.format_exc() - return send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta": data[2]["meta"]}) - - if not code or len(toExec) == 0: - return send(data[0], "editor.eval.python.result", None) - - try: - if not "path" in data[2]: - module = sys.modules["__main__"] + result = None + code = cleanCode(data[2]["code"]) + if "meta" in data[2]: + loc = data[2]["meta"] + else: + loc = {"start": 1, "end": 1} + + toExec = [] + + if "pos" in data[2] and data[2]["pos"]: + try: + toExec.append(handlePos(code, data[2]["pos"])) + except: + e = traceback.format_exc() + return send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": {"start": data[2]["pos"]["line"], "end": data[2]["pos"]["line"]}}) else: - module = toModule(data[2]["path"]) - except: - e = traceback.format_exc() - return send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta":loc}) - - for form in toExec: - code = form[1] - loc = form[0] - isEval = False - try: - code= compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'eval') - isEval = True - except: try: - code= compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'exec') + exp = code + if "meta" in data[2]: + exp = "\n" * data[2]["meta"]["start"] + code + toExec = explodeCode(exp) except: - e = traceback.format_exc() - send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": loc}) - continue - - try: - if isEval: - result = eval(code, module.__dict__) - send(data[0], "editor.eval.python.result", {"meta": loc, "result": asUnicode(result)}) + e = traceback.format_exc() + return send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": data[2]["meta"]}) + + if not code or len(toExec) == 0: + return send(data[0], "editor.eval.python.result", None) + + try: + if not "path" in data[2]: + module = sys.modules["__main__"] else: - exec(code, module.__dict__) - send(data[0], "editor.eval.python.success", {"meta": loc}) - except Exception as exc: + module = toModule(data[2]["path"]) + except: e = traceback.format_exc() + return send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": loc}) + + for form in toExec: + code = form[1] + loc = form[0] + isEval = False try: - send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta":loc}) - continue + code = compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'eval') + isEval = True except: - pass + try: + code = compile( + ensureUtf(code), ensureUtf(data[2]["name"]), 'exec') + except: + e = traceback.format_exc() + send(data[0], "editor.eval.python.exception", + {"ex": cleanTrace(e), "meta": loc}) + continue + + try: + if isEval: + result = eval(code, module.__dict__) + send(data[0], "editor.eval.python.result", + {"meta": loc, "result": asUnicode(result)}) + else: + exec(code, module.__dict__) + send(data[0], "editor.eval.python.success", {"meta": loc}) + except Exception as exc: + e = traceback.format_exc() + try: + send(data[0], "editor.eval.python.exception", + {"ex": cleanTrace(e), "meta": loc}) + continue + except: + pass + def ipyEval(data): - result = None - code = cleanCode(data[2]["code"]) - if "meta" in data[2]: - loc = data[2]["meta"] - else: - loc = {"start":1, "end":1} - - toExec = [] - - if "pos" in data[2] and data[2]["pos"]: - try: - toExec.append(handlePos(code, data[2]["pos"])) - except: - e = traceback.format_exc() - return send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta": {"start": data[2]["pos"]["line"], "end": data[2]["pos"]["line"]}}) - else: - try: - exp = code - if "meta" in data[2]: - exp = "\n" * data[2]["meta"]["start"] + code - toExec = explodeCode(exp) - except: - e = traceback.format_exc() - return send(data[0], "editor.eval.python.exception", {"ex":cleanTrace(e), "meta": data[2]["meta"]}) - - - if not code: - return send(data[0], "editor.eval.python.result", None) - - try: - ltipy.setNs(data[2]['path']) - except: - pass - - if "path" in data[2]: - path = data[2]["path"] - else: - path = "untitled" - - for form in toExec: - code = form[1] - loc = form[0] - isEval = False - try: - compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'eval') - isEval = True - except: + result = None + code = cleanCode(data[2]["code"]) + if "meta" in data[2]: + loc = data[2]["meta"] + else: + loc = {"start": 1, "end": 1} + + toExec = [] + + if "pos" in data[2] and data[2]["pos"]: + try: + toExec.append(handlePos(code, data[2]["pos"])) + except: + e = traceback.format_exc() + return send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": {"start": data[2]["pos"]["line"], "end": data[2]["pos"]["line"]}}) + else: + try: + exp = code + if "meta" in data[2]: + exp = "\n" * data[2]["meta"]["start"] + code + toExec = explodeCode(exp) + except: + e = traceback.format_exc() + return send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": data[2]["meta"]}) + + if not code: + return send(data[0], "editor.eval.python.result", None) + + try: + ltipy.setNs(data[2]['path']) + except: + pass + + if "path" in data[2]: + path = data[2]["path"] + else: + path = "untitled" + + for form in toExec: + code = form[1] + loc = form[0] + isEval = False try: - compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'exec') + compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'eval') + isEval = True except: - e = traceback.format_exc() - send(data[0], "editor.eval.python.exception", {"ex": cleanTrace(e), "meta": loc}) - continue + try: + compile(ensureUtf(code), ensureUtf(data[2]["name"]), 'exec') + except: + e = traceback.format_exc() + send(data[0], "editor.eval.python.exception", + {"ex": cleanTrace(e), "meta": loc}) + continue + ltipy.request({"meta": loc, "name": data[2]["name"], "path": path, "code": code, "client": data[ + 0], "evaltype": "expression" if isEval else "statement"}) - ltipy.request({"meta": loc, "name": data[2]["name"], "path": path, "code": code, "client": data[0], "evaltype": "expression" if isEval else "statement"}) def shutdown(): - global threads, oldout, s, stop - stop = True - killThreads(threads) - s.close() - sys.stdout = oldout - ltipy.killIPy() - safePrint("Disconnected") - sys.exit() + global threads, oldout, s, stop + stop = True + killThreads(threads) + s.close() + sys.stdout = oldout + ltipy.killIPy() + safePrint("Disconnected") + sys.exit() + def signal_handler(signal, frame): - shutdown() + shutdown() signal.signal(signal.SIGINT, signal_handler) + def handle(data, threads): - global currentClient - currentClient = data[0] - if data[1] == 'client.close': - shutdown() - elif data[1] == 'client.cancel-all': - killThreads(threads) - elif data[1] == 'editor.eval.python': - if local: - t = ThreadWithExc(target=handleEval, args=(data,)) - t.start() - return t - else: - ipyEval(data) + global currentClient + currentClient = data[0] + if data[1] == 'client.close': + shutdown() + elif data[1] == 'client.cancel-all': + killThreads(threads) + elif data[1] == 'editor.eval.python': + if local: + t = ThreadWithExc(target=handleEval, args=(data,)) + t.start() + return t + else: + ipyEval(data) + def _async_raise(tid, exctype): '''Raises an exception in the threads with id tid''' if not inspect.isclass(exctype): raise TypeError("Only types can be raised (not instances)") res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), - ctypes.py_object(exctype)) + ctypes.py_object(exctype)) if res == 0: raise ValueError("invalid thread id") elif res != 1: ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None) raise SystemError("PyThreadState_SetAsyncExc failed") + class ThreadWithExc(threading.Thread): + '''A thread class that supports raising exception in the thread from another thread. ''' + def _get_my_tid(self): if not self.isAlive(): raise threading.ThreadError("the thread is not active") @@ -334,94 +362,102 @@ def _get_my_tid(self): raise AssertionError("could not determine the thread's id") def raiseExc(self, exctype): - _async_raise( self._get_my_tid(), exctype ) + _async_raise(self._get_my_tid(), exctype) + def killThreads(threads): - for t in threads: - if t.isAlive(): - t.raiseExc(Exception) + for t in threads: + if t.isAlive(): + t.raiseExc(Exception) + def removeFinished(threads): - return [t for t in threads if t.isAlive()] + return [t for t in threads if t.isAlive()] + def safePrint(s): - sys.stdout.write(s) - sys.stdout.flush() + sys.stdout.write(s) + sys.stdout.flush() + def start(type): - sys.stdout.flush() - info["type"] = type - s.send((json.dumps(info)+ "\n").encode('utf-8')); + sys.stdout.flush() + info["type"] = type + s.send((json.dumps(info) + "\n").encode('utf-8')) + + sys.stdout = Printer() + sys.stderr = Printer() - sys.stdout = Printer() - sys.stderr = Printer() + asyncore.loop() - asyncore.loop() def connected(): - global local - local = False - t = threading.Thread(target=start, args=("ipython",)) - t.start() + global local + local = False + t = threading.Thread(target=start, args=("ipython",)) + t.start() + def disconnected(): - global local - if not local: - return - local = True - start("python") + global local + if not local: + return + local = True + start("python") + class Client(asyncore.dispatcher): - def __init__(self, host, port): - asyncore.dispatcher.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.connect( (host, port) ) - self.buffer = "" - self.cur = "" + def __init__(self, host, port): + asyncore.dispatcher.__init__(self) + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.connect((host, port)) + self.buffer = "" + self.cur = "" - def handle_connect(self): - pass + def handle_connect(self): + pass - def handle_close(self): - shutdown() + def handle_close(self): + shutdown() - def handle_read(self): - self.cur += self.recv(1024).decode('utf-8') - if self.cur[-1] == '\n': - global threads - t = handle(json.loads(self.cur[:-1]), threads) - if t: - threads.append(t) - self.cur = "" + def handle_read(self): + self.cur += self.recv(1024).decode('utf-8') + if self.cur[-1] == '\n': + global threads + t = handle(json.loads(self.cur[:-1]), threads) + if t: + threads.append(t) + self.cur = "" - def writable(self): - return (len(self.buffer) > 0) + def writable(self): + return (len(self.buffer) > 0) - def handle_write(self): - sent = self.send(self.buffer.encode('utf-8')) - self.buffer = self.buffer[sent:] + def handle_write(self): + sent = self.send(self.buffer.encode('utf-8')) + self.buffer = self.buffer[sent:] - def sendoff(self, msg): - self.buffer += msg + def sendoff(self, msg): + self.buffer += msg if __name__ == "__main__": - curDir = os.getcwd() - sys.path.append(curDir) - name = os.path.basename(curDir) - - try: - cid = int(sys.argv[2]) - except: - cid = None - - info = {'name':name, 'client-id':cid, 'dir':curDir, 'commands': ['editor.eval.python']} - - s = Client('127.0.0.1', int(sys.argv[1])) - lttools.setRespond(send); - safePrint("Connected") - - ltipy.startIPy({"respond": send, - "connected": connected, - "disconnected": disconnected}) - #disconnected() + curDir = os.getcwd() + sys.path.append(curDir) + name = os.path.basename(curDir) + + try: + cid = int(sys.argv[2]) + except: + cid = None + + info = {'name': name, 'client-id': cid, + 'dir': curDir, 'commands': ['editor.eval.python']} + + s = Client('127.0.0.1', int(sys.argv[1])) + lttools.setRespond(send) + safePrint("Connected") + + ltipy.startIPy({"respond": send, + "connected": connected, + "disconnected": disconnected}) + # disconnected() diff --git a/py-src/lttools.py b/py-src/lttools.py index 392fc1c..a0b0560 100644 --- a/py-src/lttools.py +++ b/py-src/lttools.py @@ -13,45 +13,52 @@ pp = pprint.PrettyPrinter() try: - ipy = sys.modules['__main__'].__dict__['get_ipython']() + ipy = sys.modules['__main__'].__dict__['get_ipython']() except: - ipy = None + ipy = None + def toModuleNameByPath(path): - cur = [os.path.splitext(os.path.basename(path))[0]] - p = os.path.dirname(path); - while os.path.exists(os.path.join(p, "__init__.py")): - cur.insert(0, os.path.basename(p)) - p = os.path.dirname(p) - return ".".join(cur) + cur = [os.path.splitext(os.path.basename(path))[0]] + p = os.path.dirname(path) + while os.path.exists(os.path.join(p, "__init__.py")): + cur.insert(0, os.path.basename(p)) + p = os.path.dirname(p) + return ".".join(cur) + def setRespond(s): - global respond - respond = s + global respond + respond = s + def watch(exp, meta): - if not ipy and respond: - respond(None, "clients.raise-on-object", [meta["obj"], "editor.eval.python.watch", {"meta": meta, "result": pp.pformat(exp)}]); - else: - sys.stdout.write("__WATCH " + pickle.dumps({"meta": meta, "result": pp.pformat(exp)})) - return exp + if not ipy and respond: + respond(None, "clients.raise-on-object", + [meta["obj"], "editor.eval.python.watch", {"meta": meta, "result": pp.pformat(exp)}]) + else: + sys.stdout.write( + "__WATCH " + pickle.dumps({"meta": meta, "result": pp.pformat(exp)})) + return exp + def toModule(path): - name = toModuleNameByPath(path) - if name in sys.modules: - return sys.modules[name] - else: - parts = name.split(".") - for idx in range(len(parts)): - mname = ".".join(parts[:idx+1]) - __import__(mname) - exec("import sys", sys.modules[name].__dict__) - return sys.modules[name] + name = toModuleNameByPath(path) + if name in sys.modules: + return sys.modules[name] + else: + parts = name.split(".") + for idx in range(len(parts)): + mname = ".".join(parts[:idx + 1]) + __import__(mname) + exec("import sys", sys.modules[name].__dict__) + return sys.modules[name] + def switch_ns(path): - module = toModule(path) - ipy.init_create_namespaces(module) - ipy.init_user_ns() + module = toModule(path) + ipy.init_create_namespaces(module) + ipy.init_user_ns() #---------------------------------------------------------- # VirtualEnv magic From 4bbc41cad9c0fe2380bba78fada70adb04950fc2 Mon Sep 17 00:00:00 2001 From: Andy Hayden Date: Sat, 27 Jun 2015 23:16:54 -0700 Subject: [PATCH 2/2] Python 3 compat. Also, use enumerate rather than range(len(..)). --- py-src/ltmain.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/py-src/ltmain.py b/py-src/ltmain.py index 47ab7bf..13e2aae 100644 --- a/py-src/ltmain.py +++ b/py-src/ltmain.py @@ -23,7 +23,7 @@ currentClient = 0 -class Printer(): +class Printer(object): cur = "" def write(self, text): @@ -46,28 +46,28 @@ def read(self): def asUnicode(s): try: return unicode(s) - except: + except NameError: # python 3 return str(s) def ensureUtf(s): - if type(s) == unicode: - return s.encode('utf8', 'ignore') - else: + try: + return s.decode('utf8', 'ignore') + except AttributeError: return str(s) def findLoc(body, line, total): - for i in range(len(body)): - if body[i].lineno == line: + for i, bi in enumerate(body): + if bi.lineno == line: if i + 1 >= len(body): - return {"start": body[i].lineno, "end": total} + return {"start": bi.lineno, "end": total} else: - return {"start": body[i].lineno, "end": body[i + 1].lineno - 1} - elif body[i].lineno > line and line != 0: - return {"start": body[i - 1].lineno, "end": body[i].lineno - 1} - elif body[i].lineno < line and i + 1 == len(body) and line <= total: - return {"start": body[i].lineno, "end": total} + return {"start": bi.lineno, "end": body[i + 1].lineno - 1} + elif bi.lineno > line and line != 0: + return {"start": body[i - 1].lineno, "end": bi.lineno - 1} + elif bi.lineno < line and i + 1 == len(body) and line <= total: + return {"start": bi.lineno, "end": total} return None @@ -103,7 +103,7 @@ def toModule(path): return sys.modules[name] else: parts = name.split(".") - for idx in range(len(parts)): + for idx, _ in enumerate(parts): mname = ".".join(parts[:idx + 1]) __import__(mname) exec("import sys", sys.modules[name].__dict__) @@ -118,8 +118,8 @@ def explodeCode(string): a = ast.parse(string) forms = [] totalForms = len(a.body) - for i in range(totalForms): - start = a.body[i].lineno + for i, bi in enumerate(a.body): + start = bi.lineno if i >= totalForms - 1: end = total else: