{"record":{"id":"7296bee69f2193cb","repo":"python/cpython","slug":"write-argument-must-be-bytes-like-not-type-b-7296be","errorCode":null,"errorMessage":"write() argument must be bytes-like, not {type(b).__name__}","messagePattern":"write\\(\\) argument must be bytes-like, not (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"warning","filePath":"Lib/_apple_support.py","lineNumber":55,"sourceCode":"\n\nclass LogStream(io.RawIOBase):\n    def __init__(self, log_write, level):\n        self.log_write = log_write\n        self.level = level\n\n    def __repr__(self):\n        return f\"<LogStream (level {self.level!r})>\"\n\n    def writable(self):\n        return True\n\n    def write(self, b):\n        if type(b) is not bytes:\n            try:\n                b = bytes(memoryview(b))\n            except TypeError:\n                raise TypeError(\n                    f\"write() argument must be bytes-like, not {type(b).__name__}\"\n                ) from None\n\n        # Writing an empty string to the stream should have no effect.\n        if b:\n            # Encode null bytes using \"modified UTF-8\" to avoid truncating the\n            # message. This should not affect the return value, as the caller\n            # may be expecting it to match the length of the input.\n            self.log_write(self.level, b.replace(b\"\\x00\", b\"\\xc0\\x80\"))\n\n        return len(b)\n","sourceCodeStart":37,"sourceCodeEnd":67,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_apple_support.py#L37-L67","documentation":"Debug-mode guard in BaseSelectorEventLoop.sock_sendall(): the loop verifies the socket is non-blocking before driving a full send, since a blocking socket could stall the loop inside send() indefinitely. With self._debug on and sock.gettimeout() != 0 the call fails immediately with ValueError.","triggerScenarios":"await loop.sock_sendall(sock, data) with asyncio debug enabled and a blocking/timeout-configured socket — including sockets obtained from getaddrinfo-plus-connect sync flows, or inherited from libraries that set timeouts for their own retry logic.","commonSituations":"Debugging a stalled sender by enabling debug mode and hitting this earlier, clearer error; mixing a sync client library's socket into loop-based sending; porting threaded senders to coroutines without flipping blocking mode.","solutions":["sock.setblocking(False) before using sock_sendall","Create and connect sockets via loop.sock_connect on a non-blocking socket end to end","Guard shared sockets with an assertion in tests: assert sock.gettimeout() == 0"],"exampleFix":"# before\nsock = socket.create_connection(addr)  # blocking\nawait loop.sock_sendall(sock, payload)  # debug: ValueError\n# after\nsock = socket.socket(); sock.setblocking(False)\nawait loop.sock_connect(sock, addr)\nawait loop.sock_sendall(sock, payload)","handlingStrategy":"validation","validationCode":"sock = socket.socket()\nsock.setblocking(False)\nawait loop.sock_connect(sock, addr)      # non-blocking end to end\nawait loop.sock_sendall(sock, payload)","typeGuard":null,"tryCatchPattern":"try:\n    await loop.sock_sendall(sock, data)\nexcept ValueError as e:\n    if 'non-blocking' in str(e):\n        sock.setblocking(False)\n        return await loop.sock_sendall(sock, data)\n    raise","preventionTips":["Never feed blocking sockets from sync factories into sock_sendall","Convert send timeouts into wait_for(sendall(...), t)","setblocking(False) at adoption boundaries with third-party sockets","Keep debug mode on in CI to surface blocking sockets early"],"tags":["asyncio","socket","debug-mode","send"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}