diff --git a/jira/client.py b/jira/client.py index ff70b2ccc..78e600db4 100644 --- a/jira/client.py +++ b/jira/client.py @@ -35,6 +35,7 @@ Type, TypeVar, Union, + cast, no_type_check, ) from urllib.parse import urlparse @@ -849,8 +850,11 @@ def add_attachment( Returns: Attachment """ + close_attachment = False if isinstance(attachment, str): attachment: BufferedReader = open(attachment, "rb") # type: ignore + attachment = cast(BufferedReader, attachment) + close_attachment = True elif isinstance(attachment, BufferedReader) and attachment.mode != "rb": self.log.warning( "%s was not opened in 'rb' mode, attaching file may fail." @@ -865,13 +869,17 @@ def add_attachment( if "MultipartEncoder" not in globals(): method = "old" - r = self._session.post( - url, - files={"file": (fname, attachment, "application/octet-stream")}, - headers=CaseInsensitiveDict( - {"content-type": None, "X-Atlassian-Token": "no-check"} - ), - ) + try: + r = self._session.post( + url, + files={"file": (fname, attachment, "application/octet-stream")}, + headers=CaseInsensitiveDict( + {"content-type": None, "X-Atlassian-Token": "no-check"} + ), + ) + finally: + if close_attachment: + attachment.close() else: method = "MultipartEncoder" @@ -882,14 +890,21 @@ def file_stream() -> MultipartEncoder: ) m = file_stream() - r = self._session.post( - url, - data=m, - headers=CaseInsensitiveDict( - {"content-type": m.content_type, "X-Atlassian-Token": "no-check"} - ), - retry_data=file_stream, - ) + try: + r = self._session.post( + url, + data=m, + headers=CaseInsensitiveDict( + { + "content-type": m.content_type, + "X-Atlassian-Token": "no-check", + } + ), + retry_data=file_stream, + ) + finally: + if close_attachment: + attachment.close() js: Union[Dict[str, Any], List[Dict[str, Any]]] = json_loads(r) if not js or not isinstance(js, Iterable):