Skip to content

Commit 0f821cf

Browse files
committed
Refactor range expansion logic to a standalone function for improved reusability and clarity
1 parent f08610c commit 0f821cf

File tree

1 file changed

+42
-36
lines changed

1 file changed

+42
-36
lines changed

infrahub_sdk/spec/object.py

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -167,44 +167,45 @@ async def get_relationship_info(
167167
return info
168168

169169

170-
class InfrahubObjectFileData(BaseModel):
171-
def expand_data_with_ranges(self) -> list[dict[str, Any]]:
172-
"""Expand any item in self.data with range pattern in any value. Supports multiple fields, requires equal expansion length."""
173-
range_pattern = re.compile(MATCH_PATTERN)
174-
expanded = []
175-
for item in self.data:
176-
# Find all fields to expand
177-
expand_fields = {}
178-
for key, value in item.items():
179-
if isinstance(value, str) and range_pattern.search(value):
180-
try:
181-
expand_fields[key] = range_expansion(value)
182-
except Exception:
183-
# If expansion fails, treat as no expansion
184-
expand_fields[key] = [value]
185-
if not expand_fields:
186-
expanded.append(item)
187-
continue
188-
# Check all expanded lists have the same length
189-
lengths = [len(v) for v in expand_fields.values()]
190-
if len(set(lengths)) > 1:
191-
raise ValidationError(f"Range expansion mismatch: fields expanded to different lengths: {lengths}")
192-
n = lengths[0]
193-
# Zip expanded values and produce new items
194-
for i in range(n):
195-
new_item = copy.deepcopy(item)
196-
for key, values in expand_fields.items():
197-
new_item[key] = values[i]
198-
expanded.append(new_item)
199-
return expanded
170+
def expand_data_with_ranges(data: list[dict[str, Any]]) -> list[dict[str, Any]]:
171+
"""Expand any item in self.data with range pattern in any value. Supports multiple fields, requires equal expansion length."""
172+
range_pattern = re.compile(MATCH_PATTERN)
173+
expanded = []
174+
for item in data:
175+
# Find all fields to expand
176+
expand_fields = {}
177+
for key, value in item.items():
178+
if isinstance(value, str) and range_pattern.search(value):
179+
try:
180+
expand_fields[key] = range_expansion(value)
181+
except Exception:
182+
# If expansion fails, treat as no expansion
183+
expand_fields[key] = [value]
184+
if not expand_fields:
185+
expanded.append(item)
186+
continue
187+
# Check all expanded lists have the same length
188+
lengths = [len(v) for v in expand_fields.values()]
189+
if len(set(lengths)) > 1:
190+
raise ValidationError(f"Range expansion mismatch: fields expanded to different lengths: {lengths}")
191+
n = lengths[0]
192+
# Zip expanded values and produce new items
193+
for i in range(n):
194+
new_item = copy.deepcopy(item)
195+
for key, values in expand_fields.items():
196+
new_item[key] = values[i]
197+
expanded.append(new_item)
198+
return expanded
199+
200200

201+
class InfrahubObjectFileData(BaseModel):
201202
kind: str
202203
data: list[dict[str, Any]] = Field(default_factory=list)
203204

204205
async def validate_format(self, client: InfrahubClient, branch: str | None = None) -> list[ObjectValidationError]:
205206
errors: list[ObjectValidationError] = []
206207
schema = await client.schema.get(kind=self.kind, branch=branch)
207-
expanded_data = self.expand_data_with_ranges()
208+
expanded_data = expand_data_with_ranges(self.data)
208209
self.data = expanded_data
209210
for idx, item in enumerate(expanded_data):
210211
errors.extend(
@@ -221,7 +222,7 @@ async def validate_format(self, client: InfrahubClient, branch: str | None = Non
221222

222223
async def process(self, client: InfrahubClient, branch: str | None = None) -> None:
223224
schema = await client.schema.get(kind=self.kind, branch=branch)
224-
expanded_data = self.expand_data_with_ranges()
225+
expanded_data = expand_data_with_ranges(self.data)
225226
for idx, item in enumerate(expanded_data):
226227
await self.create_node(
227228
client=client,
@@ -347,7 +348,8 @@ async def validate_related_nodes(
347348
rel_info.find_matching_relationship(peer_schema=peer_schema)
348349
context.update(rel_info.get_context(value="placeholder"))
349350

350-
for idx, peer_data in enumerate(data["data"]):
351+
extended_data = expand_data_with_ranges(data=data["data"])
352+
for idx, peer_data in enumerate(extended_data):
351353
context["list_index"] = idx
352354
errors.extend(
353355
await cls.validate_object(
@@ -457,22 +459,24 @@ async def create_node(
457459
remaining_rels.append(key)
458460
elif not rel_info.is_reference and not rel_info.is_mandatory:
459461
if rel_info.format == RelationshipDataFormat.ONE_OBJ:
462+
expanded_data = expand_data_with_ranges(data=[value])
460463
nodes = await cls.create_related_nodes(
461464
client=client,
462465
position=position,
463466
rel_info=rel_info,
464-
data=value,
467+
data=expanded_data,
465468
branch=branch,
466469
default_schema_kind=default_schema_kind,
467470
)
468471
clean_data[key] = nodes[0]
469472

470473
else:
474+
expanded_data = expand_data_with_ranges(data=value)
471475
nodes = await cls.create_related_nodes(
472476
client=client,
473477
position=position,
474478
rel_info=rel_info,
475-
data=value,
479+
data=expanded_data,
476480
branch=branch,
477481
default_schema_kind=default_schema_kind,
478482
)
@@ -561,7 +565,9 @@ async def create_related_nodes(
561565
rel_info.find_matching_relationship(peer_schema=peer_schema)
562566
context.update(rel_info.get_context(value=parent_node.id))
563567

564-
for idx, peer_data in enumerate(data["data"]):
568+
expanded_data = expand_data_with_ranges(data=data["data"])
569+
570+
for idx, peer_data in enumerate(expanded_data):
565571
context["list_index"] = idx
566572
if isinstance(peer_data, dict):
567573
node = await cls.create_node(

0 commit comments

Comments
 (0)