{"action":"opened","issue":{"url":"https://api.github.com/repos/biopython/biopython/issues/874","repository_url":"https://api.github.com/repos/biopython/biopython","labels_url":"https://api.github.com/repos/biopython/biopython/issues/874/labels{/name}","comments_url":"https://api.github.com/repos/biopython/biopython/issues/874/comments","events_url":"https://api.github.com/repos/biopython/biopython/issues/874/events","html_url":"https://github.com/biopython/biopython/issues/874","id":166097891,"number":874,"title":"Check handle mode in Bio.SeqIO etc?","user":{"login":"peterjc","id":63959,"avatar_url":"https://avatars.githubusercontent.com/u/63959?v=3","gravatar_id":"","url":"https://api.github.com/users/peterjc","html_url":"https://github.com/peterjc","followers_url":"https://api.github.com/users/peterjc/followers","following_url":"https://api.github.com/users/peterjc/following{/other_user}","gists_url":"https://api.github.com/users/peterjc/gists{/gist_id}","starred_url":"https://api.github.com/users/peterjc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peterjc/subscriptions","organizations_url":"https://api.github.com/users/peterjc/orgs","repos_url":"https://api.github.com/users/peterjc/repos","events_url":"https://api.github.com/users/peterjc/events{/privacy}","received_events_url":"https://api.github.com/users/peterjc/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-07-18T13:50:10Z","updated_at":"2016-07-18T13:50:10Z","closed_at":null,"body":"In regards to #872 some sanity testing for the mode of handles passed to ``Bio.SeqIO.parse()`` etc might be sensible to give meaningful error messages when (accidentally) passing a binary handle to a parser expected a text handle.\r\n\r\nRight now we get a range of errors, e.g.\r\n* ``ValueError: Is this handle in binary mode not text mode?`` for ``fastq``\r\n* ``TypeError: a bytes-like object is required, not 'str'`` for ``tab``\r\n* ``TypeError: startswith first arg must be bytes or a tuple of bytes, not str`` for ``phd``, ``ig`` and ``ace``\r\n* ``IndexError: index out of range`` for ``qual`` and ``pir`` and ``fasta``\r\n* Zero records but no error for ``embl``, ``genbank``\r\n\r\nLikewise the reverse can happen when giving a text handle to a parser expecting binary, e.g.\r\n\r\n* ``ValueError: ABI files has to be opened in 'rb' mode.`` for ``abi``\r\n* ``UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 15: invalid start byte`` for ``sff`` when given a text handle\r\n\r\nSomething like this ought to have the desired effect (although I think the error messages need better wording:\r\n\r\n```\r\n--- a/Bio/File.py\r\n+++ b/Bio/File.py\r\n@@ -57,7 +57,8 @@ def as_handle(handleish, mode='r', **kwargs):\r\n     All other inputs are returned, and are *not* closed\r\n \r\n         - handleish  - Either a string or file handle\r\n-        - mode       - Mode to open handleish (used only if handleish is a string)\r\n+        - mode       - Mode to open handleish (used if handleish is a string,\r\n+                       if handleish is a handle checks compatible)\r\n         - kwargs     - Further arguments to pass to open(...)\r\n \r\n     Example:\r\n@@ -87,7 +88,22 @@ def as_handle(handleish, mode='r', **kwargs):\r\n         else:\r\n             with open(handleish, mode, **kwargs) as fp:\r\n                 yield fp\r\n+    elif hasattr(handleish, \"mode\"):\r\n+        if \"b\" in mode and \"b\" not in handleish.mode:\r\n+            raise ValueError(\"Binary mode requested (%r), \"\r\n+                             \"but given handle mode %r\" %\r\n+                             (mode, handleish.mode))\r\n+        if \"b\" not in mode and \"b\" in handleish.mode:\r\n+            raise ValueError(\"Text mode requested (%r), \"\r\n+                             \"but given handle binary mode %r\" %\r\n+                             (mode, handleish.mode))\r\n+        yield handleish\r\n     else:\r\n+        # It is already handle like, but is the mode OK?\r\n+        try:\r\n+            existing_mode = handleish.mode\r\n+        except AttributeError:\r\n+            existing_mode = mode\r\n         yield handleish\r\n \r\n```\r\n\r\nTODO: Test this doesn't break anything, and add some test to verify this works as intended."}}
{"actor":{"display_login":"peterjc"}}