Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/builtin_trap.py: 41%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

54 statements  

1""" 

2A context manager for managing things injected into :mod:`builtins`. 

3""" 

4# Copyright (c) IPython Development Team. 

5# Distributed under the terms of the Modified BSD License. 

6from __future__ import annotations 

7 

8import builtins as builtin_mod 

9from typing import Any, Literal, TYPE_CHECKING 

10 

11from traitlets.config.configurable import Configurable 

12 

13from traitlets import Instance 

14 

15if TYPE_CHECKING: 

16 from types import TracebackType 

17 

18 

19class __BuiltinUndefined: 

20 pass 

21 

22 

23BuiltinUndefined = __BuiltinUndefined() 

24 

25 

26class __HideBuiltin: 

27 pass 

28 

29 

30HideBuiltin = __HideBuiltin() 

31 

32 

33class BuiltinTrap(Configurable): 

34 

35 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', 

36 allow_none=True) 

37 

38 def __init__(self, shell: Any = None) -> None: 

39 super().__init__(shell=shell, config=None) 

40 self._orig_builtins: dict[str, Any] = {} 

41 # We define this to track if a single BuiltinTrap is nested. 

42 # Only turn off the trap when the outermost call to __exit__ is made. 

43 self._nested_level = 0 

44 self.shell = shell 

45 # builtins we always add - if set to HideBuiltin, they will just 

46 # be removed instead of being replaced by something else 

47 self.auto_builtins: dict[str, Any] = { 

48 'exit': HideBuiltin, 

49 'quit': HideBuiltin, 

50 'get_ipython': self.shell.get_ipython, 

51 } 

52 

53 def __enter__(self) -> BuiltinTrap: 

54 if self._nested_level == 0: 

55 self.activate() 

56 self._nested_level += 1 

57 # I return self, so callers can use add_builtin in a with clause. 

58 return self 

59 

60 def __exit__(self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None) -> Literal[False]: 

61 if self._nested_level == 1: 

62 self.deactivate() 

63 self._nested_level -= 1 

64 # Returning False will cause exceptions to propagate 

65 return False 

66 

67 def add_builtin(self, key: str, value: Any) -> None: 

68 """Add a builtin and save the original.""" 

69 bdict = builtin_mod.__dict__ 

70 orig = bdict.get(key, BuiltinUndefined) 

71 if value is HideBuiltin: 

72 if orig is not BuiltinUndefined: #same as 'key in bdict' 

73 self._orig_builtins[key] = orig 

74 del bdict[key] 

75 else: 

76 self._orig_builtins[key] = orig 

77 bdict[key] = value 

78 

79 def remove_builtin(self, key: str, orig: Any) -> None: 

80 """Remove an added builtin and re-set the original.""" 

81 if orig is BuiltinUndefined: 

82 del builtin_mod.__dict__[key] 

83 else: 

84 builtin_mod.__dict__[key] = orig 

85 

86 def activate(self) -> None: 

87 """Store ipython references in the __builtin__ namespace.""" 

88 

89 add_builtin = self.add_builtin 

90 for name, func in self.auto_builtins.items(): 

91 add_builtin(name, func) 

92 

93 def deactivate(self) -> None: 

94 """Remove any builtins which might have been added by add_builtins, or 

95 restore overwritten ones to their previous values.""" 

96 remove_builtin = self.remove_builtin 

97 for key, val in self._orig_builtins.items(): 

98 remove_builtin(key, val) 

99 self._orig_builtins.clear()