Coverage for backend/django/flowsheetInternals/unitops/config/variant_families.py: 90%

31 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-07-22 05:22 +0000

1from __future__ import annotations 

2 

3from dataclasses import dataclass 

4from pathlib import Path 

5 

6from .json_loader import JsonUnitOpConfig, UnitOpJsonConfigError 

7 

8 

9@dataclass(frozen=True, slots=True) 

10class UnitOpVariantFamily: 

11 """Variant selector data derived from unit-operation JSON configs.""" 

12 

13 default: str 

14 selector_label: str 

15 variants: tuple[str, ...] 

16 preserve_ports: dict[str, bool] 

17 preserve_graphic: dict[str, bool] 

18 

19 

20def load_unit_op_variant_families_from_json_dir( 

21 path: Path, 

22) -> dict[str, UnitOpVariantFamily]: 

23 """Build model-type variant families from per-unit JSON config files.""" 

24 

25 members_by_family: dict[str, list[JsonUnitOpConfig]] = {} 

26 for config_path in sorted(path.glob("*.json")): 

27 config = JsonUnitOpConfig.model_validate_json(config_path.read_text(encoding="utf-8")) 

28 if config.frontend is None or config.frontend.variant is None: 

29 continue 

30 members_by_family.setdefault(config.frontend.variant.familyKey, []).append(config) 

31 

32 families: dict[str, UnitOpVariantFamily] = {} 

33 for family_key, members in sorted(members_by_family.items()): 

34 selector_labels = { 

35 member.frontend.variant.selectorLabel 

36 for member in members 

37 if member.frontend is not None and member.frontend.variant is not None 

38 } 

39 if len(selector_labels) != 1: 39 ↛ 40line 39 didn't jump to line 40 because the condition on line 39 was never true

40 raise UnitOpJsonConfigError( 

41 f"Variant family {family_key!r} must use exactly one selector label." 

42 ) 

43 

44 defaults = [ 

45 member 

46 for member in members 

47 if member.frontend is not None 

48 and member.frontend.variant is not None 

49 and member.frontend.variant.default 

50 ] 

51 if len(defaults) != 1: 51 ↛ 52line 51 didn't jump to line 52 because the condition on line 51 was never true

52 raise UnitOpJsonConfigError( 

53 f"Variant family {family_key!r} must define exactly one default." 

54 ) 

55 

56 sorted_members = sorted( 

57 members, 

58 key=lambda member: ( 

59 member.frontend.variant.order is None, 

60 member.frontend.variant.order 

61 if member.frontend is not None 

62 and member.frontend.variant is not None 

63 and member.frontend.variant.order is not None 

64 else 0, 

65 member.frontend.variant.label 

66 if member.frontend is not None and member.frontend.variant is not None 

67 else member.displayType, 

68 member.objectType, 

69 ), 

70 ) 

71 families[family_key] = UnitOpVariantFamily( 

72 default=defaults[0].objectType, 

73 selector_label=selector_labels.pop(), 

74 variants=tuple(member.objectType for member in sorted_members), 

75 preserve_ports={ 

76 member.objectType: member.frontend.variant.preservePorts 

77 for member in sorted_members 

78 if member.frontend is not None and member.frontend.variant is not None 

79 }, 

80 preserve_graphic={ 

81 member.objectType: member.frontend.variant.preserveGraphic 

82 for member in sorted_members 

83 if member.frontend is not None and member.frontend.variant is not None 

84 }, 

85 ) 

86 

87 return families 

88 

89 

90def load_unit_op_variant_families() -> dict[str, UnitOpVariantFamily]: 

91 """Load variant families from the conventional unit-operation JSON directory.""" 

92 

93 return load_unit_op_variant_families_from_json_dir(Path(__file__).parent / "objects")