This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: socket._GLOBAL_DEFAULT_TIMEOUT being an object() makes for ugly docstrings, can be better
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ferdnyc
Priority: normal Keywords:

Created on 2022-03-19 20:18 by ferdnyc, last changed 2022-04-11 14:59 by admin.

Messages (1)
msg415568 - (view) Author: FeRD (Frank Dana) (ferdnyc) * Date: 2022-03-19 20:18
socket._GLOBAL_DEFAULT_TIMEOUT's status as a bare object() instance has been brought up before (bpo-12441). That was reported as a bug, but appeared to stem from developer confusion, so it was correctly closed as "not a bug". At the time @orsenthil defended _GLOBAL_DEFAULT_TIMEOUT's current status quo as:

> The _GLOBAL_DEFAULT_TIMEOUT usage is an established pattern with socket > module. https://github.com/python/cpython/blob/main/Lib/socket.py#L805

I don't disagree with that, but I think it can be improved upon, which is why I'm opening this as an enhancement instead of a bug report.

If nothing else, the current implementation of _GLOBAL_DEFAULT_TIMEOUT makes for some really ugly method synopses, both in socket.py and in other classes that make use of it:

>>> import socket, urllib.request
>>> help(socket.create_connection)
Help on function create_connection in module socket:

create_connection(address, timeout=<object object at 0x7f9986ed8880>, source_address=None)
    Connect to *address* and return the socket object.

>>> help(urllib.request.urlopen)
Help on function urlopen in module urllib.request:

urlopen(url, data=None, timeout=<object object at 0x7f9986ed8880>, *, cafile=None, capath=None, cadefault=False, context=None)
    Open the URL url, which can be either a string or a Request object.

>>>


...Converting socket._GLOBAL_DEFAULT_TIMEOUT from an object() instance to a bare class definition, in the style of an Exception subclass, appears to be semantically equivalent in all cases, but has the advantage that the resulting docstrings become VASTLY more readable:

>>> import myedits; import myedits.socket as socket
>>> help(socket.create_connection)
Help on function create_connection in module myedits.socket:

create_connection(address, timeout=<class 'myedits.socket._GLOBAL_DEFAULT_TIMEOUT'>, source_address=None)
    Connect to *address* and return the socket object.

>>> import sys; sys.modules['socket'] = myedits.socket
>>> import myedits.urllib.request
>>> help(myedits.urllib.request.urlopen)
urlopen(url, data=None, timeout=<class 
Help on function urlopen in module myedits.urllib.request:

urlopen(url, data=None, timeout=<class 'myedits.socket._GLOBAL_DEFAULT_TIMEOUT'>, *, cafile=None, capath=None, cadefault=False, context=None)
    Open the URL url, which can be either a string or a Request object.

>>>


Unless someone objects, I'd like to open a PR changing the definition of  socket._GLOBAL_DEFAULT_TIMEOUT from:

_GLOBAL_DEFAULT_TIMEOUT = object()

to:

class _GLOBAL_DEFAULT_TIMEOUT: pass

While leaving everything else the same. AFAICT from testing, that should have no impact on the functionality of socket or its consumers, but improve life for Python developers by making the module more readable and self-documenting.
History
Date User Action Args
2022-04-11 14:59:57adminsetgithub: 91225
2022-03-19 20:18:03ferdnyccreate