Skip to content

gh-110012: Fix RuntimeWarning in test_socket #110013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

sobolevn
Copy link
Member

@sobolevn sobolevn commented Sep 28, 2023

After:

Ran 483 tests in 27.474s

OK (skipped=245)

== Tests result: SUCCESS ==

1 test OK.

Total duration: 27.6 sec
Total tests: run=483 skipped=245
Total test files: run=1/1
Result: SUCCESS

I haven't checked if it also generates this warning on other platforms (different from macos sonoma), but in case it is not, I will just change quiet to True

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

You mean "malformed" and "quiet", not "mailformed" and "quite" :-)

@sobolevn
Copy link
Member Author

@AlexWaygood I am really into tpyos, thanks! :)

@AlexWaygood
Copy link
Member

Yuo're wellcom!

@@ -165,6 +166,16 @@ def socket_setdefaulttimeout(timeout):
socket.setdefaulttimeout(old_timeout)


@contextlib.contextmanager
def catch_malformed_data_warning(quiet=True):
Copy link
Member

Choose a reason for hiding this comment

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

Does it catch them or ignore them? What is the behavior of quiet=False?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes

def _filterwarnings(filters, quiet=False):
"""Catch the warnings, then check if all the expected
warnings have been raised and re-raise unexpected warnings.
If 'quiet' is True, only re-raise the unexpected warnings.
"""
# Clear the warning registry of the calling module
# in order to re-raise the warnings.
frame = sys._getframe(2)
registry = frame.f_globals.get('__warningregistry__')
if registry:
registry.clear()
with warnings.catch_warnings(record=True) as w:
# Set filter "always" to record all warnings. Because
# test_warnings swap the module, we need to look up in
# the sys.modules dictionary.
sys.modules['warnings'].simplefilter("always")
yield WarningsRecorder(w)
# Filter the recorded warnings
reraise = list(w)
missing = []
for msg, cat in filters:
seen = False
for w in reraise[:]:
warning = w.message
# Filter out the matching messages
if (re.match(msg, str(warning), re.I) and
issubclass(warning.__class__, cat)):
seen = True
reraise.remove(w)
if not seen and not quiet:
# This filter caught nothing
missing.append((msg, cat.__name__))
if reraise:
raise AssertionError("unhandled warning %s" % reraise[0])
if missing:
raise AssertionError("filter (%r, %s) did not catch any warning" %
missing[0])

  1. It catches warnings with warnings.catch_warnings(record=True)
  2. Then it filters out ones that matched ("received malformed or improperly-truncated ancillary data", RuntimeWarning)
  3. If there are any left, the test fails
  4. quiet=True handles the cases where no warning was raised - just by ignoring the last check, if quiet=False we are required to have at least one matched warning

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

Is there a correlation between a warning and the emptiness of ancdata?

@vstinner
Copy link
Member

"received malformed or improperly-truncated ancillary data" message comes from Python if get_cmsg_data_len() returns non-zero. Can you please check in which case your are?

static int 
get_cmsg_data_len(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *data_len)
{
    size_t space, cmsg_data_len;

    if (!cmsg_min_space(msg, cmsgh, CMSG_LEN(0)) ||
        cmsgh->cmsg_len < CMSG_LEN(0))
        return -1; 
    cmsg_data_len = cmsgh->cmsg_len - CMSG_LEN(0);
    if (!get_cmsg_data_space(msg, cmsgh, &space))
        return -1;
    if (space >= cmsg_data_len) {
        *data_len = cmsg_data_len;
        return 0;
    }
    *data_len = space;
    return 1;
}   

@sobolevn
Copy link
Member Author

Local debug shows that I face

printf("3");
*data_len = space;
return 1;

@sobolevn
Copy link
Member Author

Hm, I agree that this does not look like a proper fix. There's something else going on inside, for some reason there's not enough space to write the data.

@serhiy-storchaka
Copy link
Member

