Index: Lib/re.py =================================================================== --- Lib/re.py (revision 62337) +++ Lib/re.py (working copy) @@ -222,34 +222,54 @@ _pattern_type = type(sre_compile.compile("", 0)) -_MAXCACHE = 100 +_MAXCACHE = 256 +_CACHE_CLEAR = _MAXCACHE >> 1 +_CACHE_IDX = -1 +_CACHE_REPL_IDX = -1 + def _compile(*key): # internal: compile pattern + global _CACHE_IDX + _CACHE_IDX += 1 cachekey = (type(key[0]),) + key - p = _cache.get(cachekey) - if p is not None: + entry = _cache.get(cachekey) + if entry is not None: + p = entry[1] + _cache[cachekey] = (_CACHE_IDX, p) return p pattern, flags = key if isinstance(pattern, _pattern_type): if flags: raise ValueError('Cannot process flags argument with a compiled pattern') return pattern - if not sre_compile.isstring(pattern): + if not isinstance(pattern, basestring): raise TypeError, "first argument must be string or compiled pattern" try: p = sre_compile.compile(pattern, flags) except error, v: raise error, v # invalid expression if len(_cache) >= _MAXCACHE: + cache_items = _cache.items() _cache.clear() - _cache[cachekey] = p + + # Sort by index + cache_items.sort(key = lambda x: x[1][0]) + + # Reinsert the last + _cache.update(cache_items[-_CACHE_CLEAR:]) + + _cache[cachekey] = (_CACHE_IDX, p) return p def _compile_repl(*key): # internal: compile replacement pattern - p = _cache_repl.get(key) - if p is not None: + global _CACHE_REPL_IDX + _CACHE_REPL_IDX += 1 + entry = _cache_repl.get(key) + if entry is not None: + p = entry[1] + _cache_repl[key] = (_CACHE_REPL_IDX, p) return p repl, pattern = key try: @@ -257,8 +277,16 @@ except error, v: raise error, v # invalid expression if len(_cache_repl) >= _MAXCACHE: + cache_items = _cache_repl.items() _cache_repl.clear() - _cache_repl[key] = p + + # Sort by index + cache_items.sort(key = lambda x: x[1][0]) + + # Reinsert the last + _cache_repl.update(cache_items[-_CACHE_CLEAR:]) + + _cache_repl[key] = (_CACHE_REPL_IDX, p) return p def _expand(pattern, match, template):