typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

OSError stubs don't match actual types for TimeoutError subclass

Open chrisdahlberg opened this issue 2 years ago • 6 comments

OSError is currently stubbed as:

class OSError(Exception):
    errno: int
    strerror: str
    # filename, filename2 are actually str | bytes | None
    filename: Any
    filename2: Any
    if sys.platform == "win32":
        winerror: int

The CPython TimeoutError subclass of it returned by socket functions will sometimes have errno and strerror None depending on which underlying syscall detected the timeout (select() reporting 0 sockets ready vs something failing with ETIMEDOUT)

Example:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.1)
try:
    # Try to connect to a host that doesn't exist on your
    # network
    s.connect(("10.10.10.10", 22))
except OSError as ex:
    print(repr(ex))
    print(f"errno is {type(ex.errno)} - {ex.errno}")
    print(f"strerror is {type(ex.strerror)} - {ex.strerror}")

produces

TimeoutError('timed out')
errno is <class 'NoneType'> - None
strerror is <class 'NoneType'> - None

on Python 3.10.9 | packaged by conda-forge | (main, Feb 2 2023, 20:14:58) [MSC v.1929 64 bit (AMD64)]

The CPython implementation looks like it would do the same on all platforms


(@srittau 2024-09-02) Deferred until python/cpython#109601 and python/cpython#109714 are decided on.

chrisdahlberg avatar Mar 10 '23 22:03 chrisdahlberg

Interesting -- the docs pretty clearly imply that errno and strerror should always be (respectively) int and str for OSError: https://docs.python.org/3/library/exceptions.html#OSError. And there's nothing in the docs for TimeoutError to suggest that the types for these attributes on the subclass should be any different: https://docs.python.org/3/library/exceptions.html#TimeoutError.

I wonder if this is a bug in CPython (or, at the very least, a bug in the CPython docs for OSError/TimeoutError?).

AlexWaygood avatar Mar 11 '23 17:03 AlexWaygood

@AlexWaygood According to https://docs.python.org/3/library/exceptions.html#TimeoutError and the corresponding errno https://docs.python.org/3/library/errno.html#errno.ETIMEDOUT should by default have a value, so on Linux 110 and on Windows 138 if I'm not wrong.

I'll open an issue in CPython repo with reference to this to see if this is an docs issue or implementation in CPython.

aminalaee avatar Sep 20 '23 08:09 aminalaee

I've marked this as deferred for now, pending the outcome of python/cpython#109601 and python/cpython#109714.

srittau avatar Sep 02 '24 21:09 srittau

Any change in CPython would almost certainly apply only to 3.14, so we may still want to change the types in typeshed for earlier versions.

JelleZijlstra avatar Sep 02 '24 21:09 JelleZijlstra

That makes sense. Based on the PR I think it's not only the TimeoutError and other subclasses of OSError could be like this. Do we want to change all of them or just TimeoutError? This could be coming from different places so I'm not sure how to decide this.

aminalaee avatar Sep 03 '24 07:09 aminalaee

While we could try an exploratory PR, I suspect that adding None will be very disruptive.

srittau avatar Sep 03 '24 09:09 srittau