Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/__init__.py: 45%

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

42 statements  

1# PYTHON_ARGCOMPLETE_OK 

2""" 

3IPython: tools for interactive and parallel computing in Python. 

4 

5https://ipython.org 

6""" 

7#----------------------------------------------------------------------------- 

8# Copyright (c) 2008-2011, IPython Development Team. 

9# Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu> 

10# Copyright (c) 2001, Janko Hauser <jhauser@zscout.de> 

11# Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu> 

12# 

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

14# 

15# The full license is in the file COPYING.txt, distributed with this software. 

16#----------------------------------------------------------------------------- 

17 

18#----------------------------------------------------------------------------- 

19# Imports 

20#----------------------------------------------------------------------------- 

21 

22import sys 

23import warnings 

24from typing import Any 

25 

26#----------------------------------------------------------------------------- 

27# Setup everything 

28#----------------------------------------------------------------------------- 

29 

30# Don't forget to also update setup.py when this changes! 

31# 

32# NOTE: these imports look like they could be made lazy (PEP 562) to speed up 

33# `import IPython` considerably, but downstream projects (pyflyby at least) 

34# rely on the transitive side effects: they do `import IPython` and then 

35# access attribute chains like `IPython.terminal.ipapp.TerminalIPythonApp`, 

36# which only resolve because the imports below load those submodules. 

37# 

38# `embed`, `Application` and `get_ipython` are the exceptions, and are 

39# deferred via module `__getattr__` below: 

40# 

41# - `embed` drags in the whole terminal / prompt_toolkit stack, by far 

42# the most expensive of these imports, and is only needed by code that 

43# calls `IPython.embed()`; 

44# - `Application` is only a re-export of `traitlets.config.application 

45# .Application`, but importing it pulled in `IPython.core.application` 

46# and with it the crash handler; no known downstream imports it from 

47# here (ipykernel imports `BaseIPythonApplication` from 

48# `IPython.core.application` directly); 

49# - `get_ipython` costs nothing to defer -- `IPython.core.getipython` 

50# ends up imported anyway via `IPython.core.magic` -- but is kept 

51# alongside the others so all three top-level names resolve the same 

52# way. 

53# 

54# This does mean that code relying on `import IPython` to transitively 

55# populate `IPython.terminal.embed` / `IPython.core.application` (or 

56# submodules only reachable through them) as a side effect will need to 

57# import those submodules explicitly instead. `Application` raises a 

58# `DeprecationWarning` when accessed here, both because such code is worth 

59# spotting and because the name should be imported from traitlets; 

60# `embed` and `get_ipython` stay silent, being widely and legitimately 

61# used from here. 

62from .core import release 

63 

64from .core.interactiveshell import InteractiveShell 

65from .utils.sysinfo import sys_info 

66from .utils.frame import extract_module_locals 

67 

68__all__ = ["start_ipython", "embed", "embed_kernel"] 

69 

70 

71# Nothing below is cached in `globals()`: the lookups stay lazy on every 

72# access, so that the `Application` warning keeps firing instead of only 

73# on the first access, and so that these names never silently turn into 

74# plain module attributes that later code could mistake for eagerly 

75# imported ones. 

76# 

77# `Application` is deliberately absent from `_lazy_attrs`, and hence from 

78# `__dir__`: anything that walks `dir(IPython)` and getattr()s the result 

79# -- our own module completer does, and so do other introspection tools -- 

80# would otherwise trigger its `DeprecationWarning` without any code 

81# actually wanting the name. Explicit `IPython.Application` access still 

82# resolves, and still warns, which is the access we want to hear about. 

83_lazy_attrs = frozenset({"embed", "get_ipython"}) 

84 

85 

86def __getattr__(name: str) -> Any: 

87 if name == "embed": 

88 from .terminal.embed import embed 

89 

90 return embed 

91 if name == "get_ipython": 

92 from .core.getipython import get_ipython 

93 

94 return get_ipython 

95 if name == "Application": 

