{"html_url": "https://github.com/simonw/sqlite-utils/issues/448#issuecomment-1297703307", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/448", "id": 1297703307, "node_id": "IC_kwDOCGYnMM5NWWGL", "user": {"value": 167893, "label": "mcarpenter"}, "created_at": "2022-10-31T21:23:51Z", "updated_at": "2022-10-31T21:27:32Z", "author_association": "CONTRIBUTOR", "body": "The Windows aspect is a red herring: OP's sample above produces the same error on Linux. (Though I don't know what's going on with the CI).\r\n\r\nThe same error can also be obtained by passing an `io` from a file opened in non-binary mode (`'r'` as opposed to `'rb'`) to `rows_from_file()`. This is how I got here.\r\n\r\nThe fix for my case is easy: open the file in mode `'rb'`. The analagous fix for OP's problem also works: use `BytesIO` in place of `StringIO`.\r\n\r\nMinimal test case (derived from [utils.py](https://github.com/simonw/sqlite-utils/blob/main/sqlite_utils/utils.py#L304)):\r\n\r\n``` python\r\nimport io\r\nfrom typing import cast\r\n\r\n#fp = io.StringIO(\"id,name\\n1,Cleo\") # error\r\nfp = io.BytesIO(bytes(\"id,name\\n1,Cleo\", encoding='utf-8')) # okay\r\nreader = io.BufferedReader(cast(io.RawIOBase, fp))\r\nreader.peek(1) # exception thrown here\r\n```\r\nI see the signature of `rows_from_file()` correctly has `fp: BinaryIO` but I guess you'd need either a runtime type check for that (not all `io`s have `mode()`), or to catch the `AttributeError` on `peek()` to produce a better error for users. Neither option is ideal.\r\n\r\nSome thoughts on testing binary-ness of `io`s in this SO question: https://stackoverflow.com/questions/44584829/how-to-determine-if-file-is-opened-in-binary-or-text-mode", "reactions": "{\"total_count\": 2, \"+1\": 2, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1279144769, "label": "Reading rows from a file => AttributeError: '_io.StringIO' object has no attribute 'readinto'"}, "performed_via_github_app": null}