Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonใ‚นใ‚ฏใƒชใƒ—ใƒˆใ‚’่ปฝ้‡ใ‚ตใƒณใƒ‰ใƒœใƒƒใ‚ฏใ‚นใงๅ‰ฒใจๅฎ‰ๅ…จใซๅฎŸ่กŒใ™ใ‚‹

Last updated at Posted at 2025-02-26

LLMใฎPythonใ‚นใ‚ฏใƒชใƒ—ใƒˆๅ‡บๅŠ›ใ‚’ๆฏ”่ผƒ็š„ๅฎ‰ๅ…จใซๅฎŸ่กŒใ—ใŸใ„ใ€ใใ†ใ„ใ†ๆ™‚ใฃใฆๅ‰ฒใจใ‚ใ‚Šใพใ™ใ‚ˆใญใ€‚ไฝฟใ†ใฎใฏ่‡ชๅˆ†ใ ใ‘ใชใฎใงๆ€–ใ„ใฎใฏๅถ็„ถๅฑ้™บใชใ‚ณใƒผใƒ‰ใŒๅ‡บใฆใใŸๆ™‚ใ ใ‘ใ€ใฟใŸใ„ใชใ‚ฑใƒผใ‚นใงใ™ใ€‚

ใงใ‚‚ไธ–้–“ใซๅ‡บๅ›žใฃใฆใ‚‹ๆƒ…ๅ ฑใฏDockerใ‚’ไฝฟใฃใŸใ‚‚ใฎ (llm-sandbox) ใจใ‹ใ€WebAssemblyใ‚’ไฝฟใฃใŸใ‚‚ใฎ (Pyodide) ใจใ‹ใ€CPythonไปฅๅค–ใฎๅฎŸ่ฃ…ใ‚’ไฝฟใฃใŸใ‚‚ใฎ (PyPyใฎใ‚ตใƒณใƒ‰ใƒœใƒƒใ‚ฏใ‚นๆฉŸ่ƒฝ) ใจใ‹ใ€Webใ‚ตใƒผใƒ“ใ‚นๅ‘ใ‘ใฎ้‡้‡็ดšใฎใ‚‚ใฎใฐใ‹ใ‚Šใ€‚่ปฝใ‹ใฃใŸใงใ‚ใ‚ใ† pysandbox ใฏใƒ‡ใ‚ถใ‚คใƒณใซๆฌ ้™ฅใŒใ‚ใ‚Šใ€ๅˆถ้™ใ‚‚ๅคšใ้–‹็™บไธญๆญขใจใชใฃใฆใ„ใพใ—ใŸใ€‚

ใใ‚“ใชไธญใงใ•ใฆใฉใ†ใ—ใ‚ˆใ†ใ€ใ‚ตใƒณใƒ‰ใƒœใƒƒใ‚ฏใ‚นใฎPython็’ฐๅขƒใงใ‚‚ใƒ›ใ‚นใƒˆใฎPython็’ฐๅขƒใจๅŒใ˜ใ‚‚ใฎใŒไฝฟใˆใ‚Œใฐ็ฎก็†ใŒๆฅฝใชใฎใซใ€ใจๆ€ใ„ใชใŒใ‚‰่ชฟในใฆใ„ใพใ—ใŸใ€‚

