]>
Commit | Line | Data |
---|---|---|
1 | import typing as t | |
2 | from threading import local | |
3 | ||
4 | if t.TYPE_CHECKING: | |
5 | import typing_extensions as te | |
6 | from .core import Context | |
7 | ||
8 | _local = local() | |
9 | ||
10 | ||
11 | @t.overload | |
12 | def get_current_context(silent: "te.Literal[False]" = False) -> "Context": | |
13 | ... | |
14 | ||
15 | ||
16 | @t.overload | |
17 | def get_current_context(silent: bool = ...) -> t.Optional["Context"]: | |
18 | ... | |
19 | ||
20 | ||
21 | def get_current_context(silent: bool = False) -> t.Optional["Context"]: | |
22 | """Returns the current click context. This can be used as a way to | |
23 | access the current context object from anywhere. This is a more implicit | |
24 | alternative to the :func:`pass_context` decorator. This function is | |
25 | primarily useful for helpers such as :func:`echo` which might be | |
26 | interested in changing its behavior based on the current context. | |
27 | ||
28 | To push the current context, :meth:`Context.scope` can be used. | |
29 | ||
30 | .. versionadded:: 5.0 | |
31 | ||
32 | :param silent: if set to `True` the return value is `None` if no context | |
33 | is available. The default behavior is to raise a | |
34 | :exc:`RuntimeError`. | |
35 | """ | |
36 | try: | |
37 | return t.cast("Context", _local.stack[-1]) | |
38 | except (AttributeError, IndexError) as e: | |
39 | if not silent: | |
40 | raise RuntimeError("There is no active click context.") from e | |
41 | ||
42 | return None | |
43 | ||
44 | ||
45 | def push_context(ctx: "Context") -> None: | |
46 | """Pushes a new context to the current stack.""" | |
47 | _local.__dict__.setdefault("stack", []).append(ctx) | |
48 | ||
49 | ||
50 | def pop_context() -> None: | |
51 | """Removes the top level from the stack.""" | |
52 | _local.stack.pop() | |
53 | ||
54 | ||
55 | def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: | |
56 | """Internal helper to get the default value of the color flag. If a | |
57 | value is passed it's returned unchanged, otherwise it's looked up from | |
58 | the current context. | |
59 | """ | |
60 | if color is not None: | |
61 | return color | |
62 | ||
63 | ctx = get_current_context(silent=True) | |
64 | ||
65 | if ctx is not None: | |
66 | return ctx.color | |
67 | ||
68 | return None |