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
Programmatic management of BytesWarning doesn't work for native triggers. #87692
Comments
When setting import warnings
warnings.simplefilter('default', category=BytesWarning)
str(b'')
warnings.warn('test', category=BytesWarning) If run using
There is no warning for the string-ification of the bytes instance. If run using
Inspecting
(in Python 3.9). The warning module's own suggestion: import sys
if not sys.warnoptions:
import warnings
warnings.simplefilter("default") # Change the filter in this process also fails to enable BytesWarning. If this is intended behaviour, which seems to be the case according to ncoghlan's comment https://bugs.python.org/issue32230#msg307721, it should be clearly documented, as it's rather frustrating. |
Addendum: is there a way to force |
Yes, it is intended behaviour. BytesWarning is only emitted when you set a special internal flag (by the -b option). Warning filters control what happen with that warning later: be it ignored, printed, or converted to exception. In normal circumstances you should never deal with BytesWarning. The -b option is only used for testing your program for some possible bugs caused by migration from Python 2. If your program always worked only with Python 3, the -b option has no use for you. It may be more complicated if you write a library which support bytes and strings. Since you do not know in what program it will be used, it may be nice to to test it with mixed bytes and str data and ensure that it works with bytes warnings enabled. |
That's technically true for perfect programs, but practically if the program is not tested enough it's possible for it to contain unexpected instances of stringifying bytes which pass by mostly unnoticed, just with garbage bits of output which may or may not get reported. Noticing such cases in an existing codebase is exactly what prompted me to try and enable BytesWarning (and then try and filter them to just conversion warnings, as the category is quite noisy with somewhat uninteresting warnings), and then spend a while trying to understand why programmatically enabling BytesWarning didn't do anything. As noted in the last paragraph it's fine if |
Serhiy an other question (because I've encountered it *again*), do you think it'd be possible to split out the specific warning of stringifying (but *not* explicitely repr-ing) a bytes instance from everything else? There are use-cases for it, but I think it's rather error prone when a |
I am not against documenting the behavior of -b and BytesWarning clearly. I don't think that anyone would be against. Just somebody have to provide a PR. Explicitly repr-ing a bytes instance does not produce a warning, and never produced, so I don't understand what do you mean. |
Right but what about the ability to enable warning on stringification without enabling the warning on comparison? There are packages / situations where comparing strings and bytes makes a lot of sense (e.g. use string and byte versions of data as keys in the same dict), but I think stringifying bytes rarely if ever does.
Well that's absolutely ideal as I did not check if it did, just wanted to be clear that I wasn't looking for a warning in that case. |
And though I did not check, I expect the I recall Inada-san tends to be quite involved in BytesWarning, is adding people to the nosy list something that's done or is it in bad taste? |
If working Python 3 program suddenly became emitting BytesWarning it will confuse users. Finally we will get rid of the -b option and BytesWarning. str() for bytes object will be equal to repr(), without warnings and errors. If you want to change it, use -b. Maybe introducing PYTHONBYTESWARNING will help. But I do not think we should change the behavior for these who do not ask for it specially if it will differ from the future behavior.
I think it would work. But it is significant amount of work (add corresponding C API, parsing and copying code, documentation, tests), and for small benefit. Would not be better to filter out warnings by message? I think that adding PYTHONBYTESWARNING can help you. |
Oh yeah no I meant making it a normal warning, without needing the Because controlling / configuring warnings can be done programmatically and dynamically from inside the program, but in my understanding -b is either set or unset when calling it, if you're not setting it you're SOL. Or so I understand, I didn't find any switch accessible from inside the Python program.
Wouldn't it just be removing the check on
Well yes and no, my issue remains the one from the beginning: it's quite easy to unexpectedly stringify bytes, which usually isn't what's desired. Ensuring that doesn't happen requires making sure every developer and environment (non-production at least) does run python with -b to enable the warning, which is not as easy as the software being able to set that internally (which is doable for various deprecation warnings and friends). |
fwiw, at work we modified our interpreter to treat PYTHONBYTESWARNING=1 or 2 as if -b or -bb were passed. All of our tests run by default with a PYTHONBYTESWARNING=2 in their environment. |
clarification after poking around: s/all/a lot/ - YouTube used it to help their Python 3 migration. Regardless, the env. var has been useful. |
While you should not do that at home ;-), it's now *technically* possible to change the BytesWarning flag at runtime using a a *private* *internal* API: $ ./python
Python 3.11.0a2+ (heads/remove_asyncore:010015d2eb, Nov 11 2021, >>> "unicode" == b"bytes"
False
# Change the internal BytesWarning flag
>>> import _testinternalcapi
>>> config=_testinternalcapi.get_config()
>>> config['bytes_warning']=1
>>> _testinternalcapi.set_config(config)
>>> "unicode" == b"bytes"
<stdin>:1: BytesWarning: Comparison between bytes and string
False |
The -b command line documentation is not explicitly enough? "Issue a warning when comparing bytes or bytearray with str or bytes with int. Issue an error when the option is given twice (-bb)." https://docs.python.org/dev/using/cmdline.html#cmdoption-b Modifying warning filters don't change how Python emits or not warnings. It only changes how emitted warnings are handlded: ignored, displayed, treated as errors. The relationship between -b and BytesWarning is different than other warnings. Should we add a note near the BytesWarning documentation? |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: