ResourceWarning in python 3.2+

Requests issues a ResourceWarning in python 3.2+ as sockets are not explicitly closed before garbage collection occurs. While ResourceWarnings are not displayed by default, it can be a distraction to some developers when working with warnings enabled.

File: test.py

``` python
import requests

def make_request():
    resp = requests.get('http://google.com')
    resp.close()  # this appears to have no effect, even though the function exists

make_request()
```

```
$ python -Wall test.py 
test.py:7: ResourceWarning: unclosed <socket.socket object, fd=4, family=2, type=1, proto=6>
  make_request()
test.py:7: ResourceWarning: unclosed <socket.socket object, fd=3, family=2, type=1, proto=6>
  make_request()
```

It would be great if there was a way to prevent the ResourceWarning from occurring, without issuing a `Connection:close` header.


Thanks for this!

This is actually a behaviour in urllib3. I'm going to summon @shazow into this conversation, but I believe this is a deliberate design decision. We can often reuse the socket object to reconnect to the same host without the overhead of recreating the object. This makes this deliberate. I wonder if we can silence the warning.


I think the problem might be fixed (in urllib3's end) if when the connection pool is garbage collected, it explicitly closes all of its sockets, rather than using the previously okay (didn't issue warnings in python < 3.2) method of allowing garbage collection to close them.


urllib3 has a [`pool.close()`](https://github.com/shazow/urllib3/blob/master/urllib3/connectionpool.py#L347) which does this. We decided explicit is better than automatically doing it on garbage collection because you may be manually hanging on to connections/requests outside of the pool (e.g. when streaming).


I also ran into this in writing unit tests.

As a workaround, here are [docs on temporarily suppressing warnings](https://docs.python.org/3/library/warnings.html#temporarily-suppressing-warnings) on a case by case basis.

```
import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    fxn()
```


Thanks @here 


after for some wired reason <a href="https://docs.python.org/3/library/warnings.html#temporarily-suppressing-warnings" > suppressing warnings  </a> didnt work for me (still dont know why)
i came across this:

<pre>
   req=requests.get('http://google.com')
   req.connection.close()
</pre>

and no more "ResourceWarning"....
is it an actual solution? dose it work for you too?


Is this fixed? I'm using 

```
closing(requests.post("something.com", stream=True)) as r:
    # do stuff
```

and i'm still getting (while using this within a unittest.TestCase method)

`/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/unittest/case.py:574: ResourceWarning: unclosed <socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=6, laddr=('someip', 57353), raddr=('someip', 81)>
  testMethod()`


This is not fixed, because we're not entirely confident it's a bug. =) The warning is annoying but it's not symptomatic of a problem.


@Lukasa: if this is not a bug, then what exactly is it? It seems to be that its complaining that a connection was left open after the unit tests ended, but how can that be if I'm wrapping the requests.post() call with contextlib.closing() like the documentation mentions here? http://docs.python-requests.org/en/latest/user/advanced/#body-content-workflow am I doing something incorrect?


Nope, you're just running into the magic of requests. =)

We use connection pooling under the covers. This means we attempt to recycle socket objects as much as possible, by leaving them connected. This is an efficiency gain, as creating socket objects is expensive and connecting them is even more expensive.

When you use `requests.X`, that creates a `Session` and `ConnectionPool` under the covers and then throws them away. This behaviour means the socket object owned by the `ConnectionPool` is cleaned up by the garbage collector, which will close the socket when it does so.

What's important is that `response.close()` does not close all open sockets on the underlying `ConnectionPool` because that would be ridiculous, it just returns the socket to the pool. To get the behaviour you want (please close all sockets), you need to use an explicit `Session` object and then clean up with `Session.close()`.


Would it be possible to expose a `requests.close()` method to access the global, shared `Session` hiding in the module? Or perhaps `requests.set_session()`? Some better alternative than plumbing a `Session` through everything and creating a leaky abstraction?


@thejohnfreeman we create a new session every time you make a request with `requests.{get,post,put,delete,etc.}`. See [the relevant code in `requests/api.py`](https://github.com/kennethreitz/requests/blob/master/requests/api.py#L48)


@here suppressing the warning with `warnings.catch_warnings()` is not guaranteed to work because the warning is issued when the connection pool is garbage collected which can happen after the context manager has closed.


@siebenschlaefer That's correct, which is why we recommend you use explicit `Session` objects. =)


Related: #3912 (_ResourceWarning: unclosed socket.socket when I run a unittest?_)