Collects the values of the config attributes that are used by the plugin, accounting for parent classes.
(self)
| 549 | sym.node.func.is_class = True |
| 550 | |
| 551 | def collect_config(self) -> ModelConfigData: # noqa: C901 (ignore complexity) |
| 552 | """Collects the values of the config attributes that are used by the plugin, accounting for parent classes.""" |
| 553 | cls = self._cls |
| 554 | config = ModelConfigData() |
| 555 | |
| 556 | has_config_kwargs = False |
| 557 | has_config_from_namespace = False |
| 558 | |
| 559 | # Handle `class MyModel(BaseModel, <name>=<expr>, ...):` |
| 560 | for name, expr in cls.keywords.items(): |
| 561 | config_data = self.get_config_update(name, expr) |
| 562 | if config_data: |
| 563 | has_config_kwargs = True |
| 564 | config.update(config_data) |
| 565 | |
| 566 | # Handle `model_config` |
| 567 | stmt: Statement | None = None |
| 568 | for stmt in cls.defs.body: |
| 569 | if not isinstance(stmt, (AssignmentStmt, ClassDef)): |
| 570 | continue |
| 571 | |
| 572 | if isinstance(stmt, AssignmentStmt): |
| 573 | lhs = stmt.lvalues[0] |
| 574 | if not isinstance(lhs, NameExpr) or lhs.name != 'model_config': |
| 575 | continue |
| 576 | |
| 577 | if isinstance(stmt.rvalue, CallExpr): # calls to `dict` or `ConfigDict` |
| 578 | for arg_name, arg in zip(stmt.rvalue.arg_names, stmt.rvalue.args): |
| 579 | if arg_name is None: |
| 580 | continue |
| 581 | config.update(self.get_config_update(arg_name, arg, lax_extra=True)) |
| 582 | elif isinstance(stmt.rvalue, DictExpr): # dict literals |
| 583 | for key_expr, value_expr in stmt.rvalue.items: |
| 584 | if not isinstance(key_expr, StrExpr): |
| 585 | continue |
| 586 | config.update(self.get_config_update(key_expr.value, value_expr)) |
| 587 | |
| 588 | elif isinstance(stmt, ClassDef): |
| 589 | if stmt.name != 'Config': # 'deprecated' Config-class |
| 590 | continue |
| 591 | for substmt in stmt.defs.body: |
| 592 | if not isinstance(substmt, AssignmentStmt): |
| 593 | continue |
| 594 | lhs = substmt.lvalues[0] |
| 595 | if not isinstance(lhs, NameExpr): |
| 596 | continue |
| 597 | config.update(self.get_config_update(lhs.name, substmt.rvalue)) |
| 598 | |
| 599 | if has_config_kwargs: |
| 600 | self._api.fail( |
| 601 | 'Specifying config in two places is ambiguous, use either Config attribute or class kwargs', |
| 602 | cls, |
| 603 | ) |
| 604 | break |
| 605 | |
| 606 | has_config_from_namespace = True |
| 607 | |
| 608 | if has_config_kwargs or has_config_from_namespace: |
no test coverage detected