2013-02-18 4 views
7

Używam urllib.request.urlopen() do pobrania z usługi sieci Web próbuję przetestować.gniazdo ResourceWarning za pomocą urllib w Pythonie 3

Powoduje to zwrócenie obiektu HTTPResponse, który następnie odczytuję() w celu pobrania treści odpowiedzi.

Ale zawsze zobaczyć ResourceWarning o niezamkniętych gniazda z socket.py

Oto odpowiednia funkcja:

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) 

Oto ostrzeżenie, gdyż pojawia się na wyjściu programu:

$ ./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) 

Jeśli jest coś, co mogę zrobić z HTTPResponse (lub Żądaniem?), Aby całkowicie zamknąć to gniazdo, Bardzo bym chciał wiedzieć, ponieważ ten kod służy do testów jednostkowych; Nie lubię ignorowanie ostrzeżeń w dowolnym miejscu, ale w szczególności ich nie ma.

+1

Nie mogę odtworzyć go w Pythonie 3.3.1. Czy możesz przetestować go na najnowszej wersji Pythona; było kilka błędów związanych z [zamykaniem gniazda] (http://bugs.python.org/issue12133) (ResourceWarning na timeout) i ['Connection: close" 'nagłówek odpowiedzi] (http: // bugs. python.org/issue12576) (pokazuje różne ścieżki kodu w zależności od nagłówka). – jfs

Odpowiedz

3

Nie wiem, czy jest to odpowiedź na odpowiedź, ale jest to część drogi do odpowiedzi.

Jeśli dodaję nagłówek "połączenie: zamknij" do odpowiedzi z moich usług internetowych, obiekt HTTPResponse wydaje się prawidłowo czyścić bez ostrzeżenia.

A w rzeczywistości, HTTP Spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) mówi:

HTTP/1.1 aplikacji, które nie obsługują połączeń trwałych MUSI zawierać „Zamknij” opcję połączenia w każdej wiadomości.

Więc problem był na końcu serwera (tj. Moja wina!). Jeśli nie masz kontroli nad nagłówkami pochodzącymi z serwera, nie wiem, co możesz zrobić.