def iter_interpreters(
        self,
        python_spec: str | None = None,
        search_venv: bool | None = None,
        filter_func: Callable[[PythonInfo], bool] | None = None,
        respect_version_file: bool = True,
    ) -> Iterable[PythonInfo]:
        """Iterate over all interpreters that matches the given specifier.
        And optionally install the interpreter if not found.
        """
        from packaging.version import InvalidVersion

        from pdm.cli.commands.python import InstallCommand

        def read_version_from_version_file(python_version_file: Path) -> str | None:
            content = python_version_file.read_text().strip()
            content_lines = [cl for cl in content.splitlines() if not cl.lstrip().startswith("#")]

            return content_lines[0] if len(content_lines) == 1 else None

        version_file = self.root.joinpath(".python-version")
        found = False
        if respect_version_file and not python_spec and (os.getenv("PDM_PYTHON_VERSION") or version_file.exists()):
            requested = os.getenv("PDM_PYTHON_VERSION") or read_version_from_version_file(version_file)
            if requested is not None and requested not in self.python_requires:
                self.core.ui.warn(".python-version is found but the version is not in requires-python, ignored.")
            elif requested is not None:
                python_spec = requested
        for interpreter in self.find_interpreters(python_spec, search_venv):
            if filter_func is None or filter_func(interpreter):
                found = True
                yield interpreter
        if found or self.is_global:
            return

        if not python_spec:  # handle both empty string and None
            # Get the best match meeting the requires-python
            best_match = self.get_best_matching_cpython_version()
            if best_match is None:
                return
            python_spec = str(best_match)
        else:
            try:
                if python_spec not in self.python_requires:
                    return
            except InvalidVersion:
                return
        try:
            # otherwise if no interpreter is found, try to install it
            installed = InstallCommand.install_python(self, python_spec)
        except Exception as e:
            self.core.ui.error(f"Failed to install Python {python_spec}: {e}")
            return
        else:
            if filter_func is None or filter_func(installed):
                yield installed
Iterate over all interpreters that matches the given specifier.
        And optionally install the interpreter if not found.
        
src/pdm/project/core.py