{"action":"created","comment":{"url":"https://api.github.com/repos/python/asyncio/pulls/comments/47560233","id":47560233,"diff_hunk":"@@ -426,43 +454,134 @@ def _wait_for_data(self, func_name):\n \n     @coroutine\n     def readline(self):\n+        \"\"\"Read chunk of data from the stream until newline (b'\\n') is found.\n+\n+        On success, return chunk that ends with newline. If only partial\n+        line can be read due to EOF, return incomplete line without\n+        terminating newline. When EOF was reached while no bytes read, empty\n+        bytes object is returned.\n+\n+        If limit is reached, ValueError will be raised. In that case, if\n+        newline was found, complete line including newline will be removed\n+        from internal buffer. Else, internal buffer will be cleared. Limit is\n+        compared against part of the line without newline.\n+\n+        If stream was paused, this function will automatically resume it if\n+        needed.\n+        \"\"\"\n+        sep = b'\\n'\n+        seplen = len(sep)\n+        try:\n+            line = yield from self.readuntil(sep)\n+        except IncompleteReadError as e:\n+            return e.partial\n+        except LimitOverrunError as e:\n+            if self._buffer.startswith(sep, e.consumed):\n+                del self._buffer[:e.consumed + seplen]\n+            else:\n+                self._buffer.clear()\n+            self._maybe_resume_transport()\n+            raise ValueError(e.args[0])\n+        return line\n+\n+    @coroutine\n+    def readuntil(self, separator=b'\\n'):\n+        \"\"\"Read chunk of data from the stream until `separator` is found.\n+\n+        On success, chunk and its separator will be removed from internal buffer\n+        (i.e. consumed). Returned chunk will include separator at the end.\n+\n+        Configured stream limit is used to check result. Limit means maximal\n+        length of chunk that can be returned, not counting the separator.\n+\n+        If EOF occurs and complete separator still not found,\n+        IncompleteReadError(<partial data>, None) will be raised and internal\n+        buffer becomes empty. This partial data may contain a partial separator.\n+\n+        If chunk cannot be read due to overlimit, LimitOverrunError will be raised\n+        and data will be left in internal buffer, so it can be read again, in\n+        some different way.","path":"asyncio/streams.py","position":136,"original_position":136,"commit_id":"f143d32b4cdff68b5883963c8559c6bbaf37c368","original_commit_id":"9e0c0f997b7fa63f4e3408d0d2dffdb11d48c4d7","user":{"login":"socketpair","id":1157412,"avatar_url":"https://avatars.githubusercontent.com/u/1157412?v=3","gravatar_id":"","url":"https://api.github.com/users/socketpair","html_url":"https://github.com/socketpair","followers_url":"https://api.github.com/users/socketpair/followers","following_url":"https://api.github.com/users/socketpair/following{/other_user}","gists_url":"https://api.github.com/users/socketpair/gists{/gist_id}","starred_url":"https://api.github.com/users/socketpair/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/socketpair/subscriptions","organizations_url":"https://api.github.com/users/socketpair/orgs","repos_url":"https://api.github.com/users/socketpair/repos","events_url":"https://api.github.com/users/socketpair/events{/privacy}","received_events_url":"https://api.github.com/users/socketpair/received_events","type":"User","site_admin":false},"body":"Yes, readline before me just clears buffers (sometimes, depending on fact it found newline or not), and was not closing connection. You may see original, not so obvious code.","created_at":"2015-12-14T21:26:34Z","updated_at":"2015-12-14T21:26:34Z","html_url":"https://github.com/python/asyncio/pull/297#discussion_r47560233","pull_request_url":"https://api.github.com/repos/python/asyncio/pulls/297","_links":{"self":{"href":"https://api.github.com/repos/python/asyncio/pulls/comments/47560233"},"html":{"href":"https://github.com/python/asyncio/pull/297#discussion_r47560233"},"pull_request":{"href":"https://api.github.com/repos/python/asyncio/pulls/297"}}},"pull_request":{"url":"https://api.github.com/repos/python/asyncio/pulls/297","id":52069365,"html_url":"https://github.com/python/asyncio/pull/297","diff_url":"https://github.com/python/asyncio/pull/297.diff","patch_url":"https://github.com/python/asyncio/pull/297.patch","issue_url":"https://api.github.com/repos/python/asyncio/issues/297","number":297,"state":"open","locked":false,"title":"Add new StreamReader.readuntil() method.","user":{"login":"socketpair","id":1157412,"avatar_url":"https://avatars.githubusercontent.com/u/1157412?v=3","gravatar_id":"","url":"https://api.github.com/users/socketpair","html_url":"https://github.com/socketpair","followers_url":"https://api.github.com/users/socketpair/followers","following_url":"https://api.github.com/users/socketpair/following{/other_user}","gists_url":"https://api.github.com/users/socketpair/gists{/gist_id}","starred_url":"https://api.github.com/users/socketpair/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/socketpair/subscriptions","organizations_url":"https://api.github.com/users/socketpair/orgs","repos_url":"https://api.github.com/users/socketpair/repos","events_url":"https://api.github.com/users/socketpair/events{/privacy}","received_events_url":"https://api.github.com/users/socketpair/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-11-29T19:53:07Z","updated_at":"2015-12-14T21:26:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f1cd99fa94e292200bf54990051437ceff45e588","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/python/asyncio/pulls/297/commits","review_comments_url":"https://api.github.com/repos/python/asyncio/pulls/297/comments","review_comment_url":"https://api.github.com/repos/python/asyncio/pulls/comments{/number}","comments_url":"https://api.github.com/repos/python/asyncio/issues/297/comments","statuses_url":"https://api.github.com/repos/python/asyncio/statuses/f143d32b4cdff68b5883963c8559c6bbaf37c368","head":{"label":"socketpair:separ","ref":"separ","sha":"f143d32b4cdff68b5883963c8559c6bbaf37c368","user":{"login":"socketpair","id":1157412,"avatar_url":"https://avatars.githubusercontent.com/u/1157412?v=3","gravatar_id":"","url":"https://api.github.com/users/socketpair","html_url":"https://github.com/socketpair","followers_url":"https://api.github.com/users/socketpair/followers","following_url":"https://api.github.com/users/socketpair/following{/other_user}","gists_url":"https://api.github.com/users/socketpair/gists{/gist_id}","starred_url":"https://api.github.com/users/socketpair/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/socketpair/subscriptions","organizations_url":"https://api.github.com/users/socketpair/orgs","repos_url":"https://api.github.com/users/socketpair/repos","events_url":"https://api.github.com/users/socketpair/events{/privacy}","received_events_url":"https://api.github.com/users/socketpair/received_events","type":"User","site_admin":false},"repo":{"id":47069205,"name":"asyncio","full_name":"socketpair/asyncio","owner":{"login":"socketpair","id":1157412,"avatar_url":"https://avatars.githubusercontent.com/u/1157412?v=3","gravatar_id":"","url":"https://api.github.com/users/socketpair","html_url":"https://github.com/socketpair","followers_url":"https://api.github.com/users/socketpair/followers","following_url":"https://api.github.com/users/socketpair/following{/other_user}","gists_url":"https://api.github.com/users/socketpair/gists{/gist_id}","starred_url":"https://api.github.com/users/socketpair/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/socketpair/subscriptions","organizations_url":"https://api.github.com/users/socketpair/orgs","repos_url":"https://api.github.com/users/socketpair/repos","events_url":"https://api.github.com/users/socketpair/events{/privacy}","received_events_url":"https://api.github.com/users/socketpair/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/socketpair/asyncio","description":"This project is the asyncio module for Python 3.3. Since Python 3.4, asyncio is part of the standard library.","fork":true,"url":"https://api.github.com/repos/socketpair/asyncio","forks_url":"https://api.github.com/repos/socketpair/asyncio/forks","keys_url":"https://api.github.com/repos/socketpair/asyncio/keys{/key_id}","collaborators_url":"https://api.github.com/repos/socketpair/asyncio/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/socketpair/asyncio/teams","hooks_url":"https://api.github.com/repos/socketpair/asyncio/hooks","issue_events_url":"https://api.github.com/repos/socketpair/asyncio/issues/events{/number}","events_url":"https://api.github.com/repos/socketpair/asyncio/events","assignees_url":"https://api.github.com/repos/socketpair/asyncio/assignees{/user}","branches_url":"https://api.github.com/repos/socketpair/asyncio/branches{/branch}","tags_url":"https://api.github.com/repos/socketpair/asyncio/tags","blobs_url":"https://api.github.com/repos/socketpair/asyncio/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/socketpair/asyncio/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/socketpair/asyncio/git/refs{/sha}","trees_url":"https://api.github.com/repos/socketpair/asyncio/git/trees{/sha}","statuses_url":"https://api.github.com/repos/socketpair/asyncio/statuses/{sha}","languages_url":"https://api.github.com/repos/socketpair/asyncio/languages","stargazers_url":"https://api.github.com/repos/socketpair/asyncio/stargazers","contributors_url":"https://api.github.com/repos/socketpair/asyncio/contributors","subscribers_url":"https://api.github.com/repos/socketpair/asyncio/subscribers","subscription_url":"https://api.github.com/repos/socketpair/asyncio/subscription","commits_url":"https://api.github.com/repos/socketpair/asyncio/commits{/sha}","git_commits_url":"https://api.github.com/repos/socketpair/asyncio/git/commits{/sha}","comments_url":"https://api.github.com/repos/socketpair/asyncio/comments{/number}","issue_comment_url":"https://api.github.com/repos/socketpair/asyncio/issues/comments{/number}","contents_url":"https://api.github.com/repos/socketpair/asyncio/contents/{+path}","compare_url":"https://api.github.com/repos/socketpair/asyncio/compare/{base}...{head}","merges_url":"https://api.github.com/repos/socketpair/asyncio/merges","archive_url":"https://api.github.com/repos/socketpair/asyncio/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/socketpair/asyncio/downloads","issues_url":"https://api.github.com/repos/socketpair/asyncio/issues{/number}","pulls_url":"https://api.github.com/repos/socketpair/asyncio/pulls{/number}","milestones_url":"https://api.github.com/repos/socketpair/asyncio/milestones{/number}","notifications_url":"https://api.github.com/repos/socketpair/asyncio/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/socketpair/asyncio/labels{/name}","releases_url":"https://api.github.com/repos/socketpair/asyncio/releases{/id}","created_at":"2015-11-29T15:40:00Z","updated_at":"2015-11-29T15:40:02Z","pushed_at":"2015-12-14T21:11:21Z","git_url":"git://github.com/socketpair/asyncio.git","ssh_url":"git@github.com:socketpair/asyncio.git","clone_url":"https://github.com/socketpair/asyncio.git","svn_url":"https://github.com/socketpair/asyncio","homepage":"https://github.com/python/asyncio/wiki","size":1583,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"python:master","ref":"master","sha":"74f2d8c87b30f9867b781c87b64c1a4e9ee27cc5","user":{"login":"python","id":1525981,"avatar_url":"https://avatars.githubusercontent.com/u/1525981?v=3","gravatar_id":"","url":"https://api.github.com/users/python","html_url":"https://github.com/python","followers_url":"https://api.github.com/users/python/followers","following_url":"https://api.github.com/users/python/following{/other_user}","gists_url":"https://api.github.com/users/python/gists{/gist_id}","starred_url":"https://api.github.com/users/python/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/python/subscriptions","organizations_url":"https://api.github.com/users/python/orgs","repos_url":"https://api.github.com/users/python/repos","events_url":"https://api.github.com/users/python/events{/privacy}","received_events_url":"https://api.github.com/users/python/received_events","type":"Organization","site_admin":false},"repo":{"id":33739295,"name":"asyncio","full_name":"python/asyncio","owner":{"login":"python","id":1525981,"avatar_url":"https://avatars.githubusercontent.com/u/1525981?v=3","gravatar_id":"","url":"https://api.github.com/users/python","html_url":"https://github.com/python","followers_url":"https://api.github.com/users/python/followers","following_url":"https://api.github.com/users/python/following{/other_user}","gists_url":"https://api.github.com/users/python/gists{/gist_id}","starred_url":"https://api.github.com/users/python/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/python/subscriptions","organizations_url":"https://api.github.com/users/python/orgs","repos_url":"https://api.github.com/users/python/repos","events_url":"https://api.github.com/users/python/events{/privacy}","received_events_url":"https://api.github.com/users/python/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/python/asyncio","description":"This project is the asyncio module for Python 3.3. Since Python 3.4, asyncio is part of the standard library.","fork":false,"url":"https://api.github.com/repos/python/asyncio","forks_url":"https://api.github.com/repos/python/asyncio/forks","keys_url":"https://api.github.com/repos/python/asyncio/keys{/key_id}","collaborators_url":"https://api.github.com/repos/python/asyncio/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/python/asyncio/teams","hooks_url":"https://api.github.com/repos/python/asyncio/hooks","issue_events_url":"https://api.github.com/repos/python/asyncio/issues/events{/number}","events_url":"https://api.github.com/repos/python/asyncio/events","assignees_url":"https://api.github.com/repos/python/asyncio/assignees{/user}","branches_url":"https://api.github.com/repos/python/asyncio/branches{/branch}","tags_url":"https://api.github.com/repos/python/asyncio/tags","blobs_url":"https://api.github.com/repos/python/asyncio/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/python/asyncio/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/python/asyncio/git/refs{/sha}","trees_url":"https://api.github.com/repos/python/asyncio/git/trees{/sha}","statuses_url":"https://api.github.com/repos/python/asyncio/statuses/{sha}","languages_url":"https://api.github.com/repos/python/asyncio/languages","stargazers_url":"https://api.github.com/repos/python/asyncio/stargazers","contributors_url":"https://api.github.com/repos/python/asyncio/contributors","subscribers_url":"https://api.github.com/repos/python/asyncio/subscribers","subscription_url":"https://api.github.com/repos/python/asyncio/subscription","commits_url":"https://api.github.com/repos/python/asyncio/commits{/sha}","git_commits_url":"https://api.github.com/repos/python/asyncio/git/commits{/sha}","comments_url":"https://api.github.com/repos/python/asyncio/comments{/number}","issue_comment_url":"https://api.github.com/repos/python/asyncio/issues/comments{/number}","contents_url":"https://api.github.com/repos/python/asyncio/contents/{+path}","compare_url":"https://api.github.com/repos/python/asyncio/compare/{base}...{head}","merges_url":"https://api.github.com/repos/python/asyncio/merges","archive_url":"https://api.github.com/repos/python/asyncio/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/python/asyncio/downloads","issues_url":"https://api.github.com/repos/python/asyncio/issues{/number}","pulls_url":"https://api.github.com/repos/python/asyncio/pulls{/number}","milestones_url":"https://api.github.com/repos/python/asyncio/milestones{/number}","notifications_url":"https://api.github.com/repos/python/asyncio/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/python/asyncio/labels{/name}","releases_url":"https://api.github.com/repos/python/asyncio/releases{/id}","created_at":"2015-04-10T16:41:54Z","updated_at":"2015-12-12T07:11:21Z","pushed_at":"2015-12-14T21:11:21Z","git_url":"git://github.com/python/asyncio.git","ssh_url":"git@github.com:python/asyncio.git","clone_url":"https://github.com/python/asyncio.git","svn_url":"https://github.com/python/asyncio","homepage":"https://github.com/python/asyncio/wiki","size":1923,"stargazers_count":208,"watchers_count":208,"language":"Python","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":43,"mirror_url":null,"open_issues_count":39,"forks":43,"open_issues":39,"watchers":208,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/python/asyncio/pulls/297"},"html":{"href":"https://github.com/python/asyncio/pull/297"},"issue":{"href":"https://api.github.com/repos/python/asyncio/issues/297"},"comments":{"href":"https://api.github.com/repos/python/asyncio/issues/297/comments"},"review_comments":{"href":"https://api.github.com/repos/python/asyncio/pulls/297/comments"},"review_comment":{"href":"https://api.github.com/repos/python/asyncio/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/python/asyncio/pulls/297/commits"},"statuses":{"href":"https://api.github.com/repos/python/asyncio/statuses/f143d32b4cdff68b5883963c8559c6bbaf37c368"}}}}