Skip to content

gh-50720: Set errno and strerror on URLError wrapping an OSError - #160938

Merged
orsenthil merged 2 commits into
python:mainfrom
vasiliyk:gh-50720-urllib
Oct 31, 2026
Merged

orsenthil merged 2 commits into
python:mainfrom
vasiliyk:gh-50720-urllib

Conversation

@vasiliyk

@vasiliyk vasiliyk commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

URLError wrapping an OSError such as socket.gaierror always had errno and strerror set to None.

This PR copies errno and strerror from the reason when it is an OSError.
A string reason leaves both attributes None, as before.

@read-the-docs-community

read-the-docs-community Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Comment thread Lib/urllib/error.py
self.reason = reason
if filename is not None:
self.filename = filename
if isinstance(reason, OSError):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only question is winerror Should we handle that?
We don't have a great on windows and if winerror will be different than errno for the scenarios that URLError will capture.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping this just as thought. Not a blocker.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, winerror stays None on Windows while the wrapped error carries the code. For socket errors it equals errno, but it differs for non-socket errors wrapped by FileHandler.

Should I open a separate improvement issue for it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a windows system, could you verify it with a some tests?
Exposing winerror gated by system check will be good.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only have macOS and Linux.

The CI runs the test suite on Windows, so a Windows-only test would be verified there. I can open a follow-up PR that copies winerror behind a platform check, with the test skipped elsewhere.

What do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sounds good to me.

@orsenthil
orsenthil enabled auto-merge (squash) October 31, 2026 15:58
@orsenthil
orsenthil merged commit 2cf2dd6 into python:main Oct 31, 2026
101 of 103 checks passed
@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot x86 Debian Installed with X 3.x (tierless) has failed when building commit 2cf2dd6.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/1244/builds/10167) and take a look at the build logs.
  4. Check if the failure is related to this commit (2cf2dd6) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1244/builds/10167

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1575�[0m, in �[35mftp_open�[0m
    fp, retrlen = �[31mfw.retrfile�[0m�[1;31m(file, type)�[0m
                  �[31m~~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1845�[0m, in �[35mretrfile�[0m
    conn, retrlen = �[31mself.ftp.ntransfercmd�[0m�[1;31m(cmd)�[0m
                    �[31m~~~~~~~~~~~~~~~~~~~~~�[0m�[1;31m^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m359�[0m, in �[35mntransfercmd�[0m
    resp = self.sendcmd(cmd)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m281�[0m, in �[35msendcmd�[0m
    return �[31mself.getresp�[0m�[1;31m()�[0m
           �[31m~~~~~~~~~~~~�[0m�[1;31m^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m252�[0m, in �[35mgetresp�[0m
    raise error_temp(resp)
�[1;35mftplib.error_temp�[0m: �[35m425 Security: Bad IP connecting.�[0m


Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m381�[0m, in �[35mtest_ftp_no_timeout�[0m
    u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m32�[0m, in �[35mwrapped�[0m
    return _retry_thrice(func, exc, *args, **kwargs)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m28�[0m, in �[35m_retry_thrice�[0m
    raise last_exc
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m24�[0m, in �[35m_retry_thrice�[0m
    return func(*args, **kwargs)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m187�[0m, in �[35murlopen�[0m
    return �[31mopener.open�[0m�[1;31m(url, data, timeout)�[0m
           �[31m~~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m489�[0m, in �[35mopen�[0m
    response = self._open(req, data)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m506�[0m, in �[35m_open�[0m
    result = self._call_chain(self.handle_open, protocol, protocol +
                              '_open', req)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m466�[0m, in �[35m_call_chain�[0m
    result = func(*args)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1588�[0m, in �[35mftp_open�[0m
    raise URLError(f"ftp error: {exp}") from exp
�[1;35murllib.error.URLError�[0m: �[35m<urlopen error ftp error: 425 Security: Bad IP connecting.>�[0m


Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1575�[0m, in �[35mftp_open�[0m
    fp, retrlen = �[31mfw.retrfile�[0m�[1;31m(file, type)�[0m
                  �[31m~~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1865�[0m, in �[35mretrfile�[0m
    conn, retrlen = �[31mself.ftp.ntransfercmd�[0m�[1;31m(cmd)�[0m
                    �[31m~~~~~~~~~~~~~~~~~~~~~�[0m�[1;31m^^^^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m359�[0m, in �[35mntransfercmd�[0m
    resp = self.sendcmd(cmd)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m281�[0m, in �[35msendcmd�[0m
    return �[31mself.getresp�[0m�[1;31m()�[0m
           �[31m~~~~~~~~~~~~�[0m�[1;31m^^�[0m
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/ftplib.py"�[0m, line �[35m252�[0m, in �[35mgetresp�[0m
    raise error_temp(resp)
�[1;35mftplib.error_temp�[0m: �[35m425 Security: Bad IP connecting.�[0m


Traceback (most recent call last):
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m286�[0m, in �[35m_test_urls�[0m
    f = urlopen(url, req, support.INTERNET_TIMEOUT)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m32�[0m, in �[35mwrapped�[0m
    return _retry_thrice(func, exc, *args, **kwargs)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m28�[0m, in �[35m_retry_thrice�[0m
    raise last_exc
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/test/test_urllib2net.py"�[0m, line �[35m24�[0m, in �[35m_retry_thrice�[0m
    return func(*args, **kwargs)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m489�[0m, in �[35mopen�[0m
    response = self._open(req, data)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m506�[0m, in �[35m_open�[0m
    result = self._call_chain(self.handle_open, protocol, protocol +
                              '_open', req)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m466�[0m, in �[35m_call_chain�[0m
    result = func(*args)
  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.installed/build/target/lib/python3.16/urllib/request.py"�[0m, line �[35m1588�[0m, in �[35mftp_open�[0m
    raise URLError(f"ftp error: {exp}") from exp
�[1;35murllib.error.URLError�[0m: �[35m<urlopen error ftp error: 425 Security: Bad IP connecting.>�[0m

@orsenthil

Copy link
Copy Markdown
Member

You can take a look at the buildbot page here:
https://buildbot.python.org/#/builders/1244/builds/10167

The buildbot failures are not related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants