Build the outputs spec, expanding wildcards to concrete IDs. For wildcard outputs, derives concrete IDs from the resolved inputs. The browser does the same: input and output wildcards resolve against the same set of matching components.
(
output_id: str,
cb_info: dict,
resolved_inputs: list[CallbackInputs],
)
| 383 | |
| 384 | |
| 385 | def _expand_output_spec( |
| 386 | output_id: str, |
| 387 | cb_info: dict, |
| 388 | resolved_inputs: list[CallbackInputs], |
| 389 | ) -> CallbackOutputTarget | list[CallbackOutputTarget]: |
| 390 | """Build the outputs spec, expanding wildcards to concrete IDs. |
| 391 | |
| 392 | For wildcard outputs, derives concrete IDs from the resolved inputs. |
| 393 | The browser does the same: input and output wildcards resolve against |
| 394 | the same set of matching components. |
| 395 | """ |
| 396 | if cb_info.get("no_output"): |
| 397 | return [] |
| 398 | |
| 399 | parsed = split_callback_id(output_id) |
| 400 | if isinstance(parsed, dict): |
| 401 | parsed = [parsed] |
| 402 | |
| 403 | results: list[CallbackOutputTarget] = [] |
| 404 | for p in parsed: |
| 405 | pid = p["id"] |
| 406 | prop = clean_property_name(p["property"]) |
| 407 | pattern = parse_wildcard_id(pid) |
| 408 | if pattern is not None: |
| 409 | concrete_ids = _derive_output_ids(pattern, resolved_inputs) |
| 410 | if not concrete_ids: |
| 411 | concrete_ids = [ |
| 412 | getattr(comp, "id") for comp in find_matching_components(pattern) |
| 413 | ] |
| 414 | expanded: list[CallbackDependency] = [ |
| 415 | CallbackDependency(id=cid, property=prop) for cid in concrete_ids |
| 416 | ] |
| 417 | # ALL/ALLSMALLER → nested list; MATCH → single dict |
| 418 | if len(expanded) == 1: |
| 419 | results.append(expanded[0]) |
| 420 | else: |
| 421 | results.append(expanded) |
| 422 | else: |
| 423 | results.append(CallbackDependency(id=pid, property=prop)) |
| 424 | |
| 425 | # Mirror the Dash renderer: single-output callbacks send a bare dict, |
| 426 | # multi-output callbacks send a list. The framework's output value |
| 427 | # matching depends on this shape. |
| 428 | if len(results) == 1: |
| 429 | return results[0] |
| 430 | return results |
| 431 | |
| 432 | |
| 433 | def _derive_output_ids( |
no test coverage detected
searching dependent graphs…