diff --git a/astroid/interpreter/_import/spec.py b/astroid/interpreter/_import/spec.py index 09e98c888b..d2dc13bfc8 100644 --- a/astroid/interpreter/_import/spec.py +++ b/astroid/interpreter/_import/spec.py @@ -21,7 +21,7 @@ from typing import Any, Literal, NamedTuple, Protocol from astroid.const import PY310_PLUS -from astroid.modutils import EXT_LIB_DIRS +from astroid.modutils import EXT_LIB_DIRS, cached_os_path_isfile from . import util @@ -167,7 +167,7 @@ def find_module( for suffix in suffixes: package_file_name = "__init__" + suffix file_path = os.path.join(package_directory, package_file_name) - if os.path.isfile(file_path): + if cached_os_path_isfile(file_path): return ModuleSpec( name=modname, location=package_directory, @@ -176,7 +176,7 @@ def find_module( for suffix, type_ in ImportlibFinder._SUFFIXES: file_name = modname + suffix file_path = os.path.join(entry, file_name) - if os.path.isfile(file_path): + if cached_os_path_isfile(file_path): return ModuleSpec(name=modname, location=file_path, type=type_) return None diff --git a/astroid/manager.py b/astroid/manager.py index e7c2c806f7..7206be616a 100644 --- a/astroid/manager.py +++ b/astroid/manager.py @@ -24,6 +24,7 @@ NoSourceFile, _cache_normalize_path_, _has_init, + cached_os_path_isfile, file_info_from_modpath, get_source_file, is_module_name_part_of_extension_package_whitelist, @@ -471,6 +472,7 @@ def clear_cache(self) -> None: LookupMixIn.lookup, _cache_normalize_path_, _has_init, + cached_os_path_isfile, util.is_namespace, ObjectModel.attributes, ClassDef._metaclass_lookup_attribute, diff --git a/astroid/modutils.py b/astroid/modutils.py index 8f7d0d3fe9..1536447e34 100644 --- a/astroid/modutils.py +++ b/astroid/modutils.py @@ -604,6 +604,12 @@ def is_relative(modname: str, from_file: str) -> bool: ) +@lru_cache(maxsize=1024) +def cached_os_path_isfile(path: str | os.PathLike) -> bool: + """A cached version of os.path.isfile that helps avoid repetitive I/O""" + return os.path.isfile(path) + + # internal only functions #####################################################