Normalize ``plugins`` entries to Plugin instances. Auto-instantiates Plugin subclasses passed without parentheses (e.g. ``plugins=[SitemapPlugin]``) so they behave the same as ``plugins=[SitemapPlugin()]``. Any entry that is neither a Plugin subclass nor a Plugin ins
(self)
| 410 | raise ConfigError(msg) |
| 411 | |
| 412 | def _normalize_plugins(self): |
| 413 | """Normalize ``plugins`` entries to Plugin instances. |
| 414 | |
| 415 | Auto-instantiates Plugin subclasses passed without parentheses (e.g. |
| 416 | ``plugins=[SitemapPlugin]``) so they behave the same as |
| 417 | ``plugins=[SitemapPlugin()]``. Any entry that is neither a Plugin |
| 418 | subclass nor a Plugin instance raises ``ConfigError`` with a message |
| 419 | that names the offending value, instead of failing later in the |
| 420 | compiler with a confusing ``TypeError`` about a missing ``self``. |
| 421 | |
| 422 | An ``_InvalidPlugin`` (produced when a ``REFLEX_PLUGINS`` import path |
| 423 | cannot be resolved) is fatal here: ``plugins`` is an explicit list of |
| 424 | plugins the app needs, so a bad entry raises ``InvalidPluginConfigError`` |
| 425 | and the app cannot start. |
| 426 | |
| 427 | Raises: |
| 428 | ConfigError: If an entry is neither a Plugin instance nor subclass. |
| 429 | InvalidPluginConfigError: If an entry could not be loaded. |
| 430 | """ |
| 431 | normalized: list[Plugin] = [] |
| 432 | invalid: list[_InvalidPlugin] = [] |
| 433 | for entry in self.plugins: |
| 434 | if isinstance(entry, _InvalidPlugin): |
| 435 | invalid.append(entry) |
| 436 | elif isinstance(entry, Plugin): |
| 437 | normalized.append(entry) |
| 438 | elif isinstance(entry, type) and issubclass(entry, Plugin): |
| 439 | try: |
| 440 | normalized.append(entry()) |
| 441 | except TypeError as exc: |
| 442 | msg = ( |
| 443 | f"reflex.Config.plugins entry {entry.__name__!r} could not be " |
| 444 | f"instantiated and may require arguments; pass an instance " |
| 445 | f"instead, e.g. plugins=[{entry.__name__}(...)]." |
| 446 | ) |
| 447 | raise InvalidPluginConfigError(msg) from exc |
| 448 | else: |
| 449 | msg = ( |
| 450 | f"reflex.Config.plugins must contain Plugin instances, but got " |
| 451 | f"{entry!r} of type {type(entry).__name__}. " |
| 452 | f"Pass an instance, e.g. plugins=[SitemapPlugin()]." |
| 453 | ) |
| 454 | raise InvalidPluginConfigError(msg) |
| 455 | if invalid: |
| 456 | details = ", ".join(p.describe() for p in invalid) |
| 457 | msg = ( |
| 458 | f"reflex.Config.plugins contains plugin(s) that could not be loaded " |
| 459 | f"(check REFLEX_PLUGINS import paths): {details}." |
| 460 | ) |
| 461 | raise InvalidPluginConfigError(msg) |
| 462 | self.plugins = normalized |
| 463 | |
| 464 | def _add_extra_plugins(self): |
| 465 | """Append plugins declared via the ``REFLEX_EXTRA_PLUGINS`` env var. |
no test coverage detected