Skip to content
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

warnings.warn's skip_file_prefixes doesn't work when provided __file__. #126209

Open
nairb774 opened this issue Oct 30, 2024 · 0 comments
Open

warnings.warn's skip_file_prefixes doesn't work when provided __file__. #126209

nairb774 opened this issue Oct 30, 2024 · 0 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@nairb774
Copy link

nairb774 commented Oct 30, 2024

Bug report

Bug description:

I was attempting to make warning.warn skip all frames in the calling file by setting skip_file_prefixes=(__file__,). Frustratingly it wasn't working as expected and was blaming an intermediate frame in the file I was trying to skip. Looking at Lib/warnings.py I was confused as to why it wasn't working. After some digging I discovered there is a parallel C implementation in Python/_warnings.c.

The following script demonstrates the difference between the two implementations:

import sys
# Uncomment to compare the C and Py implementation of warnings.warn.
# sys.modules["_warnings"] = None
import warnings

# Desired input which works as expected with the Py impl, but not the C impl.
skip_file_prefixes=(__file__,)

# Hack to make the C implementation match the Py behavior:
# skip_file_prefixes=(__file__[:-1],)  

def ccc():
    warnings.warn("Hello", UserWarning, skip_file_prefixes=skip_file_prefixes)

def bbb():
    ccc()

def aaa():
    bbb()

aaa()

Broken C implementation:

$ python sample.py 
/tmp/sample.py:12: UserWarning: Hello
  ccc()

Correct Python implementation:

$ python sample.py 
sys:1: UserWarning: Hello

There is a slight implementation difference between Python/_warnings.c:is_filename_to_skip and Lib/warnings.py:_is_filename_to_skip. The Python implementation is uses filename.startswith(prefix) 1 while the C implementation uses PyUnicode_Tailmatch(filename, prefix, 0, -1, -1) 2. It looks like the C implementation should be something like PyUnicode_Tailmatch(filename, prefix, 0, PY_SSIZE_T_MAX, -1).

$ python --version
Python 3.12.7

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Footnotes

  1. https://github.com/python/cpython/blob/679dfaeb4c78a138441a2073530be105c6752766/Lib/warnings.py#L280

  2. https://github.com/python/cpython/blob/3ef8a3a9004ff7ed2bf6f2f67f13ff5b37c42204/Python/_warnings.c#L809

@nairb774 nairb774 added the type-bug An unexpected behavior, bug, or error label Oct 30, 2024
@picnixz picnixz added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants