1# encoding: utf-8
2"""Decorators that don't go anywhere else.
3
4This module contains misc. decorators that don't really go with another module
5in :mod:`IPython.utils`. Before putting something here please see if it should
6go into another topical module in :mod:`IPython.utils`.
7"""
8
9#-----------------------------------------------------------------------------
10# Copyright (C) 2008-2011 The IPython Development Team
11#
12# Distributed under the terms of the BSD License. The full license is in
13# the file COPYING, distributed as part of this software.
14#-----------------------------------------------------------------------------
15
16#-----------------------------------------------------------------------------
17# Imports
18#-----------------------------------------------------------------------------
19from __future__ import annotations
20
21from collections.abc import Callable, Sequence
22from typing import Any, TypeVar
23
24from IPython.utils.docs import GENERATING_DOCUMENTATION
25
26F = TypeVar("F", bound=Callable[..., Any])
27
28#-----------------------------------------------------------------------------
29# Code
30#-----------------------------------------------------------------------------
31
32def flag_calls(func: Callable[..., Any]) -> Callable[..., Any]:
33 """Wrap a function to detect and flag when it gets called.
34
35 This is a decorator which takes a function and wraps it in a function with
36 a 'called' attribute. wrapper.called is initialized to False.
37
38 The wrapper.called attribute is set to False right before each call to the
39 wrapped function, so if the call fails it remains False. After the call
40 completes, wrapper.called is set to True and the output is returned.
41
42 Testing for truth in wrapper.called allows you to determine if a call to
43 func() was attempted and succeeded."""
44
45 # don't wrap twice
46 if hasattr(func, 'called'):
47 return func
48
49 def wrapper(*args: Any, **kw: Any) -> Any:
50 wrapper.called = False # type: ignore[attr-defined]
51 out = func(*args, **kw)
52 wrapper.called = True # type: ignore[attr-defined]
53 return out
54
55 wrapper.called = False # type: ignore[attr-defined]
56 wrapper.__doc__ = func.__doc__
57 return wrapper
58
59
60def undoc(func: F) -> F:
61 """Mark a function or class as undocumented.
62
63 This is found by inspecting the AST, so for now it must be used directly
64 as @undoc, not as e.g. @decorators.undoc
65 """
66 return func
67
68
69def sphinx_options(
70 show_inheritance: bool = True,
71 show_inherited_members: bool = False,
72 exclude_inherited_from: Sequence[str] = tuple(),
73) -> Callable[[F], F]:
74 """Set sphinx options"""
75
76 def wrapper(func: F) -> F:
77 if not GENERATING_DOCUMENTATION:
78 return func
79
80 func._sphinx_options = dict( # type: ignore[attr-defined]
81 show_inheritance=show_inheritance,
82 show_inherited_members=show_inherited_members,
83 exclude_inherited_from=exclude_inherited_from,
84 )
85 return func
86
87 return wrapper