96 warnings.warn( 

97 "`IPython.Application` is only a re-export of" 

98 " `traitlets.config.application.Application`; import it from" 

99 " traitlets directly. Accessing it here triggers an import of" 

100 " `IPython.core.application`, which is no longer imported when" 

101 " IPython is -- import that module explicitly if you rely on" 

102 " that import happening, in particular if you also rely on other" 

103 " submodules being transitively imported as a side effect.", 

104 DeprecationWarning, 

105 stacklevel=2, 

106 ) 

107 from .core.application import Application 

108 

109 return Application 

110 raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 

111 

112 

113def __dir__() -> list[str]: 

114 return [*globals(), *_lazy_attrs] 

115 

116# Release data 

117__author__ = '{} <{}>'.format(release.author, release.author_email) 

118__license__ = release.license 

119__version__ = release.version 

120version_info = release.version_info 

121# list of CVEs that should have been patched in this release. 

122# this is informational and should not be relied upon. 

123__patched_cves__ = {"CVE-2022-21699", "CVE-2023-24816"} 

124 

125 

126def embed_kernel(module=None, local_ns=None, **kwargs): 

127 """Embed and start an IPython kernel in a given scope. 

128 

129 If you don't want the kernel to initialize the namespace 

130 from the scope of the surrounding function, 

131 and/or you want to load full IPython configuration, 

132 you probably want `IPython.start_kernel()` instead. 

133 

134 This is a deprecated alias for `ipykernel.embed.embed_kernel()`, 

135 to be removed in the future. 

136 You should import directly from `ipykernel.embed`; this wrapper 

137 fails anyway if you don't have `ipykernel` package installed. 

138 

139 Parameters 

140 ---------- 

141 module : types.ModuleType, optional 

142 The module to load into IPython globals (default: caller) 

143 local_ns : dict, optional 

144 The namespace to load into IPython user namespace (default: caller) 

145 **kwargs : various, optional 

146 Further keyword args are relayed to the IPKernelApp constructor, 

147 such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`), 

148 allowing configuration of the kernel. Will only have an effect 

149 on the first embed_kernel call for a given process. 

150 """ 

151 

152 warnings.warn( 

153 "import embed_kernel from ipykernel.embed directly (since 2013)." 

154 " Importing from IPython will be removed in the future", 

155 DeprecationWarning, 

156 stacklevel=2, 

157 ) 

158 

159 (caller_module, caller_locals) = extract_module_locals(1) 

160 if module is None: 

161 module = caller_module 

162 if local_ns is None: 

163 local_ns = dict(**caller_locals) 

164 

165 # Only import .zmq when we really need it 

166 from ipykernel.embed import embed_kernel as real_embed_kernel 

167 real_embed_kernel(module=module, local_ns=local_ns, **kwargs) 

168 

169def start_ipython(argv: list[str] | None = None, **kwargs: Any) -> Any: 

170 """Launch a normal IPython instance (as opposed to embedded) 

171 

172 `IPython.embed()` puts a shell in a particular calling scope, 

173 such as a function or method for debugging purposes, 

174 which is often not desirable. 

175 

176 `start_ipython()` does full, regular IPython initialization, 

177 including loading startup files, configuration, etc. 

178 much of which is skipped by `embed()`. 

179 

180 This is a public API method, and will survive implementation changes. 

181 

182 Parameters 

183 ---------- 

184 argv : list or None, optional 

185 If unspecified or None, IPython will parse command-line options from sys.argv. 

186 To prevent any command-line parsing, pass an empty list: `argv=[]`. 

187 user_ns : dict, optional 

188 specify this dictionary to initialize the IPython user namespace with particular values. 

189 **kwargs : various, optional 

190 Any other kwargs will be passed to the Application constructor, 

191 such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`), 

192 allowing configuration of the instance (see :ref:`terminal_options`). 

193 """ 

194 from IPython.terminal.ipapp import launch_new_instance 

195 return launch_new_instance(argv=argv, **kwargs)