Skip to content

Commit

Permalink
Nested lists of models work... At what cost?
Browse files Browse the repository at this point in the history
  • Loading branch information
morington committed Jul 1, 2024
1 parent 2aadf7b commit c814e4e
Showing 1 changed file with 50 additions and 8 deletions.
58 changes: 50 additions & 8 deletions confhub/builder.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import List, Any, Dict, Optional
from typing import List, Any, Dict, Optional, Type

import yaml
import structlog
Expand All @@ -22,9 +22,23 @@ def generate_filenames(self) -> Dict[str, Any]:

def data_typing(field: ConfigurationField) -> Any:
if field.is_list:
return [field.get_default_value()]

return field.get_default_value()
if isinstance(field.data_type, BlockCore):
nested_block = {}
for nested_field_name, nested_field in field.data_type.__class__.__dict__.items():
if isinstance(nested_field, ConfigurationField):
nested_block[nested_field_name] = data_typing(nested_field)
return [nested_block]
else:
return [field.get_default_value()]
else:
if isinstance(field.data_type, BlockCore):
nested_block = {}
for nested_field_name, nested_field in field.data_type.__class__.__dict__.items():
if isinstance(nested_field, ConfigurationField):
nested_block[nested_field_name] = data_typing(nested_field)
return nested_block
else:
return field.get_default_value()

def add_field_to_datafiles(
field_name: str, field: ConfigurationField, parent_path: List[str]
Expand All @@ -44,7 +58,31 @@ def add_field_to_datafiles(
current[part] = {}
current = current[part]

current[field_name] = data_typing(field)
def new_nested(nested_model: Type[BlockCore]):
nested_block = {nested_model.__block__: {}}
for nested_field_name, nested_field in nested_model.__dict__.items():
if isinstance(nested_field, ConfigurationField):
if isinstance(nested_field.data_type, BlockCore):
nested_block[nested_model.__block__][nested_field_name] = [new_nested(nested_field.data_type.__class__)]
else:
nested_block[nested_model.__block__][nested_field_name] = data_typing(nested_field)
elif isinstance(nested_field, BlockCore):
nested_block[nested_model.__block__][nested_field_name] = [new_nested(nested_field.__class__)]
return nested_block

if field.is_list and isinstance(field.data_type, BlockCore):
data = new_nested(field.data_type.__class__)
current[field_name] = [data]
elif field.is_list:
current[field_name] = [field.get_default_value()]
elif isinstance(field.data_type, BlockCore):
nested_block = {}
for nested_field_name, nested_field in field.data_type.__class__.__dict__.items():
if isinstance(nested_field, ConfigurationField):
nested_block[nested_field_name] = data_typing(nested_field)
current[field_name] = nested_block
else:
current[field_name] = field.get_default_value()

def has_configuration_fields(select_class: BlockCore) -> bool:
if any(isinstance(item, ConfigurationField) for item in [
Expand All @@ -67,11 +105,15 @@ def process_block(_block: BlockCore, parent_path: List[str], parent: str = None)
if parent:
current_path += [_block.__block__]

# field.is_list
for field_name, field in (_block.__dict__.items() if has_configuration_fields(_block) else _block.__class__.__dict__.items()):
if isinstance(field, ConfigurationField):
if isinstance(field.data_type, BlockCore):
process_block(field.data_type, current_path, parent=field_name)
if field.is_list:
add_field_to_datafiles(field_name, field, current_path)
process_block(field.data_type, current_path + [field_name])
else:
add_field_to_datafiles(field_name, field, current_path)
process_block(field.data_type, current_path, parent=field_name)
else:
add_field_to_datafiles(field_name, field, current_path)
elif isinstance(field, BlockCore):
Expand Down Expand Up @@ -106,4 +148,4 @@ def create_files(self, config_path: Path) -> None:
if filename.startswith('.'):
add_to_gitignore(f"{filename}.*")

logger.info("Create file", path=file_path)
logger.info("Create file", path=file_path)

0 comments on commit c814e4e

Please sign in to comment.