ใใฎ็ตๆžœใ€Pythonใƒฉใ‚คใƒ–ใƒฉใƒชใฎไธญใงใฏๆฑบๅฎšๆ‰“ใŒ่ฆ‹ใคใ‹ใ‚‰ใชใ‹ใฃใŸใ‚‚ใฎใฎใ€Linux็’ฐๅขƒใฎไธญใงใฏ systemd-nspawn ใ‚’่ชญใฟ่พผใฟๅฐ‚็”จใƒžใ‚ฆใƒณใƒˆใงไฝฟใ†ๆ–นๆณ•ใ‚’ๆ€ใ„ใคใ๏ผˆไฝ†ใ—ใƒซใƒผใƒˆๆจฉ้™ใŒๅฟ…่ฆ๏ผ‰ใ€ใใฎ systemd-nspawn ใซไผผใชใŒใ‚‰ใ‚‚ใƒซใƒผใƒˆๆจฉ้™ใŒไธ่ฆใชbubblewrap (bwrap) ใ‚’่ฆ‹ใคใ‘ใ€ใใฎ bwrap ใ‚’ไฝฟใฃใฆใ‚ตใƒณใƒ‰ใƒœใƒƒใ‚ฏใ‚นใง Python ใ‚นใ‚ฏใƒชใƒ—ใƒˆใ‚’ๅฎŸ่กŒใ™ใ‚‹ใ‚ณใƒผใƒ‰ใ‚’ๆ›ธใ„ใฆใฟใพใ—ใŸใ€‚

# License: Public Domain
import os
import subprocess

home_dir = os.path.expanduser("~")

try:
    os.makedirs("/tmp/mysandbox_root")
except FileExistsError:
    pass

def sandbox_pyexec(code):
    proc = subprocess.Popen(
        ["bwrap", "--bind", "/tmp/mysandbox_root", "/", "--ro-bind", "/bin", "/bin", # ใ‚ทใ‚นใƒ†ใƒ ใƒ•ใ‚กใ‚คใƒซใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
         "--ro-bind", "/lib", "/lib", "--ro-bind", "/lib64", "/lib64", 
         "--ro-bind", "/usr", "/usr", "--ro-bind", "/etc", "/etc", # ใ‚ใ‚“ใพใ‚Š่‰ฏใใชใ„
         "--ro-bind", home_dir + "/.local/lib", home_dir + "/.local/lib", # pip ใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
         "--ro-bind", home_dir + "/.local/bin", home_dir + "/.local/bin",
         "--ro-bind", home_dir + "/.local/share", home_dir + "/.local/share",
         "--bind", "/proc", "/proc", "--unshare-all", "--", # ใชใ‚‹ในใใƒ›ใ‚นใƒˆใจ้žๅ…ฑๆœ‰๏ผˆsystemd-nspawnใจ้•ใฃใฆใƒ—ใƒญใ‚ปใ‚นใƒชใ‚นใƒˆใฏๅ…ฑๆœ‰ใ—ใฆใ‚‹ใ‘ใฉ๏ผ‰
         "bash", "-c", "python -"],  # Pythonใงๆจ™ๆบ–ๅ…ฅๅŠ›ใฎใ‚ณใƒผใƒ‰ใ‚’ๅฎŸ่กŒ
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True  # stdin / stdout ใ‚’ๆ–‡ๅญ—ๅˆ—ใจใ—ใฆๆ‰ฑใ†
    )
    result, err = proc.communicate(code)
    return (result.strip(), err.strip())
    

r, err = sandbox_pyexec( """print("ใ“ใ‚Œใฏใƒ†ใ‚นใƒˆใงใ™")""")

print("stdout:", r)
print("stderr:", err)
# stdout: ใ“ใ‚Œใฏใƒ†ใ‚นใƒˆใงใ™
# stderr: 

r, err = sandbox_pyexec( """import os
os.system("ls /")""")

print("stdout:", r)
print("stderr:", err)
# stdout: bin
# etc
# home
# lib
# lib64
# proc
# usr
# stderr: 

r, err = sandbox_pyexec( """wrong python syntax here""")

print("stdout:", r)
print("stderr:", err)
# stdout: 
# stderr: File "<stdin>", line 1
#     wrong python syntax here
#           ^^^^^^
# SyntaxError: invalid syntax

Jupyterไบ’ๆ›็‰ˆ

Jupyterไบ’ๆ›็‰ˆใ‚‚ไฝœใ‚Šใพใ—ใŸ๏ผˆ2026ๅนด1ๆœˆ11ๆ—ฅ่ฟฝ่จ˜๏ผ‰ใ€‚

