mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Enable checking for f strings

Open nielsbuwen opened this issue 1 year ago • 3 comments

Resolves #17714 , fixes #11723

Support for f-string checking was already partially implemented. Consider this code:

f"{123:abc}"
"{:abc}".format(123)

Mypy ran these lines through the format checker. The call expressions look like this:

# f-string
CallExpr:1(
  MemberExpr:1(
    StrExpr({:{}})
    format)
  Args(
    IntExpr(123)
    StrExpr(abc)))

# format
CallExpr:2(
  MemberExpr:2(
    StrExpr({:abc})
    format)
  Args(
    IntExpr(123)))

The difference is, that the actually static "abc" is converted to a "dynamic" spec.

This MR attempts to enable type checking of f-strings by inlining these "semi dynamic" specs.

Open Questions:

  • is this a good idea? Or should the actual parsing of f-strings be changed?
  • the test i added always passes on my machine: pytest mypy/test/testcheck.py::TypeCheckSuite::check-string-format.test. It never finds any errors even when it should clearly fail

Checklist

  • [x] Read the Contributing Guidelines
  • [x] Add tests for all changed behavior
  • [x] Make sure CI passes
  • [ ] Do not force push to PR once reviewed

nielsbuwen avatar Sep 03 '24 10:09 nielsbuwen

Diff from mypy_primer, showing the effect of this PR on open source code:

