From 7098fedd7a144cd315871a67927d094d09dc7cb8 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 1 Nov 2020 19:39:53 +0100 Subject: [PATCH 1/4] Add whence parameter to UploadFile.seek() --- starlette/datastructures.py | 6 +++--- tests/test_datastructures.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/starlette/datastructures.py b/starlette/datastructures.py index 8dad7b0b5..8dd5d8489 100644 --- a/starlette/datastructures.py +++ b/starlette/datastructures.py @@ -449,11 +449,11 @@ async def read(self, size: int = -1) -> typing.Union[bytes, str]: return self.file.read(size) return await run_in_threadpool(self.file.read, size) - async def seek(self, offset: int) -> None: + async def seek(self, offset: int, whence: int = 0) -> None: if self._in_memory: - self.file.seek(offset) + self.file.seek(offset, whence) else: - await run_in_threadpool(self.file.seek, offset) + await run_in_threadpool(self.file.seek, offset, whence) async def close(self) -> None: if self._in_memory: diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py index b0e6baf98..bd356c236 100644 --- a/tests/test_datastructures.py +++ b/tests/test_datastructures.py @@ -222,7 +222,7 @@ async def test_upload_file(): big_file = BigUploadFile("big-file") await big_file.write(b"big-data" * 512) await big_file.write(b"big-data") - await big_file.seek(0) + await big_file.seek(0, 0) assert await big_file.read(1024) == b"big-data" * 128 await big_file.close() From 3a62e71adcbb9b6f7babbcfd31980af80d002b6c Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 1 Nov 2020 20:14:23 +0100 Subject: [PATCH 2/4] Add UploadFile.tell() parameter Also improve tests for seek(), testing with and without the whence parameter. --- starlette/datastructures.py | 3 +++ tests/test_datastructures.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/starlette/datastructures.py b/starlette/datastructures.py index 8dd5d8489..37457b52a 100644 --- a/starlette/datastructures.py +++ b/starlette/datastructures.py @@ -455,6 +455,9 @@ async def seek(self, offset: int, whence: int = 0) -> None: else: await run_in_threadpool(self.file.seek, offset, whence) + def tell(self) -> int: + return self.file.tell() + async def close(self) -> None: if self._in_memory: self.file.close() diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py index bd356c236..23ce4edef 100644 --- a/tests/test_datastructures.py +++ b/tests/test_datastructures.py @@ -220,9 +220,15 @@ class BigUploadFile(UploadFile): @pytest.mark.asyncio async def test_upload_file(): big_file = BigUploadFile("big-file") + await big_file.seek(0) await big_file.write(b"big-data" * 512) await big_file.write(b"big-data") - await big_file.seek(0, 0) + pos = big_file.tell() + assert pos > 512 * len(b"big-data") + await big_file.seek(-10, 1) + assert big_file.tell() == pos - 10 + await big_file.seek(0) + assert big_file.tell() == 0 assert await big_file.read(1024) == b"big-data" * 128 await big_file.close() From 104d170a3055705e0d01ca90509f72018c5b61dc Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Mon, 9 Nov 2020 20:23:54 +0000 Subject: [PATCH 3/4] UploadFile.tell() made async --- starlette/datastructures.py | 7 +++++-- tests/test_datastructures.py | 6 +++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/starlette/datastructures.py b/starlette/datastructures.py index 37457b52a..71c93e7c8 100644 --- a/starlette/datastructures.py +++ b/starlette/datastructures.py @@ -455,8 +455,11 @@ async def seek(self, offset: int, whence: int = 0) -> None: else: await run_in_threadpool(self.file.seek, offset, whence) - def tell(self) -> int: - return self.file.tell() + async def tell(self) -> int: + if self._in_memory: + return self.file.tell() + else: + return await run_in_threadpool(self.file.tell) async def close(self) -> None: if self._in_memory: diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py index 23ce4edef..330296d1c 100644 --- a/tests/test_datastructures.py +++ b/tests/test_datastructures.py @@ -223,12 +223,12 @@ async def test_upload_file(): await big_file.seek(0) await big_file.write(b"big-data" * 512) await big_file.write(b"big-data") - pos = big_file.tell() + pos = await big_file.tell() assert pos > 512 * len(b"big-data") await big_file.seek(-10, 1) - assert big_file.tell() == pos - 10 + assert (await big_file.tell()) == pos - 10 await big_file.seek(0) - assert big_file.tell() == 0 + assert (await big_file.tell()) == 0 assert await big_file.read(1024) == b"big-data" * 128 await big_file.close() From bac2fa80116f8f397b96368c402dbbc6b6a94464 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Mon, 9 Nov 2020 20:43:43 +0000 Subject: [PATCH 4/4] Test FileUpload.tell() both in in_memory state and spooled on disk --- tests/test_datastructures.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py index 330296d1c..7562e2fda 100644 --- a/tests/test_datastructures.py +++ b/tests/test_datastructures.py @@ -1,4 +1,5 @@ import io +import os import pytest @@ -220,12 +221,17 @@ class BigUploadFile(UploadFile): @pytest.mark.asyncio async def test_upload_file(): big_file = BigUploadFile("big-file") + await big_file.write(b"big-data") + assert (await big_file.tell()) == 8 await big_file.seek(0) - await big_file.write(b"big-data" * 512) + assert (await big_file.tell()) == 0 + await big_file.seek(0, os.SEEK_END) + assert (await big_file.tell()) == 8 + await big_file.write(b"big-data" * 511) await big_file.write(b"big-data") pos = await big_file.tell() assert pos > 512 * len(b"big-data") - await big_file.seek(-10, 1) + await big_file.seek(-10, os.SEEK_CUR) assert (await big_file.tell()) == pos - 10 await big_file.seek(0) assert (await big_file.tell()) == 0