{"record":{"id":"6d87c31a67ab1ed2","repo":"python/cpython","slug":"write-argument-must-be-str-not-type-s-name","errorCode":null,"errorMessage":"write() argument must be str, not {type(s).__name__}","messagePattern":"write\\(\\) argument must be str, not (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"warning","filePath":"Lib/_android_support.py","lineNumber":61,"sourceCode":"            fileno = None\n\n        # The default is surrogateescape for stdout and backslashreplace for\n        # stderr, but in the context of an Android log, readability is more\n        # important than reversibility.\n        kwargs.setdefault(\"encoding\", \"UTF-8\")\n        kwargs.setdefault(\"errors\", \"backslashreplace\")\n\n        super().__init__(BinaryLogStream(prio, tag, fileno), **kwargs)\n        self._lock = RLock()\n        self._pending_bytes = []\n        self._pending_bytes_count = 0\n\n    def __repr__(self):\n        return f\"<TextLogStream {self.buffer.tag!r}>\"\n\n    def write(self, s):\n        if not isinstance(s, str):\n            raise TypeError(\n                f\"write() argument must be str, not {type(s).__name__}\")\n\n        # In case `s` is a str subclass that writes itself to stdout or stderr\n        # when we call its methods, convert it to an actual str.\n        s = str.__str__(s)\n\n        # We want to emit one log message per line wherever possible, so split\n        # the string into lines first. Note that \"\".splitlines() == [], so\n        # nothing will be logged for an empty string.\n        with self._lock:\n            for line in s.splitlines(keepends=True):\n                while line:\n                    chunk = line[:MAX_CHARS_PER_WRITE]\n                    line = line[MAX_CHARS_PER_WRITE:]\n                    self._write_chunk(chunk)\n\n        return len(s)\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_android_support.py#L43-L79","documentation":"Debug-mode guard in BaseSelectorEventLoop.sock_recv_into(): before scheduling an asynchronous read into a caller-provided buffer, the loop asserts the socket is non-blocking. A blocking socket would make the eventual recv_into call stall the entire event loop, so debug mode converts the latent hang into an immediate ValueError.","triggerScenarios":"await loop.sock_recv_into(sock, buf) with loop debug enabled and sock.gettimeout() != 0 — i.e. blocking default sockets or those configured with settimeout(n). Common when reusing sockets established by synchronous helper APIs.","commonSituations":"High-throughput readers migrated from blocking recv_into code that never set non-blocking mode; benchmarking under debug builds; socket pools created by sync connection factories feeding into async consumers.","solutions":["Call sock.setblocking(False) on every socket handed to sock_recv_into","Create sockets inside async code with blocking off from the start","Audit shared connection pools so all consumers agree on blocking mode; add an assertion sock.gettimeout() == 0 in test doubles"],"exampleFix":"# before\nsock.settimeout(5)\nawait loop.sock_recv_into(sock, buf)  # debug: ValueError\n# after\nsock.setblocking(False)\nawait loop.sock_recv_into(sock, buf)","handlingStrategy":"validation","validationCode":"def nb(sock):\n    if sock.gettimeout() != 0:\n        sock.setblocking(False)\n    return sock\n\nn = await loop.sock_recv_into(nb(sock), buf)","typeGuard":null,"tryCatchPattern":"try:\n    await loop.sock_recv_into(sock, buf)\nexcept ValueError as e:\n    if 'non-blocking' in str(e):\n        sock.setblocking(False)\n        return await loop.sock_recv_into(sock, buf)\n    raise","preventionTips":["Flip blocking off before the first await on a socket","Audit migrated recv_into code paths for leftover timeouts","Use wait_for() to bound receive durations","Keep a single factory for loop-ready sockets"],"tags":["asyncio","socket","debug-mode","non-blocking","buffer"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}