Skip to content

Commit 4720868

Browse files
authored
Merge pull request #1480 from guillermodotn/main
fix: coerce depends_on list to dict in rec_merge_one when types differ
2 parents 09bd676 + 96a2043 commit 4720868

3 files changed

Lines changed: 101 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed ``ValueError: can't merge value of depends_on`` when using ``extends`` with mixed list and dict ``depends_on`` forms.

podman_compose.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,6 +2187,14 @@ def rec_merge_one(target: dict[str, Any], source: dict[str, Any]) -> dict[str, A
21872187
if value is None and isinstance(value2, dict):
21882188
target[key] = value = {}
21892189

2190+
# normalizing inputs to dicts
2191+
if key == "depends_on":
2192+
if is_list(value) and isinstance(value2, dict):
2193+
value = {x: {} for x in value}
2194+
target[key] = value
2195+
elif isinstance(value, dict) and is_list(value2):
2196+
value2 = {x: {} for x in value2}
2197+
21902198
if not isinstance(value2, type(value)):
21912199
value_type = type(value)
21922200
value2_type = type(value2)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
from __future__ import annotations
3+
4+
import unittest
5+
from typing import Any
6+
7+
from parameterized import parameterized
8+
9+
from podman_compose import rec_merge
10+
11+
12+
class TestRecMergeDependsOn(unittest.TestCase):
13+
"""Test rec_merge with mixed list/dict depends_on."""
14+
15+
@parameterized.expand([
16+
(
17+
"dict_target_list_source",
18+
{"depends_on": {"db": {"condition": "service_healthy"}}},
19+
{"depends_on": ["redis"]},
20+
{
21+
"depends_on": {
22+
"db": {"condition": "service_healthy"},
23+
"redis": {},
24+
},
25+
},
26+
),
27+
(
28+
"list_target_dict_source",
29+
{"depends_on": ["db", "redis"]},
30+
{"depends_on": {"cache": {"condition": "service_started"}}},
31+
{
32+
"depends_on": {
33+
"db": {},
34+
"redis": {},
35+
"cache": {"condition": "service_started"},
36+
},
37+
},
38+
),
39+
(
40+
"dict_target_list_source_overlapping_keys",
41+
{"depends_on": {"db": {"condition": "service_healthy"}}},
42+
{"depends_on": ["db", "redis"]},
43+
{
44+
"depends_on": {
45+
"db": {"condition": "service_healthy"},
46+
"redis": {},
47+
},
48+
},
49+
),
50+
(
51+
"list_target_dict_source_overlapping_keys",
52+
{"depends_on": ["db", "redis"]},
53+
{"depends_on": {"db": {"condition": "service_healthy"}}},
54+
{
55+
"depends_on": {
56+
"db": {"condition": "service_healthy"},
57+
"redis": {},
58+
},
59+
},
60+
),
61+
])
62+
def test_rec_merge_depends_on(
63+
self,
64+
name: str,
65+
target: dict[str, Any],
66+
source: dict[str, Any],
67+
expected: dict[str, Any],
68+
) -> None:
69+
result = rec_merge(target, source)
70+
self.assertEqual(result, expected)
71+
72+
def test_three_way_mixed_depends_on(self) -> None:
73+
from_service: dict[str, Any] = {
74+
"image": "myimage:latest",
75+
"depends_on": {"db": {"condition": "service_healthy"}},
76+
}
77+
service: dict[str, Any] = {
78+
"depends_on": ["db", "redis"],
79+
"environment": {"FOO": "bar"},
80+
}
81+
result = rec_merge({}, from_service, service)
82+
self.assertEqual(
83+
result,
84+
{
85+
"image": "myimage:latest",
86+
"depends_on": {
87+
"db": {"condition": "service_healthy"},
88+
"redis": {},
89+
},
90+
"environment": {"FOO": "bar"},
91+
},
92+
)

0 commit comments

Comments
 (0)