-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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" :-)
@AlexWaygood I am really into tpyos, thanks! :) |
Yuo're wellcom! |
@@ -165,6 +166,16 @@ def socket_setdefaulttimeout(timeout): | |||
socket.setdefaulttimeout(old_timeout) | |||
|
|||
|
|||
@contextlib.contextmanager | |||
def catch_malformed_data_warning(quiet=True): |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
cpython/Lib/test/support/warnings_helper.py
Lines 152 to 188 in 8f324b7
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]) |
- It catches warnings with
warnings.catch_warnings(record=True)
- Then it filters out ones that matched
("received malformed or improperly-truncated ancillary data", RuntimeWarning)
- If there are any left, the test fails
quiet=True
handles the cases where no warning was raised - just by ignoring the last check, ifquiet=False
we are required to have at least one matched warning
There was a problem hiding this 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
?
"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;
} |
Local debug shows that I face printf("3");
*data_len = space;
return 1; |
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. |
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? |
We should ask @ncoghlan for help, I guess :) |
@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. |
I cannot build anything below 3.7 on mac sonora (m2) :( 3.7:
3.8:
So, this is not new at least. |
@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. |
|
@vstinner they appear both on Win and Mac, see my first commit: |
Oh ok. |
@AlexWaygood @serhiy-storchaka @vstinner Any further comments on this PR? |
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 |
What we can do is set the warning filter to default for these warnings, add a TODO comment and not close this issue |
I only ever suggested some typo fixes on this one; it's well out of my area of expertise :-) |
I've now done this in the warnings as errors PR |
After:
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
toTrue
test_socket
generates several warnings #110012