2012-03-21 11 views
8

Supponiamo che tu stia lavorando con qualche pezzo di codice che non ti puoi fidare, esiste un modo per eseguirlo senza perdere il controllo del tuo script?Come eseguire in sicurezza un pezzo di codice inaffidabile?

Un esempio potrebbe essere una funzione che funziona solo in parte e potrebbe non riuscire in modo casuale/spettacolare, come si può riprovare finché non funziona? Ho provato un po 'di hacking con l'uso del modulo di threading ma ho avuto problemi a uccidere un thread appeso ordinatamente.

#!/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!!": 
    # ??? 
+5

Quanto è spettacolare il blocco del codice? È persino sicuro eseguirlo nello stesso interprete Python del proprio codice? Se usa le estensioni c spezzate (o ne abusa quelle non interrotte), o potenzialmente modifica le globali python, potrebbe essere necessario eseguirlo in un interprete python completamente diverso in un sottoprocesso. –

risposta

4

È possibile provare a eseguirlo in un sandbox.

5

di essere al sicuro contro eccezioni, utilizzare try/tranne (ma credo che tu sai).

Per essere sicuri contro il codice sospeso (ciclo infinito), l'unico modo che conosco è eseguire il codice in un altro processo. Questo processo figlio può essere eliminato dal processo padre nel caso in cui non si risolva abbastanza presto.

Per essere al sicuro da codice sgradevole (fare cose che non deve fare), dare un'occhiata a http://pypi.python.org/pypi/RestrictedPython.

+3

C'è anche PySandbox - https://github.com/haypo/pysandbox/ – Darb

4

Nella tua applicazione reale puoi passare al multiprocessing? Per questo sembra che ciò che state chiedendo potrebbe essere fatto con multiprocessing + threading.Timer + try/except.

Date un'occhiata a questo:

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) 

che in un caso (fortunato) mi ha dato:

Running 
Empty 
None 
Running 
it worked!! 

Nei tuoi esempi di codice che avete 4 su 5 possibilità di ottenere un errore, quindi potresti anche generare una piscina o qualcosa per migliorare le tue possibilità di avere un risultato corretto.

Problemi correlati