44is not found, it will look down the module search path for a file by
55that name.
66"""
7+ import threading
78
89__all__ = ["getline" , "clearcache" , "checkcache" , "lazycache" ]
910
1213# or a tuple (size, mtime, lines, fullname) once loaded.
1314cache = {}
1415_interactive_cache = {}
16+ mutex = threading .Lock ()
1517
1618
1719def clearcache ():
@@ -33,10 +35,9 @@ def getlines(filename, module_globals=None):
3335 """Get the lines for a Python source file from the cache.
3436 Update the cache if it doesn't contain an entry for this file already."""
3537
36- if filename in cache :
37- entry = cache [filename ]
38- if len (entry ) != 1 :
39- return cache [filename ][2 ]
38+ entry = cache .get (filename , None )
39+ if entry is not None and len (entry ) != 1 :
40+ return entry [2 ]
4041
4142 try :
4243 return updatecache (filename , module_globals )
@@ -56,10 +57,9 @@ def _make_key(code):
5657
5758def _getlines_from_code (code ):
5859 code_id = _make_key (code )
59- if code_id in _interactive_cache :
60- entry = _interactive_cache [code_id ]
61- if len (entry ) != 1 :
62- return _interactive_cache [code_id ][2 ]
60+ entry = _interactive_cache .get (code_id , None )
61+ if entry is not None and len (entry ) != 1 :
62+ return entry [2 ]
6363 return []
6464
6565
@@ -84,12 +84,8 @@ def checkcache(filename=None):
8484 filenames = [filename ]
8585
8686 for filename in filenames :
87- try :
88- entry = cache [filename ]
89- except KeyError :
90- continue
91-
92- if len (entry ) == 1 :
87+ entry = cache .get (filename , None )
88+ if entry is None or len (entry ) == 1 :
9389 # lazy cache entry, leave it lazy.
9490 continue
9591 size , mtime , lines , fullname = entry
@@ -125,8 +121,9 @@ def updatecache(filename, module_globals=None):
125121 # These import can fail if the interpreter is shutting down
126122 return []
127123
128- if filename in cache :
129- if len (cache [filename ]) != 1 :
124+ with mutex :
125+ entry = cache .get (filename , None )
126+ if entry is not None and len (entry ) != 1 :
130127 cache .pop (filename , None )
131128 if _source_unavailable (filename ):
132129 return []
@@ -156,13 +153,14 @@ def updatecache(filename, module_globals=None):
156153 # No luck, the PEP302 loader cannot find the source
157154 # for this module.
158155 return []
159- cache [ filename ] = (
156+ entry = (
160157 len (data ),
161158 None ,
162159 [line + '\n ' for line in data .splitlines ()],
163160 fullname
164161 )
165- return cache [filename ][2 ]
162+ cache [filename ] = entry
163+ return entry [2 ]
166164
167165 # Try looking through the module search path, which is only useful
168166 # when handling a relative filename.
@@ -211,11 +209,9 @@ def lazycache(filename, module_globals):
211209 get_source method must be found, the filename must be a cacheable
212210 filename, and the filename must not be already cached.
213211 """
214- if filename in cache :
215- if len (cache [filename ]) == 1 :
216- return True
217- else :
218- return False
212+ entry = cache .get (filename , None )
213+ if entry is not None :
214+ return len (entry ) == 1
219215 if not filename or (filename .startswith ('<' ) and filename .endswith ('>' )):
220216 return False
221217 # Try for a __loader__, if available
@@ -245,4 +241,5 @@ def _register_code(code, string, name):
245241 for const in code .co_consts :
246242 if isinstance (const , type (code )):
247243 stack .append (const )
248- _interactive_cache [_make_key (code )] = entry
244+ key = _make_key (code )
245+ _interactive_cache [key ] = entry
0 commit comments