diff --git a/src/taskgraph/util/taskcluster.py b/src/taskgraph/util/taskcluster.py index a8e6e2e6f..cec8a8f0e 100644 --- a/src/taskgraph/util/taskcluster.py +++ b/src/taskgraph/util/taskcluster.py @@ -73,15 +73,17 @@ def get_taskcluster_client(service: str): def _handle_artifact( path: str, response: Union[requests.Response, dict[str, Any]] ) -> Any: - if isinstance(response, dict): - # When taskcluster client returns non-JSON responses, it wraps them in {"response": } - if "response" in response and isinstance( - response["response"], requests.Response - ): - response = response["response"] - else: - # If we already a dict (parsed JSON), return it directly. - return response + # When taskcluster client returns non-JSON responses, it wraps them in {"response": } + if ( + isinstance(response, dict) + and "response" in response + and isinstance(response["response"], requests.Response) + ): + response = response["response"] + + if not isinstance(response, requests.Response): + # At this point, if we don't have a response object, it's already parsed, return it + return response # We have a response object, load the content based on the path extension. if path.endswith(".json"): diff --git a/test/test_util_taskcluster.py b/test/test_util_taskcluster.py index 6f98a0df4..d6e97aaa2 100644 --- a/test/test_util_taskcluster.py +++ b/test/test_util_taskcluster.py @@ -124,6 +124,17 @@ def test_get_artifact(responses, root_url): result = tc.get_artifact(tid, "artifact.json") assert result == {"foo": "bar"} + # Test JSON artifact that isn't a dict (bug 1997236) + responses.get("http://foo.bar/artifact.json", json=[1, 2, 3]) + responses.get( + f"{root_url}/api/queue/v1/task/{tid}/artifacts/artifact.json", + body=b'{"type": "s3", "url": "http://foo.bar/artifact.json"}', + status=303, + headers={"Location": "http://foo.bar/artifact.json"}, + ) + result = tc.get_artifact(tid, "artifact.json") + assert result == [1, 2, 3] + # Test YAML artifact expected_result = {"foo": b"\xe2\x81\x83".decode()} responses.get(