|
5 | 5 |
|
6 | 6 | from __future__ import annotations |
7 | 7 |
|
8 | | -from typing import TYPE_CHECKING, Generic, TypeVar, overload |
| 8 | +from inspect import isclass |
| 9 | +from typing import TYPE_CHECKING, Callable, Generic, TypeVar, overload |
9 | 10 |
|
10 | 11 | from textual._context import NoActiveAppError, active_app |
11 | 12 | from textual.css.query import NoMatches, QueryType, WrongType |
|
23 | 24 | class app(Generic[AppType]): |
24 | 25 | """Create a property to return the active app. |
25 | 26 |
|
| 27 | + All widgets have a default `app` property which returns an App instance. |
| 28 | + Type checkers will complain if you try to access attributes defined on your App class, which aren't |
| 29 | + present in the base class. To keep the type checker happy you can add this property to get your |
| 30 | + specific App subclass. |
| 31 | +
|
26 | 32 | Example: |
27 | 33 | ```python |
28 | 34 | class MyWidget(Widget): |
29 | 35 | app = getters.app(MyApp) |
30 | 36 | ``` |
31 | 37 |
|
32 | 38 | Args: |
33 | | - app_type: The app class. |
| 39 | + app_type: The App subclass, or a callable which returns an App subclass. |
34 | 40 | """ |
35 | 41 |
|
36 | | - def __init__(self, app_type: type[AppType]) -> None: |
37 | | - self._app_type = app_type |
| 42 | + def __init__(self, app_type: type[AppType] | Callable[[], type[AppType]]) -> None: |
| 43 | + self._app_type = app_type if isclass(app_type) else app_type() |
38 | 44 |
|
39 | 45 | def __get__(self, obj: MessagePump, obj_type: type[MessagePump]) -> AppType: |
40 | 46 | try: |
|
0 commit comments