@@ -43,7 +43,7 @@ def __init__(self, processes_cls):
43
43
self ._processes_cls = processes_cls
44
44
self ._processes_obj = {k : cls () for k , cls in processes_cls .items ()}
45
45
46
- self ._reverse_lookup = { cls : k for k , cls in processes_cls . items ()}
46
+ self ._reverse_lookup = self . _get_reverse_lookup ( processes_cls )
47
47
48
48
self ._input_vars = None
49
49
@@ -53,6 +53,24 @@ def __init__(self, processes_cls):
53
53
# a cache for group keys
54
54
self ._group_keys = {}
55
55
56
+ def _get_reverse_lookup (self , processes_cls ):
57
+ """Return a dictionary with process classes as keys and process names
58
+ as values.
59
+
60
+ Additionally, the returned dictionary maps all parent classes
61
+ to one (str) or several (list) process names.
62
+
63
+ """
64
+ reverse_lookup = defaultdict (list )
65
+
66
+ for p_name , p_cls in processes_cls .items ():
67
+ # exclude `object` base class from lookup
68
+ for cls in p_cls .mro ()[:- 1 ]:
69
+ reverse_lookup [cls ].append (p_name )
70
+
71
+ return {k : v [0 ] if len (v ) == 1 else v
72
+ for k , v in reverse_lookup .items ()}
73
+
56
74
def bind_processes (self , model_obj ):
57
75
for p_name , p_obj in self ._processes_obj .items ():
58
76
p_obj .__xsimlab_model__ = model_obj
@@ -92,6 +110,17 @@ def _get_var_key(self, p_name, var):
92
110
.format (target_p_cls .__name__ , var .name , p_name )
93
111
)
94
112
113
+ elif isinstance (target_p_name , list ):
114
+ raise ValueError (
115
+ "Process class {!r} required by foreign variable '{}.{}' "
116
+ "is used (possibly via one its child classes) by multiple "
117
+ "processes: {}"
118
+ .format (
119
+ target_p_cls .__name__ , p_name , var .name ,
120
+ ', ' .join (['{!r}' .format (n ) for n in target_p_name ])
121
+ )
122
+ )
123
+
95
124
store_key , od_key = self ._get_var_key (target_p_name , target_var )
96
125
97
126
elif var_type == VarType .GROUP :
0 commit comments