websockets (https://github.com/aaugustin/websockets)
+ src/websockets/sync/messages.py:102: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

pydantic (https://github.com/pydantic/pydantic)
+ pydantic/types.py:1509: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

CPython (Argument Clinic) (https://github.com/python/cpython)
+ Tools/clinic/libclinic/converters.py:83: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/io/sas/sas7bdat.py:721: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ pandas/tests/scalar/test_na_scalar.py:38: error: Unrecognized format specification "xxx"  [str-format]

aioredis (https://github.com/aio-libs/aioredis)
+ aioredis/connection.py:406: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

itsdangerous (https://github.com/pallets/itsdangerous)
+ src/itsdangerous/signer.py:249: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ src/itsdangerous/signer.py:256: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

urllib3 (https://github.com/urllib3/urllib3)
+ src/urllib3/exceptions.py:316: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ test/contrib/test_socks.py:94: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

pwndbg (https://github.com/pwndbg/pwndbg)
+ pwndbg/gdblib/symbol.py: note: In function "get":
+ pwndbg/gdblib/symbol.py:100: error: Incompatible types in string interpolation (expression has type "Value", placeholder has type "int")  [str-format]
+ pwndbg/gdblib/onegadget.py: note: In function "check_stack_argv":
+ pwndbg/gdblib/onegadget.py:362: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ pwndbg/gdblib/onegadget.py: note: In function "check_non_stack_argv":
+ pwndbg/gdblib/onegadget.py:403: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

bokeh (https://github.com/bokeh/bokeh)
+ src/bokeh/util/token.py: note: In function "_reseed_if_needed":
+ src/bokeh/util/token.py:284:50: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

packaging (https://github.com/pypa/packaging)
+ src/packaging/_elffile.py:55: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

scrapy (https://github.com/scrapy/scrapy)
+ scrapy/core/http2/protocol.py:60: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

mongo-python-driver (https://github.com/mongodb/mongo-python-driver)
+ bson/regex.py:118: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ bson/raw_bson.py:175: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

xarray (https://github.com/pydata/xarray)
+ xarray/backends/api.py: note: In function "_validate_attrs":
+ xarray/backends/api.py:210: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ xarray/backends/api.py:217: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ xarray/backends/api.py: note: At top level:

freqtrade (https://github.com/freqtrade/freqtrade)
+ freqtrade/persistence/trade_model.py:852: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:399: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:421: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:446: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/strategy/interface.py:1511: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

core (https://github.com/home-assistant/core)
+ homeassistant/components/mqtt/binary_sensor.py:208: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

trio (https://github.com/python-trio/trio)
+ src/trio/_subprocess.py:204: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ src/trio/_tests/test_threads.py:274: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ src/trio/_tests/test_dtls.py:79: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

bandersnatch (https://github.com/pypa/bandersnatch)
+ src/bandersnatch_storage_plugins/filesystem.py: note: In member "get_hash" of class "FilesystemStorage":
+ src/bandersnatch_storage_plugins/filesystem.py:271: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

steam.py (https://github.com/Gobot1234/steam.py)
+ steam/utils.py:437: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ steam/media.py:67: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ steam/manifest.py:84: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/http_exceptions.py:88:49: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ aiohttp/http_exceptions.py:88:49: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-str-bytes-safe for more info
+ aiohttp/multipart.py:736:69: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ aiohttp/multipart.py:765:49: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ aiohttp/connector.py:1164:32: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int")  [str-format]
+ aiohttp/connector.py:1164:32: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-str-format for more info
+ aiohttp/web_response.py:657:59: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/feature_benchmark/comparator.py:56: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]
+ misc/python/materialize/feature_benchmark/comparator.py:65: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]

python-chess (https://github.com/niklasf/python-chess)
+ chess/polyglot.py:336: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

ignite (https://github.com/pytorch/ignite)
+ ignite/utils.py:134: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]
+ ignite/utils.py:165: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]

mitmproxy (https://github.com/mitmproxy/mitmproxy)
+ mitmproxy/io/tnetstring.py:239: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ release/release.py:33: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ release/build.py:151: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ release/build.py:224: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/net/http/http1/read.py:61: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/net/http/http1/read.py:220: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/net/http/http1/read.py:251: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/net/http/http1/read.py:266: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/net/http/http1/read.py:297: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ examples/addons/websocket-simple.py:16: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ examples/addons/websocket-simple.py:18: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/commands.py:82: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/addons/modifyheaders.py:44: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/events.py:55: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/websocket.py:199: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/modes.py:161: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/modes.py:245: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/http/_http1.py:320: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/http/_http1.py:398: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/http/_http1.py:439: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/tls.py:42: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/tls.py:105: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/tls.py:255: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/quic.py:141: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/quic.py:193: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/http/_upstream_proxy.py:99: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ mitmproxy/proxy/layers/http/_http2.py:614: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

anyio (https://github.com/agronholm/anyio)
+ src/anyio/_backends/_asyncio.py:1320: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ src/anyio/to_process.py:68: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ src/anyio/to_process.py:155: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

dulwich (https://github.com/dulwich/dulwich)
+ dulwich/objects.py:848: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/objects.py:959: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:206: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:495: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:499: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:503: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:543: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/config.py:551: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/refs.py:1206: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/object_store.py:683: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/repo.py:1072: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/repo.py:1407: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/index.py:309: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/index.py:332: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/index.py:436: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/server.py:258: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/server.py:263: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/server.py:271: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/ignore.py:180: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/client.py:492: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ dulwich/client.py:497: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

poetry (https://github.com/python-poetry/poetry)
+ src/poetry/publishing/uploader.py:37: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]
+ tests/publishing/test_uploader.py:65: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

manticore (https://github.com/trailofbits/manticore)
+ manticore/platforms/linux.py:579: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

jax (https://github.com/google/jax)
+ jax/_src/internal_test_util/export_back_compat_test_util.py:232: error: If x = b'abc' then f"{x}" or "{}".format(x) produces "b'abc'", not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). Otherwise, decode the bytes  [str-bytes-safe]

github-actions[bot] avatar Sep 03 '24 11:09 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

websockets (https://github.com/aaugustin/websockets)
+ src/websockets/sync/messages.py:102: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/tests/scalar/test_na_scalar.py:38: error: Unrecognized format specification "xxx"  [str-format]

pwndbg (https://github.com/pwndbg/pwndbg)
+ pwndbg/gdblib/symbol.py: note: In function "get":
+ pwndbg/gdblib/symbol.py:100: error: Incompatible types in string interpolation (expression has type "Value", placeholder has type "int")  [str-format]

freqtrade (https://github.com/freqtrade/freqtrade)
+ freqtrade/persistence/trade_model.py:852: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:399: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:421: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:446: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/strategy/interface.py:1511: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/connector.py:1164:32: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int")  [str-format]
+ aiohttp/connector.py:1164:32: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-str-format for more info

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/feature_benchmark/comparator.py:56: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]
+ misc/python/materialize/feature_benchmark/comparator.py:65: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]

ignite (https://github.com/pytorch/ignite)
+ ignite/utils.py:134: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]
+ ignite/utils.py:165: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]

github-actions[bot] avatar Sep 03 '24 11:09 github-actions[bot]

Diff from mypy_primer, showing the effect of this PR on open source code:

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/connector.py:1344:36: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int")  [str-format]
+ aiohttp/connector.py:1344:36: note: See https://mypy.rtfd.io/en/stable/_refs.html#code-str-format for more info

colour (https://github.com/colour-science/colour)
+ colour/plotting/phenomena.py:328: error: Incompatible types in string interpolation (expression has type "ndarray[tuple[Any, ...], dtype[floating[_16Bit] | floating[_32Bit] | float64]]", placeholder has type "int | float")  [str-format]
+ colour/plotting/phenomena.py:656: error: Incompatible types in string interpolation (expression has type "Buffer", placeholder has type "int | float")  [str-format]
+ colour/plotting/phenomena.py:656: error: Incompatible types in string interpolation (expression has type "_SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]", placeholder has type "int | float")  [str-format]

async-utils (https://github.com/mikeshardmind/async-utils)
+ src/async_utils/lockout.py:78: error: Unrecognized format specification "!r"  [str-format]
+ src/async_utils/lockout.py:151: error: Unrecognized format specification "!r"  [str-format]

core (https://github.com/home-assistant/core)
+ homeassistant/components/stiebel_eltron/climate.py:146: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/tests/scalar/test_na_scalar.py:38: error: Unrecognized format specification "xxx"  [str-format]

dulwich (https://github.com/dulwich/dulwich)
+ dulwich/patch.py:479: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int")  [str-format]

websockets (https://github.com/aaugustin/websockets)
+ src/websockets/sync/messages.py:89: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/feature_benchmark/benchmark_result.py:93: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]
+ misc/python/materialize/feature_benchmark/benchmark_result.py:102: error: Incompatible types in string interpolation (expression has type "T", placeholder has type "int | float")  [str-format]

freqtrade (https://github.com/freqtrade/freqtrade)
+ freqtrade/persistence/trade_model.py:878: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:438: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/rpc/telegram.py:460: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]
+ freqtrade/strategy/interface.py:1638: error: Incompatible types in string interpolation (expression has type "None", placeholder has type "int | float")  [str-format]

ignite (https://github.com/pytorch/ignite)
+ ignite/utils.py:134: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]
+ ignite/utils.py:165: error: Incompatible types in string interpolation (expression has type "Number", placeholder has type "int | float")  [str-format]

github-actions[bot] avatar Nov 29 '25 01:11 github-actions[bot]