From 875140296fada3659d224e3a5819ba77a81e36fe Mon Sep 17 00:00:00 2001 From: Nejc Habjan Date: Sat, 26 Nov 2022 15:59:20 +0100 Subject: [PATCH] feat(files): allow decoding project files directly to string --- docs/gl_objects/projects.rst | 5 ++++- gitlab/v4/objects/files.py | 22 ++++++++++++++++++++-- tests/functional/api/test_repository.py | 6 +++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst index 7fc0ab9c2..5285c40b0 100644 --- a/docs/gl_objects/projects.rst +++ b/docs/gl_objects/projects.rst @@ -434,9 +434,12 @@ Get a file:: # get the base64 encoded content print(f.content) - # get the decoded content + # get the decoded content as bytes print(f.decode()) + # get the decoded content as a string + print(f.decode("utf-8")) + Get file details from headers, without fetching its entire content:: headers = project.files.head('README.rst', ref='main') diff --git a/gitlab/v4/objects/files.py b/gitlab/v4/objects/files.py index d81b7111b..56c1791bc 100644 --- a/gitlab/v4/objects/files.py +++ b/gitlab/v4/objects/files.py @@ -7,6 +7,7 @@ Iterator, List, Optional, + overload, TYPE_CHECKING, Union, ) @@ -41,13 +42,30 @@ class ProjectFile(SaveMixin, ObjectDeleteMixin, RESTObject): file_path: str manager: "ProjectFileManager" + @overload def decode(self) -> bytes: + ... + + @overload + def decode(self, encoding: None) -> bytes: + ... + + @overload + def decode(self, encoding: str) -> str: + ... + + def decode(self, encoding: Optional[str] = None) -> Union[bytes, str]: """Returns the decoded content of the file. Returns: - The decoded content. + The decoded content as bytes. + The decoded content as string if a valid encoding is provided. """ - return base64.b64decode(self.content) + decoded_bytes = base64.b64decode(self.content) + + if encoding is not None: + return decoded_bytes.decode(encoding) + return decoded_bytes # NOTE(jlvillal): Signature doesn't match SaveMixin.save() so ignore # type error diff --git a/tests/functional/api/test_repository.py b/tests/functional/api/test_repository.py index dd70f10b1..a7c291748 100644 --- a/tests/functional/api/test_repository.py +++ b/tests/functional/api/test_repository.py @@ -36,9 +36,9 @@ def test_repository_files(project): } ) readme = project.files.get(file_path="README.rst", ref="main") - # The first decode() is the ProjectFile method, the second one is the bytes - # object method - assert readme.decode().decode() == "Initial content" + + assert readme.decode() == b"Initial content" + assert readme.decode("utf-8") == "Initial content" headers = project.files.head("README.rst", ref="main") assert headers["X-Gitlab-File-Path"] == "README.rst"