ใ“ใฃใกใฎๆ–นใŒLLMใจใฎ็›ธๆ€งใฏ่‰ฏใ„ใฏใšใงใ™๏ผˆๅฐ‘ใชใใจใ‚‚gpt-oss-120bใฏใ“ใฃใกใฎๆ–นใŒ่‰ฏใ„ใงใ™๏ผ‰ใ€‚

# License: Public Domain
import os
import pty
import termios
import select
import sys
import signal
import psutil

home_dir = os.path.expanduser("~")
try:
    os.makedirs("/tmp/mysandbox_root")
except FileExistsError:
    pass

def disable_echo(fd):
    attrs = termios.tcgetattr(fd)
    attrs[3] = attrs[3] & ~termios.ECHO  # lflags ใ‹ใ‚‰ ECHO ใ‚’่ฝใจใ™
    termios.tcsetattr(fd, termios.TCSANOW, attrs)

# IPythonใฎๅ‹•ไฝœใ‚’ใ‚ทใƒŸใƒฅใƒฌใƒผใƒˆ
# python -m pip install ipython --break-system-packages
helper_code = """from IPython.core.ultratb import VerboseTB
import sys
sys.excepthook = VerboseTB(theme_name="Linux", tb_offset=2)
import linecache

file_count = 1

import ast
def _exec_with_expr(code, globals=None, locals=None):
    global file_count
    tree = ast.parse(code, mode="exec")
    if len(tree.body) == 0:
        print("")
        return None
    filename = "/tmp/test-%s.py"%file_count
    file_count += 1
    linecache.cache[filename] = (
        len(code),
        None,
        code.splitlines(True),
        filename,
    )
    last = tree.body[-1]
    if isinstance(last, ast.Expr):
        expr = ast.Expression(last.value)
        tree.body = tree.body[:-1]
        exec(compile(tree, filename, "exec"), globals, locals)
        return eval(compile(expr, filename, "eval"), globals, locals)
    else:
        exec(compile(tree, filename, "exec"), globals, locals)
        return None

""" # + """_exec_with_expr('print("ok")\\n"ok"', globals(), locals())"""

def sandbox_pyenv():
    pid, fd = pty.fork()
    if pid == 0: # child
         # sys.stdout.flush()][
         disable_echo(0)
         os.execvp("bwrap", 
            ["bwrap", "--bind", "/tmp/mysandbox_root", "/", "--ro-bind", "/bin", "/bin", # ใ‚ทใ‚นใƒ†ใƒ ใƒ•ใ‚กใ‚คใƒซใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
             "--ro-bind", "/lib", "/lib", "--ro-bind", "/lib64", "/lib64", 
             "--ro-bind", "/usr", "/usr", "--ro-bind", "/etc", "/etc", # ใ‚ใ‚“ใพใ‚Š่‰ฏใใชใ„
             "--ro-bind", home_dir + "/.local/lib", home_dir + "/.local/lib", # pip ใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
             "--ro-bind", home_dir + "/.local/bin", home_dir + "/.local/bin",
             "--ro-bind", home_dir + "/.local/share", home_dir + "/.local/share",
             "--bind", "/proc", "/proc", "--unshare-all", "--", # ใชใ‚‹ในใใƒ›ใ‚นใƒˆใจ้žๅ…ฑๆœ‰๏ผˆsystemd-nspawnใจ้•ใฃใฆใƒ—ใƒญใ‚ปใ‚นใƒชใ‚นใƒˆใฏๅ…ฑๆœ‰ใ—ใฆใ‚‹ใ‘ใฉ๏ผ‰
             "python", "-i"],  # Pythonใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใƒ†ใ‚ฃใƒ–ใƒขใƒผใƒ‰ใงๆจ™ๆบ–ๅ…ฅๅŠ›ใฎใ‚ณใƒผใƒ‰ใ‚’ๅฎŸ่กŒ
         )
         exit()
    else:
        output = b""
        while True:
            r, _, _ = select.select([fd], [], [])
            chunk = os.read(fd, 1024)
            output += chunk

            if output.endswith(b">>> "):
                #print("debug: bunner: %s"%output)
                break

