New submission from FeRD (Frank Dana) <ferd...@gmail.com>:

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.

----------
components: Library (Lib)
messages: 415568
nosy: ferdnyc
priority: normal
severity: normal
status: open
title: socket._GLOBAL_DEFAULT_TIMEOUT being an object() makes for ugly 
docstrings, can be better
type: enhancement
versions: Python 3.11

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue47069>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to