Show More
@@ -73,25 +73,6 b' class CachingCompiler(codeop.Compile):' | |||
|
73 | 73 | def __init__(self): |
|
74 | 74 | codeop.Compile.__init__(self) |
|
75 | 75 | |
|
76 | # This is ugly, but it must be done this way to allow multiple | |
|
77 | # simultaneous ipython instances to coexist. Since Python itself | |
|
78 | # directly accesses the data structures in the linecache module, and | |
|
79 | # the cache therein is global, we must work with that data structure. | |
|
80 | # We must hold a reference to the original checkcache routine and call | |
|
81 | # that in our own check_cache() below, but the special IPython cache | |
|
82 | # must also be shared by all IPython instances. If we were to hold | |
|
83 | # separate caches (one in each CachingCompiler instance), any call made | |
|
84 | # by Python itself to linecache.checkcache() would obliterate the | |
|
85 | # cached data from the other IPython instances. | |
|
86 | if not hasattr(linecache, '_ipython_cache'): | |
|
87 | linecache._ipython_cache = {} | |
|
88 | if not hasattr(linecache, '_checkcache_ori'): | |
|
89 | linecache._checkcache_ori = linecache.checkcache | |
|
90 | # Now, we must monkeypatch the linecache directly so that parts of the | |
|
91 | # stdlib that call it outside our control go through our codepath | |
|
92 | # (otherwise we'd lose our tracebacks). | |
|
93 | linecache.checkcache = check_linecache_ipython | |
|
94 | ||
|
95 | 76 | # Caching a dictionary { filename: execution_count } for nicely |
|
96 | 77 | # rendered tracebacks. The filename corresponds to the filename |
|
97 | 78 | # argument used for the builtins.compile function. |
@@ -161,14 +142,24 b' class CachingCompiler(codeop.Compile):' | |||
|
161 | 142 | # Save the execution count |
|
162 | 143 | self._filename_map[name] = number |
|
163 | 144 | |
|
145 | # Since Python 2.5, setting mtime to `None` means the lines will | |
|
146 | # never be removed by `linecache.checkcache`. This means all the | |
|
147 | # monkeypatching has *never* been necessary, since this code was | |
|
148 | # only added in 2010, at which point IPython had already stopped | |
|
149 | # supporting Python 2.4. | |
|
150 | # | |
|
151 | # Note that `linecache.clearcache` and `linecache.updatecache` may | |
|
152 | # still remove our code from the cache, but those show explicit | |
|
153 | # intent, and we should not try to interfere. Normally the former | |
|
154 | # is never called except when out of memory, and the latter is only | |
|
155 | # called for lines *not* in the cache. | |
|
164 | 156 | entry = ( |
|
165 | 157 | len(transformed_code), |
|
166 |
|
|
|
158 | None, | |
|
167 | 159 | [line + "\n" for line in transformed_code.splitlines()], |
|
168 | 160 | name, |
|
169 | 161 | ) |
|
170 | 162 | linecache.cache[name] = entry |
|
171 | linecache._ipython_cache[name] = entry | |
|
172 | 163 | return name |
|
173 | 164 | |
|
174 | 165 | @contextmanager |
@@ -187,10 +178,20 b' class CachingCompiler(codeop.Compile):' | |||
|
187 | 178 | |
|
188 | 179 | |
|
189 | 180 | def check_linecache_ipython(*args): |
|
190 | """Call linecache.checkcache() safely protecting our cached values. | |
|
181 | """Deprecated since IPython 8.6. Call linecache.checkcache() directly. | |
|
182 | ||
|
183 | It was already not necessary to call this function directly. If no | |
|
184 | CachingCompiler had been created, this function would fail badly. If | |
|
185 | an instance had been created, this function would've been monkeypatched | |
|
186 | into place. | |
|
187 | ||
|
188 | As of IPython 8.6, the monkeypatching has gone away entirely. But there | |
|
189 | were still internal callers of this function, so maybe external callers | |
|
190 | also existed? | |
|
191 | 191 | """ |
|
192 | # First call the original checkcache as intended | |
|
193 | linecache._checkcache_ori(*args) | |
|
194 | # Then, update back the cache with our data, so that tracebacks related | |
|
195 | # to our compiled codes can be produced. | |
|
196 | linecache.cache.update(linecache._ipython_cache) | |
|
192 | import warnings | |
|
193 | warnings.warn( | |
|
194 | 'Just call linecache.checkcache() directly.', | |
|
195 | DeprecationWarning | |
|
196 | ) | |
|
197 | linecache.checkcache() |
@@ -61,7 +61,7 b' from IPython.core import magic, oinspect, page, prefilter, ultratb' | |||
|
61 | 61 | from IPython.core.alias import Alias, AliasManager |
|
62 | 62 | from IPython.core.autocall import ExitAutocall |
|
63 | 63 | from IPython.core.builtin_trap import BuiltinTrap |
|
64 |
from IPython.core.compilerop import CachingCompiler |
|
|
64 | from IPython.core.compilerop import CachingCompiler | |
|
65 | 65 | from IPython.core.debugger import InterruptiblePdb |
|
66 | 66 | from IPython.core.display_trap import DisplayTrap |
|
67 | 67 | from IPython.core.displayhook import DisplayHook |
@@ -1810,7 +1810,6 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1810 | 1810 | self.InteractiveTB = ultratb.AutoFormattedTB(mode = 'Plain', |
|
1811 | 1811 | color_scheme='NoColor', |
|
1812 | 1812 | tb_offset = 1, |
|
1813 | check_cache=check_linecache_ipython, | |
|
1814 | 1813 | debugger_cls=self.debugger_cls, parent=self) |
|
1815 | 1814 | |
|
1816 | 1815 | # The instance will store a pointer to the system-wide exception hook, |
@@ -644,10 +644,8 b' class VerboseTB(TBTools):' | |||
|
644 | 644 | self.long_header = long_header |
|
645 | 645 | self.include_vars = include_vars |
|
646 | 646 | # By default we use linecache.checkcache, but the user can provide a |
|
647 |
# different check_cache implementation. This |
|
|
648 |
# |
|
|
649 | # by a compiler instance that flushes the linecache but preserves its | |
|
650 | # own code cache. | |
|
647 | # different check_cache implementation. This was formerly used by the | |
|
648 | # IPython kernel for interactive code, but is no longer necessary. | |
|
651 | 649 | if check_cache is None: |
|
652 | 650 | check_cache = linecache.checkcache |
|
653 | 651 | self.check_cache = check_cache |
General Comments 0
You need to be logged in to leave comments.
Login now