How to safely run the untrusted part of the code?

Suppose you are working with some piece of code that you cannot trust, is there a way to safely run it without losing control of your script?

An example would be a function that only works for a while and can accidentally or spectacularly end, how could you try again until it works? I tried to hack using the streaming module, but I had a problem to gently kill the curled stream.

#!/usr/bin/env python import os import sys import random def unreliable_code(): def ok(): return "it worked!!" def fail(): return "it didn't work" def crash(): 1/0 def hang(): while True: pass def bye(): os._exit(0) return random.choice([ok, fail, crash, hang, bye])() result = None while result != "it worked!!": # ??? 
+8
python debugging multithreading logging
source share
3 answers

You can try running it in the sandbox .

+4
source share

To be safe from exceptions, use try / except (but I think you know that).

To be safe from code hanging (endless loop), the only way I know is to run the code in another process. This is a child process that you can kill from the father process, in case it does not end soon enough.

To be safe from nasty code (doing things that it shouldn't), see http://pypi.python.org/pypi/RestrictedPython .

+5
source share

In your real application, can you switch to multiprocessing? It looks like what you are asking for can be done using multiprocessing + threading.Timer + try/except .

Take a look at this:

 class SafeProcess(Process): def __init__(self, queue, *args, **kwargs): self.queue = queue super().__init__(*args, **kwargs) def run(self): print('Running') try: result = self._target(*self._args, **self._kwargs) self.queue.put_nowait(result) except: print('Exception') result = None while result != 'it worked!!': q = Queue() p = SafeProcess(q, target=unreliable_code) p.start() t = Timer(1, p.terminate) # in case it should hang t.start() p.join() t.cancel() try: result = q.get_nowait() except queues.Empty: print('Empty') print(result) 

This in one (happy) case gave me:

 Running Empty None Running it worked!! 

In your code samples, you have 4 out of 5 chances of getting an error message, so you can also create a pool or something that will improve your chances of getting the right result.

+4
source share

All Articles