Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove iter_text and iter_lines #20460

Merged
merged 4 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sdk/core/azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release History

## 1.17.1 (Unreleased)
## 1.18.0 (Unreleased)

### Features Added

Expand All @@ -10,6 +10,7 @@

- The `text` property on `azure.core.rest.HttpResponse` and `azure.core.rest.AsyncHttpResponse` has changed to a method, which also takes
an `encoding` parameter.
- Removed `iter_text` and `iter_lines` from `azure.core.rest.HttpResponse` and `azure.core.rest.AsyncHttpResponse`

### Bugs Fixed

Expand Down
2 changes: 1 addition & 1 deletion sdk/core/azure-core/azure/core/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# regenerated.
# --------------------------------------------------------------------------

VERSION = "1.17.1"
VERSION = "1.18.0"
34 changes: 0 additions & 34 deletions sdk/core/azure-core/azure/core/rest/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,40 +227,6 @@ def lookup_encoding(encoding):
except LookupError:
return False

def parse_lines_from_text(text):
# largely taken from httpx's LineDecoder code
lines = []
last_chunk_of_text = ""
while text:
text_length = len(text)
for idx in range(text_length):
curr_char = text[idx]
next_char = None if idx == len(text) - 1 else text[idx + 1]
if curr_char == "\n":
lines.append(text[: idx + 1])
text = text[idx + 1: ]
break
if curr_char == "\r" and next_char == "\n":
# if it ends with \r\n, we only do \n
lines.append(text[:idx] + "\n")
text = text[idx + 2:]
break
if curr_char == "\r" and next_char is not None:
# if it's \r then a normal character, we switch \r to \n
lines.append(text[:idx] + "\n")
text = text[idx + 1:]
break
if next_char is None:
last_chunk_of_text += text
text = ""
break
if last_chunk_of_text.endswith("\r"):
# if ends with \r, we switch \r to \n
lines.append(last_chunk_of_text[:-1] + "\n")
elif last_chunk_of_text:
lines.append(last_chunk_of_text)
return lines