#    print(_sandbox_pyexec((pid, fd), helper_code))
    _sandbox_pyexec((pid, fd), helper_code)
    return (pid, fd)

TIMEOUT = 3.0 # 3็ง’

def _sandbox_pyexec(senv, code):
    output = b""
    for line in code.split("\n"):
        os.write(senv[1], line.encode("utf-8") + b"\n")

        while True:
            r, _, _ = select.select([senv[1]], [], [], TIMEOUT)
            if not r:
                parent = psutil.Process(senv[0])
                children = parent.children(recursive=True)
                for c in children:
                    if "python" in c.name():
                        c.send_signal(signal.SIGINT)
                output = b""
                while True:
                    r, _, _ = select.select([senv[1]], [], [])
                    chunk = os.read(senv[1], 1024)
                    output += chunk

                    if output.endswith(b">>> "):
                        #print("debug: KeyboardInterrupt: %s"%output)
                        break
                raise TimeoutError("execution timed out")
            chunk = os.read(senv[1], 1024)
            output += chunk

            if output.endswith(b">>> ") or output.endswith(b"... "):
                output = output[:-4] # ใƒ—ใƒญใƒณใƒ—ใƒˆใ‚’้™คๅŽป
                break

    text = output.decode(errors="ignore")
    return text

def sandbox_pyexec(senv, code):
    code = "_exec_with_expr('''" + code.replace('\\', '\\\\').replace("'", "\\'") + "''', globals(), locals())\n"
    return _sandbox_pyexec(senv, code)

def sandbox_reset(senv):
    _sandbox_pyexec(senv, """globals().clear()
import gc
gc.collect()
globals().clear()
""" + helper_code)

senv = sandbox_pyenv()
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a = 100")) # [exec][/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "print(a)")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "b")) # [exec]---------------------------------------------------------------------------\nNameError                                 Traceback (most recent call last)\nFile /tmp/test-4.py:1\n----> 1 b\n\nNameError: name 'b' is not defined\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, """print("aaa")\nprint("bbb")""")) # [exec]aaa\nbbb\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, """print("aaa" + \\\n "bbb")""")) # [exec]aaabbb\n[/exec]

sandbox_reset(senv)
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a"))  # [exec]---------------------------------------------------------------------------\nNameError                                 Traceback (most recent call last)\nFile /tmp/test-1.py:1\n----> 1 a\n\nNameError: name 'a' is not defined\n[/exec]

try:
    print("[exec]%s[/exec]"%sandbox_pyexec(senv, """while True:\n    continue""")) # TimeoutError
except TimeoutError:
    print ("TimeoutError: execution timed out")

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "print(100)")) # [exec]100\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint(100)")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint(\"\"\"ok\"\"\")")) # [exec]ok\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint('''ok''')")) # [exec]ok\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\n'ok'")) # [exec]'ok'\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "# comment test")) # [exec]\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "def a(x): return x*x")) # [exec][/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "\n\na('a')")) # [exec]---------------------------------------------------------------------------\nTypeError                                 Traceback (most recent call last)\nFile /tmp/test-9.py:3\n----> 3 a('a')\nFile /tmp/test-8.py:1, in a(x='a')\n----> 1 def a(x): return x*x\n        x = 'a'\nTypeError: can't multiply sequence by non-int of type 'str'\n[/exec]

Jupyterไบ’ๆ› + Pyrefly็ตฑๅˆ็‰ˆ

้–ขๆ•ฐใ ใ‘ใ‚’่ฟฝๅŠ ใ™ใ‚‹ๆ™‚ใฏใ‚จใƒฉใƒผใŒๅ‡บใชใใฆใ‚ขใƒฌใชใฎใงใ€ใใฎๅ ดๅˆใฏ้™็š„่งฃๆž (lint) ใฎ Pyrefly ใ‚’ๆŽ›ใ‘ใ‚‹ใ‚ˆใ†ใซใ—ใฆใฟใพใ—ใŸ๏ผˆ2026ๅนด1ๆœˆ12ๆ—ฅ่ฟฝ่จ˜๏ผ‰ใ€‚

# License: Public Domain
# pip install pyrefly
# export PATH=$HOME/.local/bin:$PATH
import os
import pty
import termios
import select
import sys
import signal
import psutil
import subprocess
import re


home_dir = os.path.expanduser("~")
try:
    os.makedirs("/tmp/mysandbox_root")
except FileExistsError:
    pass

try:
    os.mkfifo("/tmp/mysandbox_pipe.py")
except FileExistsError:
    pass

def disable_echo(fd):
    attrs = termios.tcgetattr(fd)
    attrs[3] = attrs[3] & ~termios.ECHO  # lflags ใ‹ใ‚‰ ECHO ใ‚’่ฝใจใ™
    termios.tcsetattr(fd, termios.TCSANOW, attrs)

whole_code = ""
whole_code_line = [""]
file_count = 1

# IPythonใฎๅ‹•ไฝœใ‚’ใ‚ทใƒŸใƒฅใƒฌใƒผใƒˆ
# python -m pip install ipython --break-system-packages
helper_code = """from IPython.core.ultratb import VerboseTB
import sys
sys.excepthook = VerboseTB(theme_name="Linux", tb_offset=2)
import linecache

