mirror of
https://github.com/python/cpython.git
synced 2026-02-22 15:10:47 +00:00
Run a long living subprocess which handles multiple requests instead of running a new subprocess for each request.
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
# This script is called by test_xpickle as a subprocess to load and dump
|
|
# pickles in a different Python version.
|
|
import os
|
|
import pickle
|
|
import struct
|
|
import sys
|
|
|
|
|
|
# This allows the xpickle worker to import picklecommon.py, which it needs
|
|
# since some of the pickle objects hold references to picklecommon.py.
|
|
test_mod_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
|
'picklecommon.py'))
|
|
if sys.version_info >= (3, 5):
|
|
import importlib.util
|
|
spec = importlib.util.spec_from_file_location('test.picklecommon', test_mod_path)
|
|
sys.modules['test'] = type(sys)('test')
|
|
test_module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(test_module)
|
|
sys.modules['test.picklecommon'] = test_module
|
|
else:
|
|
test_module = type(sys)('test.picklecommon')
|
|
sys.modules['test.picklecommon'] = test_module
|
|
sys.modules['test'] = type(sys)('test')
|
|
with open(test_mod_path, 'rb') as f:
|
|
sources = f.read()
|
|
exec(sources, vars(test_module))
|
|
|
|
def read_exact(f, n):
|
|
buf = b''
|
|
while len(buf) < n:
|
|
chunk = f.read(n - len(buf))
|
|
if not chunk:
|
|
raise EOFError
|
|
buf += chunk
|
|
return buf
|
|
|
|
in_stream = getattr(sys.stdin, 'buffer', sys.stdin)
|
|
out_stream = getattr(sys.stdout, 'buffer', sys.stdout)
|
|
|
|
try:
|
|
while True:
|
|
size, = struct.unpack('!i', read_exact(in_stream, 4))
|
|
if not size:
|
|
break
|
|
data = read_exact(in_stream, size)
|
|
protocol, = struct.unpack('!i', data[:4])
|
|
obj = pickle.loads(data[4:])
|
|
data = pickle.dumps(obj, protocol)
|
|
out_stream.write(struct.pack('!i', len(data)) + data)
|
|
out_stream.flush()
|
|
except Exception as exc:
|
|
# dump the exception to stdout and write to stderr, then exit
|
|
try:
|
|
data = pickle.dumps(exc)
|
|
out_stream.write(struct.pack('!i', -len(data)) + data)
|
|
out_stream.flush()
|
|
except Exception:
|
|
out_stream.write(struct.pack('!i', 0))
|
|
out_stream.flush()
|
|
sys.stderr.write(repr(exc))
|
|
sys.stderr.flush()
|
|
sys.exit(1)
|