diff --git a/podman/domain/images_manager.py b/podman/domain/images_manager.py index 0ebf57c5..8cc3cdbe 100644 --- a/podman/domain/images_manager.py +++ b/podman/domain/images_manager.py @@ -158,17 +158,22 @@ def prune( deleted: List[Dict[str, str]] = [] error: List[str] = [] reclaimed: int = 0 - for element in response.json(): - if "Err" in element and element["Err"] is not None: - error.append(element["Err"]) - else: - reclaimed += element["Size"] - deleted.append( - { - "Deleted": element["Id"], - "Untagged": "", - } - ) + # If the prune doesn't remove images, the API returns "null" + # and it's interpreted as None (NoneType) + # so the for loop throws "TypeError: 'NoneType' object is not iterable". + # The below if condition fixes this issue. + if response.json() is not None: + for element in response.json(): + if "Err" in element and element["Err"] is not None: + error.append(element["Err"]) + else: + reclaimed += element["Size"] + deleted.append( + { + "Deleted": element["Id"], + "Untagged": "", + } + ) if len(error) > 0: raise APIError(response.url, response=response, explanation="; ".join(error)) diff --git a/podman/tests/unit/test_imagesmanager.py b/podman/tests/unit/test_imagesmanager.py index 6de8910f..c51cef8b 100644 --- a/podman/tests/unit/test_imagesmanager.py +++ b/podman/tests/unit/test_imagesmanager.py @@ -223,6 +223,15 @@ def test_prune_failure(self, mock): self.client.images.prune() self.assertEqual(e.exception.explanation, "Test prune failure in response body.") + @requests_mock.Mocker() + def test_prune_empty(self, mock): + """Unit test if prune API responses null (None).""" + mock.post(tests.LIBPOD_URL + "/images/prune", text="null") + + report = self.client.images.prune() + self.assertEqual(report["ImagesDeleted"], []) + self.assertEqual(report["SpaceReclaimed"], 0) + @requests_mock.Mocker() def test_get(self, mock): mock.get(