cpython/Lib/statcache.py

83 lines
2.4 KiB
Python
Raw Normal View History

"""Maintain a cache of stat() information on files.
There are functions to reset the cache or to selectively remove items.
"""
1990-10-13 16:23:40 -03:00
import warnings
warnings.warn("The statcache module is obsolete. Use os.stat() instead.",
DeprecationWarning)
del warnings
import os as _os
from stat import *
1990-10-13 16:23:40 -03:00
__all__ = ["stat","reset","forget","forget_prefix","forget_dir",
"forget_except_prefix","isdir"]
# The cache. Keys are pathnames, values are os.stat outcomes.
# Remember that multiple threads may be calling this! So, e.g., that
# path in cache returns 1 doesn't mean the cache will still contain
# path on the next line. Code defensively.
1990-10-13 16:23:40 -03:00
cache = {}
1990-10-13 16:23:40 -03:00
def stat(path):
2001-01-14 21:36:40 -04:00
"""Stat a file, possibly out of the cache."""
ret = cache.get(path, None)
if ret is None:
cache[path] = ret = _os.stat(path)
2001-01-14 21:36:40 -04:00
return ret
1990-10-13 16:23:40 -03:00
def reset():
"""Clear the cache."""
cache.clear()
1990-10-13 16:23:40 -03:00
# For thread saftey, always use forget() internally too.
1990-10-13 16:23:40 -03:00
def forget(path):
2001-01-14 21:36:40 -04:00
"""Remove a given item from the cache, if it exists."""
try:
2001-01-14 21:36:40 -04:00
del cache[path]
except KeyError:
pass
1990-10-13 16:23:40 -03:00
def forget_prefix(prefix):
2001-01-14 21:36:40 -04:00
"""Remove all pathnames with a given prefix."""
for path in cache.keys():
if path.startswith(prefix):
forget(path)
1990-10-13 16:23:40 -03:00
def forget_dir(prefix):
"""Forget a directory and all entries except for entries in subdirs."""
# Remove trailing separator, if any. This is tricky to do in a
# x-platform way. For example, Windows accepts both / and \ as
# separators, and if there's nothing *but* a separator we want to
# preserve that this is the root. Only os.path has the platform
# knowledge we need.
from os.path import split, join
prefix = split(join(prefix, "xxx"))[0]
2001-01-14 21:36:40 -04:00
forget(prefix)
for path in cache.keys():
# First check that the path at least starts with the prefix, so
# that when it doesn't we can avoid paying for split().
if path.startswith(prefix) and split(path)[0] == prefix:
forget(path)
1990-10-13 16:23:40 -03:00
def forget_except_prefix(prefix):
2001-01-14 21:36:40 -04:00
"""Remove all pathnames except with a given prefix.
1990-10-13 16:23:40 -03:00
Normally used with prefix = '/' after a chdir().
"""
for path in cache.keys():
if not path.startswith(prefix):
forget(path)
1990-10-13 16:23:40 -03:00
def isdir(path):
"""Return True if directory, else False."""
2001-01-14 21:36:40 -04:00
try:
st = stat(path)
except _os.error:
return False
return S_ISDIR(st.st_mode)