How to use socket in Python as a context manager?

ChaimKut picture ChaimKut · May 27, 2013 · Viewed 20.2k times · Source

It seems like it would be only natural to do something like:

with socket(socket.AF_INET, socket.SOCK_DGRAM) as s:

but Python doesn't implement a context manager for socket. Can I easily use it as a context manager, and if so, how?

Answer

Martijn Pieters picture Martijn Pieters · May 27, 2013

The socket module is fairly low-level, giving you almost direct access to the C library functionality.

You can always use the contextlib.contextmanager decorator to build your own:

import socket
from contextlib import contextmanager

@contextmanager
def socketcontext(*args, **kw):
    s = socket.socket(*args, **kw)
    try:
        yield s
    finally:
        s.close()

with socketcontext(socket.AF_INET, socket.SOCK_DGRAM) as s:

or use contextlib.closing() to achieve the same effect:

from contextlib import closing

with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as s:

but the contextmanager() decorator gives you the opportunity to do other things with the socket first.

Python 3.x does make socket() a context manager, but the documentation wasn't updated to reflect this until well into the Python 3.5 cycle, in 2016. See the socket class in the source code, which adds __enter__ and __exit__ methods.