A compiler that caches code compiled from interactive statements.
| 67 | #----------------------------------------------------------------------------- |
| 68 | |
| 69 | class CachingCompiler(codeop.Compile): |
| 70 | """A compiler that caches code compiled from interactive statements. |
| 71 | """ |
| 72 | |
| 73 | def __init__(self): |
| 74 | codeop.Compile.__init__(self) |
| 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 | |
| 96 | def ast_parse(self, source, filename='<unknown>', symbol='exec'): |
| 97 | """Parse code to an AST with the current compiler flags active. |
| 98 | |
| 99 | Arguments are exactly the same as ast.parse (in the standard library), |
| 100 | and are passed to the built-in compile function.""" |
| 101 | return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1) |
| 102 | |
| 103 | def reset_compiler_flags(self): |
| 104 | """Reset compiler flags to default state.""" |
| 105 | # This value is copied from codeop.Compile.__init__, so if that ever |
| 106 | # changes, it will need to be updated. |
| 107 | self.flags = codeop.PyCF_DONT_IMPLY_DEDENT |
| 108 | |
| 109 | @property |
| 110 | def compiler_flags(self): |
| 111 | """Flags currently active in the compilation process. |
| 112 | """ |
| 113 | return self.flags |
| 114 | |
| 115 | def cache(self, code, number=0): |
| 116 | """Make a name for a block of code, and cache the code. |
| 117 | |
| 118 | Parameters |
| 119 | ---------- |
| 120 | code : str |
| 121 | The Python source code to cache. |
| 122 | number : int |
| 123 | A number which forms part of the code's name. Used for the execution |
| 124 | counter. |
| 125 | |
| 126 | Returns |
no outgoing calls
no test coverage detected