def to_pipeline_transport_request_helper(rest_request):
from ..pipeline.transport import HttpRequest as PipelineTransportHttpRequest
return PipelineTransportHttpRequest(
Expand Down
16 changes: 0 additions & 16 deletions sdk/core/azure-core/azure/core/rest/_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from ..utils._utils import _case_insensitive_dict
from ._helpers import (
FilesType,
parse_lines_from_text,
set_content_body,
set_json_body,
set_multipart_body,
Expand Down Expand Up @@ -357,21 +356,6 @@ def iter_bytes(self):
"""
raise NotImplementedError()

def iter_text(self):
# type: () -> Iterator[str]
"""Iterate over the response text
"""
for byte in self.iter_bytes():
text = byte.decode(self.encoding or "utf-8")
yield text

def iter_lines(self):
# type: () -> Iterator[str]
for text in self.iter_text():
lines = parse_lines_from_text(text)
for line in lines:
yield line

def _close_stream(self):
# type: (...) -> None
self.is_stream_consumed = True
Expand Down
43 changes: 0 additions & 43 deletions sdk/core/azure-core/azure/core/rest/_rest_py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
FilesType,
HeadersType,
cast,
parse_lines_from_text,
set_json_body,
set_multipart_body,
set_urlencoded_body,
Expand Down Expand Up @@ -377,27 +376,6 @@ def iter_bytes(self) -> Iterator[bytes]:
"""
raise NotImplementedError()

def iter_text(self) -> Iterator[str]:
"""Iterates over the text in the response.

:return: An iterator of string. Each string chunk will be a text from the response
:rtype: Iterator[str]
"""
for byte in self.iter_bytes():
text = byte.decode(self.encoding or "utf-8")
yield text

def iter_lines(self) -> Iterator[str]:
"""Iterates over the lines in the response.

:return: An iterator of string. Each string chunk will be a line from the response
:rtype: Iterator[str]
"""
for text in self.iter_text():
lines = parse_lines_from_text(text)
for line in lines:
yield line

def __repr__(self) -> str:
content_type_str = (
", Content-Type: {}".format(self.content_type) if self.content_type else ""
Expand Down Expand Up @@ -471,27 +449,6 @@ async def iter_bytes(self) -> AsyncIterator[bytes]:
# getting around mypy behavior, see https://github.com/python/mypy/issues/10732
yield # pylint: disable=unreachable

async def iter_text(self) -> AsyncIterator[str]:
"""Asynchronously iterates over the text in the response.

:return: An async iterator of string. Each string chunk will be a text from the response
:rtype: AsyncIterator[str]
"""
async for byte in self.iter_bytes(): # type: ignore
text = byte.decode(self.encoding or "utf-8")
yield text

async def iter_lines(self) -> AsyncIterator[str]:
"""Asynchronously iterates over the lines in the response.

:return: An async iterator of string. Each string chunk will be a line from the response
:rtype: AsyncIterator[str]
"""
async for text in self.iter_text():
lines = parse_lines_from_text(text)
for line in lines:
yield line

async def close(self) -> None:
"""Close the response.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ async def test_iter_bytes(client):
assert response.is_closed
assert raw == b"Hello, world!"

@pytest.mark.skip(reason="We've gotten rid of iter_text for now")
@pytest.mark.asyncio
async def test_iter_text(client):
request = HttpRequest("GET", "/basic/string")
Expand All @@ -76,14 +77,15 @@ async def test_iter_text(client):
content += part
assert content == "Hello, world!"

@pytest.mark.skip(reason="We've gotten rid of iter_lines for now")
@pytest.mark.asyncio
async def test_iter_lines(client):
request = HttpRequest("GET", "/basic/lines")

async with client.send_request(request, stream=True) as response:
content = []
async for line in response.iter_lines():
content.append(line)
async for part in response.iter_lines():
content.append(part)
assert content == ["Hello,\n", "world!"]


Expand Down Expand Up @@ -161,11 +163,11 @@ async def test_iter_read_back_and_forth(client):
# the reason why the code flow is like this, is because the 'iter_x' functions don't
# actually read the contents into the response, the output them. Once they're yielded,
# the stream is closed, so you have to catch the output when you iterate through it
request = HttpRequest("GET", "/basic/lines")
request = HttpRequest("GET", "/basic/string")

async with client.send_request(request, stream=True) as response:
async for line in response.iter_lines():
assert line
async for part in response.iter_bytes():
assert part
with pytest.raises(ResponseNotReadError):
response.text()
with pytest.raises(StreamConsumedError):
Expand All @@ -175,16 +177,16 @@ async def test_iter_read_back_and_forth(client):

@pytest.mark.asyncio
async def test_stream_with_return_pipeline_response(client):
request = HttpRequest("GET", "/basic/lines")
request = HttpRequest("GET", "/basic/string")
pipeline_response = await client.send_request(request, stream=True, _return_pipeline_response=True)
assert hasattr(pipeline_response, "http_request")
assert hasattr(pipeline_response.http_request, "content")
assert hasattr(pipeline_response, "http_response")
assert hasattr(pipeline_response, "context")
parts = []
async for line in pipeline_response.http_response.iter_lines():
parts.append(line)
assert parts == ['Hello,\n', 'world!']
async for part in pipeline_response.http_response.iter_bytes():
parts.append(part)
assert parts == [b'Hello, world!']
await client.close()

@pytest.mark.asyncio
Expand Down
28 changes: 15 additions & 13 deletions sdk/core/azure-core/tests/test_rest_stream_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def test_iter_bytes(client):
assert response.is_stream_consumed
assert raw == b"Hello, world!"

@pytest.mark.skip(reason="We've gotten rid of iter_text for now")
def test_iter_text(client):
request = HttpRequest("GET", "/basic/string")

Expand All @@ -88,6 +89,7 @@ def test_iter_text(client):
content += part
assert content == "Hello, world!"

@pytest.mark.skip(reason="We've gotten rid of iter_lines for now")
def test_iter_lines(client):
request = HttpRequest("GET", "/basic/lines")

Expand Down Expand Up @@ -175,18 +177,18 @@ def test_decompress_compressed_header(client):
url = "https://{}.blob.core.windows.net/tests/test_with_header.tar.gz".format(account_name)
request = HttpRequest("GET", url)
response = client.send_request(request, stream=True)
iter = response.iter_text()
data = "".join(list(iter))
assert data == "test"
iter = response.iter_bytes()
data = b"".join(list(iter))
assert data == b"test"

def test_iter_read(client):
# thanks to McCoy Patiño for this test!
request = HttpRequest("GET", "/basic/lines")
request = HttpRequest("GET", "/basic/string")
response = client.send_request(request, stream=True)
response.read()
iterator = response.iter_lines()
for line in iterator:
assert line
iterator = response.iter_bytes()
for part in iterator:
assert part
assert response.text()

def test_iter_read_back_and_forth(client):
Expand All @@ -196,11 +198,11 @@ def test_iter_read_back_and_forth(client):
# the reason why the code flow is like this, is because the 'iter_x' functions don't
# actually read the contents into the response, the output them. Once they're yielded,
# the stream is closed, so you have to catch the output when you iterate through it
request = HttpRequest("GET", "/basic/lines")
request = HttpRequest("GET", "/basic/string")
response = client.send_request(request, stream=True)
iterator = response.iter_lines()
for line in iterator:
assert line
iterator = response.iter_bytes()
for part in iterator:
assert part
with pytest.raises(ResponseNotReadError):
response.text()
with pytest.raises(StreamConsumedError):
Expand All @@ -209,12 +211,12 @@ def test_iter_read_back_and_forth(client):
response.text()

def test_stream_with_return_pipeline_response(client):
request = HttpRequest("GET", "/basic/lines")
request = HttpRequest("GET", "/basic/string")
pipeline_response = client.send_request(request, stream=True, _return_pipeline_response=True)
assert hasattr(pipeline_response, "http_request")
assert hasattr(pipeline_response, "http_response")
assert hasattr(pipeline_response, "context")
assert list(pipeline_response.http_response.iter_lines()) == ['Hello,\n', 'world!']
assert list(pipeline_response.http_response.iter_bytes()) == [b'Hello, world!']

def test_error_reading(client):
request = HttpRequest("GET", "/errors/403")
Expand Down