{"action":"created","comment":{"url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/comments/34529933","id":34529933,"diff_hunk":"@@ -70,10 +70,22 @@ def open_file(dods, das=None):\n     dataset.\n \n     \"\"\"\n+    dds = ''\n+    # This file contains both ascii _and_ binary data\n+    # Let's handle them separately in sequence\n+    # Without ignoring errors, the IO library will actually read past the ascii part of the\n+    # file (despite our break from iteration) and will error out on the binary data\n+    with open(dods, \"rt\", buffering=1, encoding='ascii', newline='\\n', errors='ignore') as f:\n+        for line in f:\n+            if line.strip() == 'Data:':\n+                break\n+            dds += line\n+    dataset = build_dataset(dds)\n+    pos = len(dds) + len('Data:\\n')\n+\n     with open(dods, \"rb\") as f:\n-        dds, data = f.read().split(b'\\nData:\\n', 1)","path":"src/pydap/client.py","position":43,"original_position":43,"commit_id":"4b9c0f5b642f7103d5679c7fa7209ee6617b1ef4","original_commit_id":"4b9c0f5b642f7103d5679c7fa7209ee6617b1ef4","user":{"login":"QuLogic","id":302469,"avatar_url":"https://avatars.githubusercontent.com/u/302469?v=3","gravatar_id":"","url":"https://api.github.com/users/QuLogic","html_url":"https://github.com/QuLogic","followers_url":"https://api.github.com/users/QuLogic/followers","following_url":"https://api.github.com/users/QuLogic/following{/other_user}","gists_url":"https://api.github.com/users/QuLogic/gists{/gist_id}","starred_url":"https://api.github.com/users/QuLogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/QuLogic/subscriptions","organizations_url":"https://api.github.com/users/QuLogic/orgs","repos_url":"https://api.github.com/users/QuLogic/repos","events_url":"https://api.github.com/users/QuLogic/events{/privacy}","received_events_url":"https://api.github.com/users/QuLogic/received_events","type":"User","site_admin":false},"body":"Why doesn't this work?","created_at":"2015-07-14T01:20:08Z","updated_at":"2015-07-14T01:20:08Z","html_url":"https://github.com/robertodealmeida/pydap/pull/9#discussion_r34529933","pull_request_url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9","_links":{"self":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/comments/34529933"},"html":{"href":"https://github.com/robertodealmeida/pydap/pull/9#discussion_r34529933"},"pull_request":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9"}}},"pull_request":{"url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9","id":16249555,"html_url":"https://github.com/robertodealmeida/pydap/pull/9","diff_url":"https://github.com/robertodealmeida/pydap/pull/9.diff","patch_url":"https://github.com/robertodealmeida/pydap/pull/9.patch","issue_url":"https://api.github.com/repos/robertodealmeida/pydap/issues/9","number":9,"state":"open","locked":false,"title":"Addition of Python 3.3 to supported versions","user":{"login":"jameshiebert","id":3904316,"avatar_url":"https://avatars.githubusercontent.com/u/3904316?v=3","gravatar_id":"","url":"https://api.github.com/users/jameshiebert","html_url":"https://github.com/jameshiebert","followers_url":"https://api.github.com/users/jameshiebert/followers","following_url":"https://api.github.com/users/jameshiebert/following{/other_user}","gists_url":"https://api.github.com/users/jameshiebert/gists{/gist_id}","starred_url":"https://api.github.com/users/jameshiebert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jameshiebert/subscriptions","organizations_url":"https://api.github.com/users/jameshiebert/orgs","repos_url":"https://api.github.com/users/jameshiebert/repos","events_url":"https://api.github.com/users/jameshiebert/events{/privacy}","received_events_url":"https://api.github.com/users/jameshiebert/received_events","type":"User","site_admin":false},"body":"### Summary\r\n\r\nThis PR ports the remainder of the Pydap code to run on Python version 2.6, 2.7 and 3.3. It closes #7 and fixes #8.\r\n\r\nMuch of this exercise was straightforward, but there were a few points issues on which feedback from others would be valued.\r\n\r\n### OPeNDAP, Python3, bytes, Unicode and ASCII\r\n\r\nIn Python 3, [one needs to be very specific](http://www.slideshare.net/dabeaz/mastering-python-3-io-version-2) about whether one is using raw bytes vs. text in encoded with unicode vs. text encoded with some other encoding, etc. These are different base types in different Python versions, so I've used the `six` module's `text_type` where appropriate.\r\n\r\nThe problems is that a careful reading of the [DAP 2.0 spec](http://www.opendap.org/pdf/ESE-RFC-004v1.1.pdf) provides little clarity about what the text encoding of a DAP response is *supposed* to be. Actually, section 3.2.3 does specify that the String Type is limited to 7-bin ASCII characters and section 5 places further restrictions on the character sets of variable names.\r\n\r\nBecause of this, I have changed numerous places in the code--particularly in the DAS and DDS handlers/responses--setting the output encoding to ASCII rather than UTF-8. I don't actually like this... it's limiting the internationalization support and also a wide variety of scientific symbols that would be used in DAP attributes. However, it's true to the DAP spec by my reading. Feedback on this is welcome.\r\n\r\n### Conflicting HTTP Request Frameworks\r\n\r\nMost of the Pydap client/server code uses `webob`'s `Request` and `Response` objects. However, most (all?) of the testing code uses the `requests` package and the associated API. Both of these packages are fantastic in their own right, but they have slightly different API's.\r\n\r\nThe test suite [*does* pass](https://travis-ci.org/pacificclimate/pydap/builds/25826934) under all three version of Python, however, I'm nervous that the testing code isn't actually testing the production code (particularly w.r.t. content iteration). In this context, I would just as soon use `webob` across the board.\r\n\r\n### Monkeypatching sys.stdin is a bad idea\r\n\r\nI [removed one problematic test](https://github.com/pacificclimate/pydap/commit/afab06949e0a54cc38146e3f5e0fa4498612b192) because it was failing, and the setup function monkeypatched sys.stdin, which made it particularly heinous to debug (this makes `nosetests --pdb` disfunctional).\r\n\r\nThat test just tested a function that dumps to stdout, so I just marked it with a no cover pragma. If there's a better solution, I'm open to it.","created_at":"2014-05-22T23:07:25Z","updated_at":"2015-07-14T01:20:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"18ab1da7278e3b31f43eacb8c63df3c225c26a9d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9/commits","review_comments_url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9/comments","review_comment_url":"https://api.github.com/repos/robertodealmeida/pydap/pulls/comments{/number}","comments_url":"https://api.github.com/repos/robertodealmeida/pydap/issues/9/comments","statuses_url":"https://api.github.com/repos/robertodealmeida/pydap/statuses/4b9c0f5b642f7103d5679c7fa7209ee6617b1ef4","head":{"label":"pacificclimate:develop","ref":"develop","sha":"4b9c0f5b642f7103d5679c7fa7209ee6617b1ef4","user":{"login":"pacificclimate","id":7443397,"avatar_url":"https://avatars.githubusercontent.com/u/7443397?v=3","gravatar_id":"","url":"https://api.github.com/users/pacificclimate","html_url":"https://github.com/pacificclimate","followers_url":"https://api.github.com/users/pacificclimate/followers","following_url":"https://api.github.com/users/pacificclimate/following{/other_user}","gists_url":"https://api.github.com/users/pacificclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/pacificclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pacificclimate/subscriptions","organizations_url":"https://api.github.com/users/pacificclimate/orgs","repos_url":"https://api.github.com/users/pacificclimate/repos","events_url":"https://api.github.com/users/pacificclimate/events{/privacy}","received_events_url":"https://api.github.com/users/pacificclimate/received_events","type":"Organization","site_admin":false},"repo":{"id":19617015,"name":"pydap","full_name":"pacificclimate/pydap","owner":{"login":"pacificclimate","id":7443397,"avatar_url":"https://avatars.githubusercontent.com/u/7443397?v=3","gravatar_id":"","url":"https://api.github.com/users/pacificclimate","html_url":"https://github.com/pacificclimate","followers_url":"https://api.github.com/users/pacificclimate/followers","following_url":"https://api.github.com/users/pacificclimate/following{/other_user}","gists_url":"https://api.github.com/users/pacificclimate/gists{/gist_id}","starred_url":"https://api.github.com/users/pacificclimate/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pacificclimate/subscriptions","organizations_url":"https://api.github.com/users/pacificclimate/orgs","repos_url":"https://api.github.com/users/pacificclimate/repos","events_url":"https://api.github.com/users/pacificclimate/events{/privacy}","received_events_url":"https://api.github.com/users/pacificclimate/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pacificclimate/pydap","description":"A Python library implementing the Data Access Protocol (DAP, aka OPeNDAP or DODS).","fork":true,"url":"https://api.github.com/repos/pacificclimate/pydap","forks_url":"https://api.github.com/repos/pacificclimate/pydap/forks","keys_url":"https://api.github.com/repos/pacificclimate/pydap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pacificclimate/pydap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pacificclimate/pydap/teams","hooks_url":"https://api.github.com/repos/pacificclimate/pydap/hooks","issue_events_url":"https://api.github.com/repos/pacificclimate/pydap/issues/events{/number}","events_url":"https://api.github.com/repos/pacificclimate/pydap/events","assignees_url":"https://api.github.com/repos/pacificclimate/pydap/assignees{/user}","branches_url":"https://api.github.com/repos/pacificclimate/pydap/branches{/branch}","tags_url":"https://api.github.com/repos/pacificclimate/pydap/tags","blobs_url":"https://api.github.com/repos/pacificclimate/pydap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pacificclimate/pydap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pacificclimate/pydap/git/refs{/sha}","trees_url":"https://api.github.com/repos/pacificclimate/pydap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pacificclimate/pydap/statuses/{sha}","languages_url":"https://api.github.com/repos/pacificclimate/pydap/languages","stargazers_url":"https://api.github.com/repos/pacificclimate/pydap/stargazers","contributors_url":"https://api.github.com/repos/pacificclimate/pydap/contributors","subscribers_url":"https://api.github.com/repos/pacificclimate/pydap/subscribers","subscription_url":"https://api.github.com/repos/pacificclimate/pydap/subscription","commits_url":"https://api.github.com/repos/pacificclimate/pydap/commits{/sha}","git_commits_url":"https://api.github.com/repos/pacificclimate/pydap/git/commits{/sha}","comments_url":"https://api.github.com/repos/pacificclimate/pydap/comments{/number}","issue_comment_url":"https://api.github.com/repos/pacificclimate/pydap/issues/comments{/number}","contents_url":"https://api.github.com/repos/pacificclimate/pydap/contents/{+path}","compare_url":"https://api.github.com/repos/pacificclimate/pydap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pacificclimate/pydap/merges","archive_url":"https://api.github.com/repos/pacificclimate/pydap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pacificclimate/pydap/downloads","issues_url":"https://api.github.com/repos/pacificclimate/pydap/issues{/number}","pulls_url":"https://api.github.com/repos/pacificclimate/pydap/pulls{/number}","milestones_url":"https://api.github.com/repos/pacificclimate/pydap/milestones{/number}","notifications_url":"https://api.github.com/repos/pacificclimate/pydap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pacificclimate/pydap/labels{/name}","releases_url":"https://api.github.com/repos/pacificclimate/pydap/releases{/id}","created_at":"2014-05-09T16:06:02Z","updated_at":"2014-05-22T23:07:25Z","pushed_at":"2014-05-22T21:50:59Z","git_url":"git://github.com/pacificclimate/pydap.git","ssh_url":"git@github.com:pacificclimate/pydap.git","clone_url":"https://github.com/pacificclimate/pydap.git","svn_url":"https://github.com/pacificclimate/pydap","homepage":"http://pydap.org/","size":5923,"stargazers_count":1,"watchers_count":1,"language":"nesC","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"robertodealmeida:develop","ref":"develop","sha":"209ea543ca1e01946304b48af8a9506212bb0c38","user":{"login":"robertodealmeida","id":1534870,"avatar_url":"https://avatars.githubusercontent.com/u/1534870?v=3","gravatar_id":"","url":"https://api.github.com/users/robertodealmeida","html_url":"https://github.com/robertodealmeida","followers_url":"https://api.github.com/users/robertodealmeida/followers","following_url":"https://api.github.com/users/robertodealmeida/following{/other_user}","gists_url":"https://api.github.com/users/robertodealmeida/gists{/gist_id}","starred_url":"https://api.github.com/users/robertodealmeida/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robertodealmeida/subscriptions","organizations_url":"https://api.github.com/users/robertodealmeida/orgs","repos_url":"https://api.github.com/users/robertodealmeida/repos","events_url":"https://api.github.com/users/robertodealmeida/events{/privacy}","received_events_url":"https://api.github.com/users/robertodealmeida/received_events","type":"User","site_admin":false},"repo":{"id":10464231,"name":"pydap","full_name":"robertodealmeida/pydap","owner":{"login":"robertodealmeida","id":1534870,"avatar_url":"https://avatars.githubusercontent.com/u/1534870?v=3","gravatar_id":"","url":"https://api.github.com/users/robertodealmeida","html_url":"https://github.com/robertodealmeida","followers_url":"https://api.github.com/users/robertodealmeida/followers","following_url":"https://api.github.com/users/robertodealmeida/following{/other_user}","gists_url":"https://api.github.com/users/robertodealmeida/gists{/gist_id}","starred_url":"https://api.github.com/users/robertodealmeida/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robertodealmeida/subscriptions","organizations_url":"https://api.github.com/users/robertodealmeida/orgs","repos_url":"https://api.github.com/users/robertodealmeida/repos","events_url":"https://api.github.com/users/robertodealmeida/events{/privacy}","received_events_url":"https://api.github.com/users/robertodealmeida/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/robertodealmeida/pydap","description":"A Python library implementing the Data Access Protocol (DAP, aka OPeNDAP or DODS).","fork":false,"url":"https://api.github.com/repos/robertodealmeida/pydap","forks_url":"https://api.github.com/repos/robertodealmeida/pydap/forks","keys_url":"https://api.github.com/repos/robertodealmeida/pydap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/robertodealmeida/pydap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/robertodealmeida/pydap/teams","hooks_url":"https://api.github.com/repos/robertodealmeida/pydap/hooks","issue_events_url":"https://api.github.com/repos/robertodealmeida/pydap/issues/events{/number}","events_url":"https://api.github.com/repos/robertodealmeida/pydap/events","assignees_url":"https://api.github.com/repos/robertodealmeida/pydap/assignees{/user}","branches_url":"https://api.github.com/repos/robertodealmeida/pydap/branches{/branch}","tags_url":"https://api.github.com/repos/robertodealmeida/pydap/tags","blobs_url":"https://api.github.com/repos/robertodealmeida/pydap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/robertodealmeida/pydap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/robertodealmeida/pydap/git/refs{/sha}","trees_url":"https://api.github.com/repos/robertodealmeida/pydap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/robertodealmeida/pydap/statuses/{sha}","languages_url":"https://api.github.com/repos/robertodealmeida/pydap/languages","stargazers_url":"https://api.github.com/repos/robertodealmeida/pydap/stargazers","contributors_url":"https://api.github.com/repos/robertodealmeida/pydap/contributors","subscribers_url":"https://api.github.com/repos/robertodealmeida/pydap/subscribers","subscription_url":"https://api.github.com/repos/robertodealmeida/pydap/subscription","commits_url":"https://api.github.com/repos/robertodealmeida/pydap/commits{/sha}","git_commits_url":"https://api.github.com/repos/robertodealmeida/pydap/git/commits{/sha}","comments_url":"https://api.github.com/repos/robertodealmeida/pydap/comments{/number}","issue_comment_url":"https://api.github.com/repos/robertodealmeida/pydap/issues/comments{/number}","contents_url":"https://api.github.com/repos/robertodealmeida/pydap/contents/{+path}","compare_url":"https://api.github.com/repos/robertodealmeida/pydap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/robertodealmeida/pydap/merges","archive_url":"https://api.github.com/repos/robertodealmeida/pydap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/robertodealmeida/pydap/downloads","issues_url":"https://api.github.com/repos/robertodealmeida/pydap/issues{/number}","pulls_url":"https://api.github.com/repos/robertodealmeida/pydap/pulls{/number}","milestones_url":"https://api.github.com/repos/robertodealmeida/pydap/milestones{/number}","notifications_url":"https://api.github.com/repos/robertodealmeida/pydap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/robertodealmeida/pydap/labels{/name}","releases_url":"https://api.github.com/repos/robertodealmeida/pydap/releases{/id}","created_at":"2013-06-03T20:42:50Z","updated_at":"2015-06-10T13:25:29Z","pushed_at":"2015-06-17T19:04:24Z","git_url":"git://github.com/robertodealmeida/pydap.git","ssh_url":"git@github.com:robertodealmeida/pydap.git","clone_url":"https://github.com/robertodealmeida/pydap.git","svn_url":"https://github.com/robertodealmeida/pydap","homepage":"http://pydap.org/","size":6110,"stargazers_count":24,"watchers_count":24,"language":"nesC","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":15,"mirror_url":null,"open_issues_count":9,"forks":15,"open_issues":9,"watchers":24,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9"},"html":{"href":"https://github.com/robertodealmeida/pydap/pull/9"},"issue":{"href":"https://api.github.com/repos/robertodealmeida/pydap/issues/9"},"comments":{"href":"https://api.github.com/repos/robertodealmeida/pydap/issues/9/comments"},"review_comments":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9/comments"},"review_comment":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/robertodealmeida/pydap/pulls/9/commits"},"statuses":{"href":"https://api.github.com/repos/robertodealmeida/pydap/statuses/4b9c0f5b642f7103d5679c7fa7209ee6617b1ef4"}}}}