Skip to content

Commit

Permalink
Fix the TypeError exception in the images.prune method
Browse files Browse the repository at this point in the history
If the prune doesn't remove images,
the API returns "null" (with 200) and it's interpreted as
None (NoneType) so the for loop throws:
"TypeError: 'NoneType' object is not iterable".

My fix handles the above described case and the
client.images.prune() returns a valid Dict with zero
values, which is correct because the Podman didn't
remove anything.

Signed-off-by: Milan Balazs <milanbalazs01@gmail.com>
  • Loading branch information
milanbalazs committed Aug 1, 2024
1 parent 7dbc101 commit 052702c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
26 changes: 15 additions & 11 deletions podman/domain/images_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,21 @@ 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))

Expand Down
12 changes: 12 additions & 0 deletions podman/tests/unit/test_imagesmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ 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",
json=None
)

report = self.client.images.prune()
self.assertEqual(report["ImagesDeleted"], [])
self.assertEqual(report["SpaceReclaimed"], 0)

@requests_mock.Mocker()
def test_get(self, mock):
mock.get(
Expand Down

0 comments on commit 052702c

Please sign in to comment.