The code was added in 2011 (bpo-6560, #50809, 96fe56a). It does not emit a warning on Linux (at least I never see it). Were the warnings always on Windows, or did they appear in some version? Are they always expected in these tests, do they signal a problem? Shouldn't these tests fail if there was not a warning on Windows?

@sobolevn
Copy link
Member Author

We should ask @ncoghlan for help, I guess :)

@serhiy-storchaka
Copy link
Member

@sobolevn Could you test whether warnings were present in old Python versions (it was 3.2 or 3.3 I guess). Since most core developers do not use Windows, it might just slip past their notice.

@sobolevn
Copy link
Member Author

I cannot build anything below 3.7 on mac sonora (m2) :(

3.7:

~/Desktop/cpython2  0f56adb8d7 ✗                                                          
» ./python.exe -m test test_socket                         
0:00:00 load avg: 5.09 Run tests sequentially
0:00:00 load avg: 5.09 [1/1] test_socket
/Users/sobolev/Desktop/cpython2/Lib/test/test_socket.py:2323: RuntimeWarning: received malformed or improperly-truncated ancillary data
  result = sock.recvmsg(bufsize, *args)
/Users/sobolev/Desktop/cpython2/Lib/test/test_socket.py:2414: RuntimeWarning: received malformed or improperly-truncated ancillary data
  result = sock.recvmsg_into([buf], *args)

== Tests result: SUCCESS ==

1 test OK.

Total duration: 24.0 sec
Tests result: SUCCESS

3.8:

~/Desktop/cpython2  3.8 ✔                                                                 
» ./python.exe -m test test_socket                         
0:00:00 load avg: 6.11 Run tests sequentially
0:00:00 load avg: 6.11 [1/1] test_socket
/Users/sobolev/Desktop/cpython2/Lib/test/test_socket.py:2438: RuntimeWarning: received malformed or improperly-truncated ancillary data
  result = sock.recvmsg(bufsize, *args)
/Users/sobolev/Desktop/cpython2/Lib/test/test_socket.py:2529: RuntimeWarning: received malformed or improperly-truncated ancillary data
  result = sock.recvmsg_into([buf], *args)

== Tests result: SUCCESS ==

1 test OK.

Total duration: 23.2 sec
Tests result: SUCCESS

So, this is not new at least.

@vstinner
Copy link
Member

@serhiy-storchaka: @sobolevn is trying to make warnings quiet on macOS, not on Windows. I don't know if these warnings are emitted on other platforms than macOS.

@AlexWaygood
Copy link
Member

python -We -m test test_socket passes for me on Windows on a reasonably fresh build of Python 3.13, FWIW

@sobolevn
Copy link
Member Author

@vstinner they appear both on Win and Mac, see my first commit:

@vstinner
Copy link
Member

@vstinner they appear both on Win and Mac, see my first commit

Oh ok.

@hugovk
Copy link
Member

hugovk commented Jan 16, 2025

@AlexWaygood @serhiy-storchaka @vstinner Any further comments on this PR?

@serhiy-storchaka
Copy link
Member

I do not think that simply suppressing warnings here is the right solution. What is the warning about? What is the end user supposed to do with it? Non-zero result of get_cmsg_data_len() should be either an error or ignored (note that there are two non-zero returned values). If such situation is common, then perhaps the code just does not handle all cases correctly.

@graingert
Copy link
Contributor

graingert commented Jan 16, 2025

What we can do is set the warning filter to default for these warnings, add a TODO comment and not close this issue

@AlexWaygood
Copy link
Member

@AlexWaygood @serhiy-storchaka @vstinner Any further comments on this PR?

I only ever suggested some typo fixes on this one; it's well out of my area of expertise :-)

@graingert
Copy link
Contributor

What we can do is set the warning filter to default for these warnings, add a TODO comment and not close this issue

I've now done this in the warnings as errors PR

@tomasr8 tomasr8 removed the needs backport to 3.12 only security fixes label Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting review needs backport to 3.13 bugs and security fixes skip news tests Tests in the Lib/test dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants