from __future__ import unicode_literals from codeop import Compile import os import sys import json import traceback import platform import struct import math NODE_CHANNEL_FD = int(os.environ['NODE_CHANNEL_FD']) UNICODE_TYPE = unicode if sys.version_info[0] == 2 else str if sys.version_info[0] <= 2: # print('PY2') def _exec(_code_, _globs_): exec('exec _code_ in _globs_') else: _exec = getattr(__builtins__, 'exec') _locals = {'__name__': '__console__', '__doc__': None} _compile = Compile() if platform.system() == 'Windows': # hacky reimplementation of https://github.com/nodejs/node/blob/master/deps/uv/src/win/pipe.c def read_data(f): header = f.read(16) if not header: return header try: msg_length, = struct.unpack(' 0 else '-Infinity' return o.__dict__ if __name__ == '__main__': writer = os.fdopen(NODE_CHANNEL_FD, 'wb') reader = os.fdopen(NODE_CHANNEL_FD, 'rb') while True: try: # Read new command line = read_data(reader) if not line: break try: data = json.loads(line.decode('utf-8')) except ValueError: raise ValueError('Could not decode IPC data:\n{}'.format(repr(line))) # Assert data saneness if data['type'] not in ['execute', 'evaluate']: raise Exception('Python bridge call `type` must be `execute` or `evaluate`') if not isinstance(data['code'], UNICODE_TYPE): raise Exception('Python bridge call `code` must be a string.') # Run Python code if data['type'] == 'execute': _exec(_compile(data['code'], '', 'exec'), _locals) response = dict(type='success') else: value = eval(_compile(data['code'], '', 'eval'), _locals) response = dict(type='success', value=json.dumps(value, separators=(',', ':'), cls=JavaScriptEncoder)) except: t, e, tb = sys.exc_info() response = dict(type='exception', value=format_exception(t, e, tb)) data = json.dumps(response, separators=(',', ':')).encode('utf-8') + b'\n' write_data(writer, data) # Closing is messy try: reader.close() except IOError: pass try: writer.close() except IOError: pass