通常の (サンドボックス化されていない) cPython または PyPy スクリプト内から、サンドボックス化された PyPy インタープリターと対話する方法を作成しようとしています。
これらの指示に従って、サンドボックス化された PyPy インタープリターをコンパイルすることができましたhttp://doc.pypy.org/en/latest/sandbox.htmlと、pypy_interact.py と連携して作成する pypy-c-sandbox ファイルがありますインタラクティブなサンドボックス インタープリター。
今、私は非常に似たようなことをしたいのですが、stdin/stdout を io として使用するのではなく、python スクリプトを使用して pypy-sandbox プロセスとやり取りしたいと考えています。私はこれで大部分が機能するようになりました。cStringIO オブジェクトを入力、出力、エラーとして .communicate() 関数を使用して、通常の Python からこのデータにアクセスできます。
ただし、これは私の問題です。同じインスタンス化された PyPy サンドボックス オブジェクトで .communicate() をもう一度呼び出すと、何も返されません。最初の .communicate だけが機能します。なぜこれが当てはまるのか、どうすれば回避できるのか、私はかなり混乱しています。
私の問題を示すために、醜いハックをまとめました:
import sys, os
import autopath
from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc
from pypy.translator.sandbox.sandlib import VirtualizedSandboxedProc
from pypy.translator.sandbox.vfs import Dir, RealDir, RealFile
import pypy
LIB_ROOT = os.path.dirname(os.path.dirname(pypy.__file__))
class PyPySandboxedProc(VirtualizedSandboxedProc, SimpleIOSandboxedProc):
argv0 = '/bin/pypy-c'
virtual_cwd = '/tmp'
virtual_env = {}
virtual_console_isatty = True
arguments = ['../goal/pypy-c', '-u']
def __init__(self, executable, arguments, tmpdir=None, debug=True):
self.executable = executable = os.path.abspath(executable)
self.tmpdir = tmpdir
self.debug = debug
super(PyPySandboxedProc, self).__init__([self.argv0] + arguments,
executable=executable)
def build_virtual_root(self):
# build a virtual file system:
# * can access its own executable
# * can access the pure Python libraries
# * can access the temporary usession directory as /tmp
exclude = ['.pyc', '.pyo']
if self.tmpdir is None:
tmpdirnode = Dir({})
else:
tmpdirnode = RealDir(self.tmpdir, exclude=exclude)
libroot = str(LIB_ROOT)
return Dir({
'bin': Dir({
'pypy-c': RealFile(self.executable),
'lib-python': RealDir(os.path.join(libroot, 'lib-python'),
exclude=exclude),
'lib_pypy': RealDir(os.path.join(libroot, 'lib_pypy'),
exclude=exclude),
}),
'tmp': tmpdirnode,
})
# run test
arguments = ['../goal/pypy-c', '-u']
sandproc = PyPySandboxedProc(arguments[0], arguments[1:],
tmpdir=None, debug=True)
#start the proc
code1 = "print 'started'\na = 5\nprint a"
code2 = "b = a\nprint b\nprint 'code 2 was run'"
output, error = sandproc.communicate(code1)
print "output: %s\n error: %s\n" % (output, error)
output, error = sandproc.communicate(code2)
print "output: %s\n error: %s\n" % (output, error)
code2
同じ Sandproc インスタンスで実行できるが、その入力/出力が別々に返されるようにする方法が本当に欲しいです。すべてのコードを連結して一度に実行すると機能しますが、特定の入力の出力を解析するのは少し面倒です。