REPL preview / throwOnSideEffect / Sandboxing

Context: I was thinking about having embedding Python in a REPL with live preview of evaluation result of pure functions. Similar to nodejs REPL or Chrome DevTools (which uses {throwOnSideEffect: true} under the hood). This is somewhat similar to sandboxing. I'm aware of tricks like `object.__subclasses__` to get "hidden" types, and `type(func)(...)` to construct functions from bytecode. Currently I'm approaching it slightly differently and I didn't find previous discussions. If we define "side effects" as effects outside the current process (ex. filesystem), and allow mutation of in-process global state (ex. `sys.modules`). Then it seems all pure Python code is side-effect free, and only those C functions (ex. `open`) need to be checked. In this world, we allow arbitrary pure Python code including constructing a Python function from bytecode, as long as native functions are checked. Looking at existing APIs, I think `PyEval_SetProfile` can be abused to achieve that kind of "throw on side effect" easily - when the profile function gets a `PyTrace_C_CALL` event, it can examines the C function and decide to raise if necessary. The missing piece is to define the whitelist of side-effect free native functions, such as `sorted`, `join`, etc. I wonder what people think about this approach, and whether this is worth some sort of core support (ex. native functions whitelist per `PyThreadState`, builtin function to run another function in restricted mode). I can envision this to be useful in IPython, potentially interesting to other applications wanting a "declarative", "pure" scripting language, especially when the embedding applications can define their types and tweak the list of side-effect free functions.
participants (1)
-
Jun Wu