Introduce stacklevel-aware custom warnings#6293
Conversation
61b87be to
bbfc1b1
Compare
|
@kAIto47802 Could you review this PR? |
There was a problem hiding this comment.
Thank you for the PR! I left some comments. PTRL ![]()
Also, the stack level is currently specified in the decorators to point to the user code, which I think is no longer necessary with this PR. Therefore, how about removing these specifications?
In the current implementation, the stack level has increased by one, so it no longer points to the user code but instead points inside the Optuna internal decorator. If we don’t remove these specifications, we need to increase their stack level by one.
These specifications can be found in the following files:
- optuna/_convert_positional_args.py
- optuna/_deprecated.py
- optuna/_experimental.py
|
Also, the change to |
|
This pull request has not seen any recent activity. |
|
I changed the name of the wrapper function of |
1c97423 to
353fcab
Compare
a86f4d2 to
97d22c0
Compare
There was a problem hiding this comment.
Thank you for the update.
I confirmed that it behaves as intended for both Python 3.12 and earlier versions, and for both the decorator and non-decorator cases.
I also confirmed that there are no remaining instances of code that should have been updated to use optuna_warn.
One minor concern is that for Python < 3.12, the user message displays optuna_warn( instead of warnings.warn(, which might be surprising for users who are accustomed to seeing warnings.warn( in standard warning messages.
However, since no information is lost compared to the original behavior, and this issue will disappear once support for versions earlier than 3.12 is dropped, it’s acceptable.
Therefore, it LGTM!
Motivation
For better user experience, warnings should point to the user’s code, not Optuna’s internal code.
For example, with the following code in the current master branch, the warning points to non-user code. In such cases, it is difficult for users to identify the actual source in their own code.
output
As discussed in #6227,
warnings.warnaccepts a second argument stacklevel, which allows skipping a certain number of frames in the stack. However, passing the correct stack level everywhere is difficult, since different call paths may require different values.To address this, I implemented a wrapper that determines the stack level based on the module path. This wrapper calculates the appropriate stack level relative to the user’s code and passes it to
warnings.warn.Starting from Python 3.12,
warnings.warnprovides theskip_file_prefixesargument, which can skip stack frames belonging to files with specific prefixes. However, this argument is not available in versions earlier than 3.12. Therefore, I implemented a custom wrapper inspired by theskip_file_prefixesmechanism.Description of the changes
_warnings.py.import warningstofrom optuna import _warnings as warnings.