file_count = 1

import ast
def _exec_with_expr(code, globals=None, locals=None):
    global file_count
    tree = ast.parse(code, mode="exec")
    if len(tree.body) == 0:
        print("")
        return None
    filename = "/tmp/test-%s.py"%file_count
    file_count += 1
    linecache.cache[filename] = (
        len(code),
        None,
        code.splitlines(True),
        filename,
    )
    last = tree.body[-1]
    if isinstance(last, ast.Expr):
        expr = ast.Expression(last.value)
        tree.body = tree.body[:-1]
        exec(compile(tree, filename, "exec"), globals, locals)
        return eval(compile(expr, filename, "eval"), globals, locals)
    else:
        exec(compile(tree, filename, "exec"), globals, locals)
        return None

""" # + """_exec_with_expr('print("ok")\\n"ok"', globals(), locals())"""

def sandbox_pyenv():
    pid, fd = pty.fork()
    if pid == 0: # child
         # sys.stdout.flush()][
         disable_echo(0)
         os.execvp("bwrap", 
            ["bwrap", "--bind", "/tmp/mysandbox_root", "/", "--ro-bind", "/bin", "/bin", # ใ‚ทใ‚นใƒ†ใƒ ใƒ•ใ‚กใ‚คใƒซใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
             "--ro-bind", "/lib", "/lib", "--ro-bind", "/lib64", "/lib64", 
             "--ro-bind", "/usr", "/usr", "--ro-bind", "/etc", "/etc", # ใ‚ใ‚“ใพใ‚Š่‰ฏใใชใ„
             "--ro-bind", home_dir + "/.local/lib", home_dir + "/.local/lib", # pip ใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’Read-Onlyใงๅ…ฑๆœ‰ใ™ใ‚‹
             "--ro-bind", home_dir + "/.local/bin", home_dir + "/.local/bin",
             "--ro-bind", home_dir + "/.local/share", home_dir + "/.local/share",
             "--bind", "/proc", "/proc", "--unshare-all", "--", # ใชใ‚‹ในใใƒ›ใ‚นใƒˆใจ้žๅ…ฑๆœ‰๏ผˆsystemd-nspawnใจ้•ใฃใฆใƒ—ใƒญใ‚ปใ‚นใƒชใ‚นใƒˆใฏๅ…ฑๆœ‰ใ—ใฆใ‚‹ใ‘ใฉ๏ผ‰
             "python", "-i"],  # Pythonใฎใ‚คใƒณใ‚ฟใƒฉใ‚ฏใƒ†ใ‚ฃใƒ–ใƒขใƒผใƒ‰ใงๆจ™ๆบ–ๅ…ฅๅŠ›ใฎใ‚ณใƒผใƒ‰ใ‚’ๅฎŸ่กŒ
         )
         exit()
    else:
        output = b""
        while True:
            r, _, _ = select.select([fd], [], [])
            chunk = os.read(fd, 1024)
            output += chunk

            if output.endswith(b">>> "):
                #print("debug: bunner: %s"%output)
                break

#    print(_sandbox_pyexec((pid, fd), helper_code))
    _sandbox_pyexec((pid, fd), helper_code)
    return (pid, fd)

TIMEOUT = 3.0 # 3็ง’

def _sandbox_pyexec(senv, code):
    output = b""
    for line in code.split("\n"):
        os.write(senv[1], line.encode("utf-8") + b"\n")

        while True:
            r, _, _ = select.select([senv[1]], [], [], TIMEOUT)
            if not r:
                parent = psutil.Process(senv[0])
                children = parent.children(recursive=True)
                for c in children:
                    if "python" in c.name():
                        c.send_signal(signal.SIGINT)
                output = b""
                while True:
                    r, _, _ = select.select([senv[1]], [], [])
                    chunk = os.read(senv[1], 1024)
                    output += chunk

                    if output.endswith(b">>> "):
                        #print("debug: KeyboardInterrupt: %s"%output)
                        break
                raise TimeoutError("execution timed out")
            chunk = os.read(senv[1], 1024)
            output += chunk

            if output.endswith(b">>> ") or output.endswith(b"... "):
                output = output[:-4] # ใƒ—ใƒญใƒณใƒ—ใƒˆใ‚’้™คๅŽป
                break

    text = output.decode(errors="ignore")
    return text

def sandbox_pyexec(senv, code):
    global whole_code
    global whole_code_line
    global file_count

    file_count += 1
    e_code = "_exec_with_expr('''" + code.replace('\\', '\\\\').replace("'", "\\'") + "''', globals(), locals())\n"
    r = _sandbox_pyexec(senv, e_code)

#    print([r[i].encode("utf-8") if i < len(r) else None for i in range(5)])

    # ใ‚จใƒฉใƒผใซใชใฃใŸใ‚ณใƒผใƒ‰ใฏๅฑฅๆญดใซๆฎ‹ใ•ใชใ„
    if r.startswith("\x1b[91m---------------------------------------------------------------------------"):
        return r

    # lintใŒ้€šใ‚‰ใชใ‹ใฃใŸๆ™‚ใ‚‚ๅฑฅๆญดใซใฏๆฎ‹ใ™๏ผˆๅฎŸ้š›ใซๆฎ‹ใฃใฆใ‚‹ใŸใ‚๏ผ‰
    whole_code = whole_code + code + "\n"
    for i, v in enumerate(code.split("\n")): # TODO: ไฝฟใ†ๅดใงไบŒๅˆ†ๆœจใซใ—ใŸๆ–นใŒ่‰ฏใ„
        whole_code_line.append("test-%s.py in <cell line: %s>"%(file_count - 1, i))
#    print(whole_code_line)
#    print(whole_code)


    # ่ฟ”ใ‚Šๅ€คใŒไฝ•ใ‚‚ใชใ„ๆ™‚๏ผˆ้–ขๆ•ฐใ ใ‘ใชใฉ๏ผ‰ใฏlintใซๆŽ›ใ‘ใ‚‹
    if r == "":
        proc = subprocess.Popen(["pyrefly", "check", "/tmp/mysandbox_pipe.py"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True)
        with open("/tmp/mysandbox_pipe.py", "a", encoding="utf-8") as f:
            f.write(whole_code)

        stdout, stderr = proc.communicate()
        def replace_with_array_access(match):
            return whole_code_line[int(match.group(1))] + ":" + match.group(2)
        stdout = re.sub(r'/tmp/mysandbox_pipe.py:(\d+):(\d+)', replace_with_array_access, stdout)
        return stdout

    return r

def sandbox_reset(senv):
    global whole_code
    global whole_code_line
    global file_count
    _sandbox_pyexec(senv, """globals().clear()
