From 9ec505f019f98c97e5c8ee976ee9875f75acecb0 Mon Sep 17 00:00:00 2001 From: James Addison Date: Tue, 11 Apr 2023 17:31:40 +0100 Subject: [PATCH] refactor: use requests.Response objects as context managers during linkchecking This ensures that the close method of the response is called when the response variable goes out-of-scope --- sphinx/builders/linkcheck.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 694b6fc2440..652c2a01bc3 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -316,22 +316,20 @@ def check_uri() -> tuple[str, str, int]: try: if anchor and self.config.linkcheck_anchors: # Read the whole document and see if #anchor exists - response = requests.get(req_url, stream=True, config=self.config, - auth=auth_info, **kwargs) - response.close() # no HTTP body reads required; close the response - response.raise_for_status() - found = check_anchor(response, unquote(anchor)) - - if not found: - raise Exception(__("Anchor '%s' not found") % anchor) + with requests.get(req_url, stream=True, config=self.config, auth=auth_info, + **kwargs) as response: + response.raise_for_status() + found = check_anchor(response, unquote(anchor)) + + if not found: + raise Exception(__("Anchor '%s' not found") % anchor) else: try: # try a HEAD request first, which should be easier on # the server and the network - response = requests.head(req_url, allow_redirects=True, - config=self.config, auth=auth_info, - **kwargs) - response.raise_for_status() + with requests.head(req_url, allow_redirects=True, config=self.config, + auth=auth_info, **kwargs) as response: + response.raise_for_status() # Servers drop the connection on HEAD requests, causing # ConnectionError. except (ConnectionError, HTTPError, TooManyRedirects) as err: @@ -339,11 +337,9 @@ def check_uri() -> tuple[str, str, int]: raise # retry with GET request if that fails, some servers # don't like HEAD requests. - response = requests.get(req_url, stream=True, - config=self.config, - auth=auth_info, **kwargs) - response.close() # no HTTP body reads required; close the response - response.raise_for_status() + with requests.get(req_url, stream=True, config=self.config, + auth=auth_info, **kwargs) as response: + response.raise_for_status() except HTTPError as err: if err.response.status_code == 401: # We'll take "Unauthorized" as working.