2013-02-18 8 views
7

Sto utilizzando un urllib.request.urlopen() per ottenere da un servizio Web che sto provando a testare.socket ResourceWarning utilizzando urllib in Python 3

Questo restituisce un oggetto HTTPResponse, che quindi leggerò() per ottenere il corpo della risposta.

Ma vedo sempre un ResourceWarning su una presa non chiusa da socket.py

Ecco la relativa funzione:

from urllib.request import Request, urlopen 

def get_from_webservice(url): 
    """ GET from the webservice """ 
    req = Request(url, method="GET", headers=HEADERS) 
    with urlopen(req) as rsp: 
     body = rsp.read().decode('utf-8') 
     return json.loads(body) 

Ecco l'avvertimento come appare nel output del programma:

$ ./test/test_webservices.py 
/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/socket.py:359: ResourceWarning: unclosed <socket.socket object, fd=5, family=30, type=1, proto=6> 
self._sock = None 
.s 
---------------------------------------------------------------------- 
Ran 2 tests in 0.010s 

OK (skipped=1) 

Se c'è qualcosa che posso fare a HTTPResponse (o alla richiesta?) Per farlo chiudere il suo socket in modo pulito, Mi piacerebbe molto per sapere, perché questo codice è per i miei test di unità; Non mi piace lo ignorare gli avvisi ovunque, ma soprattutto non lì.

+1

Non riesco a riprodurlo su Python 3.3.1. Potresti testarlo sull'ultima versione di Python; c'erano un paio di bug relativi a [chiusura del socket] (http://bugs.python.org/issue12133) (ResourceWarning su timeout) e ['" Connection: close "' header di risposta] (http: // bugs. python.org/issue12576) (mostra che ci sono percorsi di codice diversi a seconda dell'intestazione). – jfs

risposta

3

Non so se questo è la risposta, ma è parte del modo di una risposta.

Se aggiungo l'intestazione "connection: close" alla risposta dai miei servizi Web, l'oggetto HTTPResponse sembra pulirsi correttamente senza alcun avviso.

E infatti, il HTTP Spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) dice:

HTTP/1.1 le applicazioni che non supportano le connessioni persistenti deve includere la "stretta" opzione di connessione in ogni messaggio.

Così il problema era sul lato server (cioè colpa mia!). Nel caso in cui non si abbia il controllo sulle intestazioni provenienti dal server, non so cosa si possa fare.