classification
Title: Context manager of socket.socket is not documented
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: berker.peksag, desbma, docs@python, martin.panter, python-dev, vstinner, yselivanov
Priority: normal Keywords: easy, patch

Created on 2015-08-21 20:34 by desbma, last changed 2016-04-24 06:23 by martin.panter. This issue is now closed.

Files
File name Uploaded Description Edit
socket-context.patch martin.panter, 2015-08-31 04:14 review
socket-context.v2.patch martin.panter, 2016-02-18 00:37 review
Messages (9)
msg248979 - (view) Author: desbma (desbma) * Date: 2015-08-21 20:34
socket.socket has a context manager to automatically close the socket with the `with` statement: https://hg.python.org/cpython/file/d1bf181afa82/Lib/socket.py#l138

However it is not documented, unlike socket.create_connection.
msg249172 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-08-26 01:40
IMO the change notice for create_connection() should be moved to apply to the “socket” class, perhaps the “Socket Objects” section. Issue 9794 looks like context manager support was added specifically for create_connection(), however any socket object, no matter what function is used to create it, should be usable the same way for free.

Also, we should explicitly document that exiting the context manager (“with” statement) invokes close(), since that affects how the underlying socket is closed when makefile() has been used.
msg249381 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-08-31 04:14
Here is my proposed patch
msg260358 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-02-16 11:53
socket-context.patch looks good to me. There is no need to add a NEWS entry for this.
msg260363 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2016-02-16 16:03
The patch looks good.  It would also be cool if you can add a short code snippet somewhere:

   sock = socket.socket()
   with sock:
      sock.bind(('127.0.0.1', 8080))
      sock.listen()
      ...
msg260393 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-02-17 11:25
I reviewed the patch.

> It would also be cool if you can add a short code snippet somewhere:

The socket module has examples.

Why not modifying these examples to promote the context manager protocol?

Example:
--------
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s
# use with to ensure that the socket is closed, especially on error
with s:
  s.bind((HOST, PORT))
  s.listen(1)
  conn, addr = s.accept()
  with conn:
    print('Connected by', addr)
    while True:
        data = conn.recv(1024)
        if not data: break
        conn.sendall(data)
    conn.close()
--------

The second "with conn:" is maybe overkill. What do you think?

For a client connection, usually I prefer to explicitly close the socket (even if I use "with conn:") to get exception on my ".close()" line, instead of getting an exception from the context manager, which is harder to understand.
msg260419 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-18 00:37
Thanks for the reviews.

In this new patch, I modified two existing examples, but did not add any new example. Does that work for you Yury?

Also modified example code for the socketserver module.

Victor: IMO the “with conn” in the example is not overkill. It ensures the client connection socket is cleaned up, which is completely independent of the server listening socket s.

What exceptions can you get out of conn.close()? I can only think of unusual programming errors like EBADF. I would prefer to remove close() as being redundant with the context manager.
msg262840 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-04-04 02:16
FWIW I discovered that socket.close() or __exit__() does not actually raise exceptions for cases like EBADF, see Issue 26685.
msg264094 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-04-24 04:55
New changeset d5f7980dd654 by Martin Panter in branch '3.5':
Issue #24911: All socket objects are context managers; update examples
https://hg.python.org/cpython/rev/d5f7980dd654

New changeset 711201953505 by Martin Panter in branch 'default':
Issue #24911: Merge socket context manager doc from 3.5
https://hg.python.org/cpython/rev/711201953505
History
Date User Action Args
2016-04-24 06:23:24martin.pantersetstatus: open -> closed
resolution: fixed
stage: commit review -> resolved
2016-04-24 04:55:45python-devsetnosy: + python-dev
messages: + msg264094
2016-04-04 02:16:04martin.pantersetmessages: + msg262840
2016-02-18 00:37:22martin.pantersetfiles: + socket-context.v2.patch

messages: + msg260419
2016-02-17 11:25:01vstinnersetnosy: + vstinner
messages: + msg260393
2016-02-16 16:03:12yselivanovsetnosy: + yselivanov
messages: + msg260363
2016-02-16 11:53:11berker.peksagsetversions: - Python 3.4
nosy: + berker.peksag

messages: + msg260358

stage: patch review -> commit review
2015-08-31 04:14:54martin.pantersetfiles: + socket-context.patch
keywords: + patch
messages: + msg249381

stage: needs patch -> patch review
2015-08-26 01:40:14martin.pantersetnosy: + martin.panter
messages: + msg249172
2015-08-25 02:18:46berker.peksagsetkeywords: + easy
stage: needs patch
type: enhancement
versions: + Python 3.5, Python 3.6
2015-08-21 20:34:06desbmacreate