import gc
gc.collect()
globals().clear()
""" + helper_code)
    whole_code = ""
    whole_code_line = [""]
    file_count = 1

senv = sandbox_pyenv()
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a = 100")) # [exec][/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "print(a)")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "b")) # [exec]---------------------------------------------------------------------------\nNameError                                 Traceback (most recent call last)\nFile /tmp/test-4.py:1\n----> 1 b\n\nNameError: name 'b' is not defined\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, """print("aaa")\nprint("bbb")""")) # [exec]aaa\nbbb\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, """print("aaa" + \\\n "bbb")""")) # [exec]aaabbb\n[/exec]

sandbox_reset(senv)
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "a"))  # [exec]---------------------------------------------------------------------------\nNameError                                 Traceback (most recent call last)\nFile /tmp/test-1.py:1\n----> 1 a\n\nNameError: name 'a' is not defined\n[/exec]

try:
    print("[exec]%s[/exec]"%sandbox_pyexec(senv, """while True:\n    continue""")) # TimeoutError
except TimeoutError:
    print ("TimeoutError: execution timed out")

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "print(100)")) # [exec]100\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint(100)")) # [exec]100\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint(\"\"\"ok\"\"\")")) # [exec]ok\n[/exec]
print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\nprint('''ok''')")) # [exec]ok\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "if True:\n    pass\n'ok'")) # [exec]'ok'\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "# comment test")) # [exec]\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "def a(x): return x*x")) # [exec][/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "\n\na('a')")) # [exec]---------------------------------------------------------------------------\nTypeError                                 Traceback (most recent call last)\nFile /tmp/test-9.py:3\n----> 3 a('a')\nFile /tmp/test-8.py:1, in a(x='a')\n----> 1 def a(x): return x*x\n        x = 'a'\nTypeError: can't multiply sequence by non-int of type 'str'\n[/exec]

print("[exec]%s[/exec]"%sandbox_pyexec(senv, "import sympy as sp\ndef a(x):\n    sp.undefined()\n    return sp.undefined2()"))
"""
[exec]ERROR No attribute `undefined` in module `sympy` [missing-attribute]
  --> test-11.py in <cell line: 2>:5
   |
18 |     sp.undefined()
   |     ^^^^^^^^^^^^
   |
ERROR No attribute `undefined2` in module `sympy` [missing-attribute]
  --> test-11.py in <cell line: 3>:12
   |
19 |     return sp.undefined2()
   |            ^^^^^^^^^^^^^
   |
[/exec]
"""
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Today's trending articles

2026ๅนด!ๅˆใ‚ขใ‚ฆใƒˆใƒ—ใƒƒใƒˆใ‚’ใ—ใ‚ˆใ†
oageST

ไบบ็”Ÿๅˆใฎๅ‰ฏๆฅญใงใ€่ฆไปถๅฎš็พฉใƒปใ‚นใ‚ฑใ‚ธใƒฅใƒผใƒซ็ฎก็†ใƒปAPI็”ณ่ซ‹ใƒปๆœฌๆฅญใƒใƒƒใƒ†ใ‚ฃใƒณใ‚ฐใซๅ…จ้ƒจใ‚„ใ‚‰ใ‚ŒใŸ่ฉฑ

Comments

No comments

Let's comment your feelings that are more than good

Being held Article posting campaign

2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address