# Consider deprecating and eventually removing \`-b\` CLI flag

**URL:** <https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903>\
**Category:** Core Development\
**Created:** [June 27, 2025, 5:27pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903 "2025-06-27T17:27:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sobolevn](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/sobolevn/32/9274_2.png) [@sobolevn](https://discuss.python.org/u/sobolevn)\
**Post date:** [June 27, 2025, 5:27pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/1 "2025-06-27T17:27:48Z")

</div>

Recently, while working on the JIT’s constant eveluation ([gh-132732: Treat `bytes` as constants in `_Py_uop_sym_is_safe_const` by sobolevn · Pull Request #136033 · python/cpython · GitHub](https://github.com/python/cpython/pull/136033)) I realized that `-b` command line flag might not be very useful now.

What it does?

> Issue a warning when converting [`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes) or [`bytearray`](https://docs.python.org/3/library/stdtypes.html#bytearray) to [`str`](https://docs.python.org/3/library/stdtypes.html#str) without specifying encoding or comparing `bytes` or `bytearray` with `str` or `bytes` with [`int`](https://docs.python.org/3/library/functions.html#int). Issue an error when the option is given twice (`-bb`).

Docs: [1. Command line and environment — Python 3.13.5 documentation](https://docs.python.org/3/using/cmdline.html#cmdoption-b)

It was originally introduced in 2007 as a `TypeError`, while it was still Python2 era, one year before Python3 release. Original commit: [Make it an error to compare a bytes object and a Unicode object. · python/cpython@18c3ff8 · GitHub](https://github.com/python/cpython/commit/18c3ff887f95e7b566b36faf97d457372c04c213)

Then converted to a warning in [Merging the py3k-pep3137 branch back into the py3k branch. · python/cpython@98297ee · GitHub](https://github.com/python/cpython/commit/98297ee7815939b124156e438b22bd652d67b5db)

Later it was modified in 3.5 to also disallow `int` comparisions: [Issue #23681: The -b option now affects comparisons of bytes with int. · python/cpython@1dd4982 · GitHub](https://github.com/python/cpython/commit/1dd49824df49d0132b21d90c12bb596da89d7a17)

The main reason for this warning, if I understand correctly, is to help Python2 → Python3 transition. Since `bytes` and `str` had a lot of changes, it was really useful back then.

But, why now is the time to re-consider this warning?

1. Python2 is long gone, all transition tools are dropped: including `lib2to3` and many others. `-b` is also a transition tool
2. Now we have type checkers that do a better job at finding such cases, mypy:

```python
byt = b'abc'
st = 'hello'
btar = bytearray()
num = 1

byt == st # E: Non-overlapping equality check (left operand type: "bytes", right operand type: "str")
byt == num # E: Non-overlapping equality check (left operand type: "bytes", right operand type: "int")
btar == num # E: Non-overlapping equality check (left operand type: "bytearray", right operand type: "int")

```

Link: [mypy Playground](https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=5447e6b2d07cbb16adb5d52f225022e3)

Pyright:

```python
byt = b'abc'
st = 'hello'
btar = bytearray()
num = 1

byt == st # E: Condition will always evaluate to False since the types "Literal[b"abc"]" and "Literal['hello']" have no overlap (reportUnnecessaryComparison)
byt == num # E: Condition will always evaluate to False since the types "Literal[b"abc"]" and "Literal[1]" have no overlap (reportUnnecessaryComparison)
btar == num # E: Condition will always evaluate to False since the types "bytearray" and "Literal[1]" have no overlap (reportUnnecessaryComparison)

```

Link: [Pyright Playground](https://pyright-play.net/?strict=true&locale=en&code=EYTwLgBAvBwOQENgGM4CgDOkZwBYFMAbQge3WDAQCdpZx9qqEQAKASjQDsBXAW1oCMaNKGwwsECAGIIAUQBcEAMIlOAEwCWYDaogB3DcQgJCe5hgj4Abie4Iw%2BCGBIQAYiYyOMGzskdgCJxAAB3wLACIAGS18JkIAbWBwpGRwgF1w43UIKJi4%2BLwiUjgMiFwEK0dOFxJKqkIEYMkWKnxgkiowAFVOTnw-DAxqEBVeYOoNDFUOUWgYHn5pOUUVdS0dTn1DQmNTc0sbQjsHJxd3Qk8Ib19-QLAQsJzoh3yklPTMhGzcl5N4gVK5UqEGqEFqsQaTQgLTaHW6vX6YSGVBGJDGEymnBmlBoUHmfEkMgUylUmm0ugMRhMZhAFmstns-jOHi8Pj8TjuDwiogYVCYIE%2B32esT%2BAMyQKqNTqkOarXanR6fQGyNR6Kok2mwiAA)

1. It has to be special cased in the JIT
2. It has to be special cased in `subprocess.py` [cpython/Lib/subprocess.py at c419af9e277bea7dd78f4defefc752fe93b0b8ec · python/cpython · GitHub](https://github.com/python/cpython/blob/c419af9e277bea7dd78f4defefc752fe93b0b8ec/Lib/subprocess.py#L339-L345)
3. I don’t think that it is used that often, it is hard to search for `-b`, but I did the search for `sys.flags.bytes_warning`: [Code search results · GitHub](https://github.com/search?type=code&q=flags.bytes_warning+language%3APython++NOT+is%3Aarchived&l=Python)

My proposal is to deprecate `-b` CLI usage in 3.15 and remove it in 3.17  
I also propose not to touch `sys.flags.bytes_warning` and always keep it as `False`  
`sys.warnoptions` will still have `'default::BytesWarning'` string, so `warnopts.remove("error::BytesWarning")` calls will keep working.

We can also remove the C code that issues this warning in 3.17 together with `-b` removal.

What do others think? Please, share your opinions.

---

<div class="post-metadata">

**Author:** ![brandtbucher](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/brandtbucher/32/22862_2.png) [@brandtbucher](https://discuss.python.org/u/brandtbucher)\
**Post date:** [June 27, 2025, 6:06pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/2 "2025-06-27T18:06:11Z")

</div>

For more background on the JIT special-casing:

We can currently evaluate comparisons between known values in the JIT when the values have known “safe” types. So any known `int`\[1\]/`str`/`float`/`bool` value compared with any other known `int`/`str`/`float`/`bool` value is safe to evaluate at JIT-compile-time.

Adding `bytes` to this list means we need to either check that the `-b` option isn’t active when compiling and branch on that, or rework the code to check for `int`/`str` on the other side of the comparison. It’s not a super heavy lift, but it adds additional subtlety, complexity, and overhead to code that is already quite subtle, complex, and performance-sensitive.

* * *

1. …provided the `int` is “compact”. Betcha didn’t know that arbitrary code can run during operations on huge integers! 😉

---

<div class="post-metadata">

**Author:** ![malemburg](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/malemburg/32/50_2.png) [@malemburg](https://discuss.python.org/u/malemburg)\
**Post date:** [June 27, 2025, 7:13pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/3 "2025-06-27T19:13:30Z")

</div>

+1. Sounds like a good idea.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [July 7, 2025, 11:44am UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/4 "2025-07-07T11:44:01Z")

</div>

I agree that it’s time to deprecate this feature.

> [@sobolevn](#):
>
> The main reason for this warning, if I understand correctly, is to help Python2 → Python3 transition. Since `bytes` and `str` had a lot of changes, it was really useful back then.

Correct, BytesWarning is mostly useful to convert a Python 2 code base using str/unicode to Python 3 with bytes/str. Once you have a Python 3 code base using correctly bytes and str, the warning is less useful (or just useless).

---

<div class="post-metadata">

**Author:** ![hroncok](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hroncok/32/18696_2.png) [@hroncok](https://discuss.python.org/u/hroncok)\
**Post date:** [July 7, 2025, 12:39pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/5 "2025-07-07T12:39:15Z")

</div>

Please consider keeping the flag forever (doing nothing) instead of removing it entirely.

---

<div class="post-metadata">

**Author:** ![sobolevn](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/sobolevn/32/9274_2.png) [@sobolevn](https://discuss.python.org/u/sobolevn)\
**Post date:** [July 7, 2025, 3:42pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/6 "2025-07-07T15:42:43Z")

</div>

I am open to that idea. Can you please share your ideas of potential benefits?

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [July 7, 2025, 3:47pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/7 "2025-07-07T15:47:45Z")

</div>

> [@hroncok](#):
>
> Please consider keeping the flag forever (doing nothing) instead of removing it entirely.

There is a prior example: the removal of the `-t` command line option, [commit](https://github.com/python/cpython/commit/e1b5ac640841e4233bcd0204efcd50fe9b50a6d0). The option is still accepted but does nothing.

---

<div class="post-metadata">

**Author:** ![hroncok](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hroncok/32/18696_2.png) [@hroncok](https://discuss.python.org/u/hroncok)\
**Post date:** [July 15, 2025, 3:28pm UTC](https://discuss.python.org/t/consider-deprecating-and-eventually-removing-b-cli-flag/96903/8 "2025-07-15T15:28:17Z")

</div>

The obvious benefit is that if there is a script somewhere that calls Python with the -b flag, it won’t stop working. Maintaining a no-op flag has an almost zero cost, so I see no benefit in not doing that. Also, if the flag is kept, there is no way somebody will introduce a new flag with the same name in the future.

Anyway, I guess the main idea is to follow “don’t break it if you really don’t need to”.
