Skip to content

nox.virtualenv.InterpreterNotFound: Python interpreter python3.11 not found #1045

@mtelka

Description

@mtelka

I do see following two test failures on a system without Python 3.11 installed:

______________ test_download_python_auto_missing_interpreter[uv] _______________
        
which = <MagicMock name='which' id='140736074242704'>
uv_install_mock = <MagicMock name='uv_install_python' id='140736074242368'>
pbs_install_mock = <MagicMock name='pbs_install_python' id='140736074242032'>
venv_backend = 'uv'
make_one = <function make_one.<locals>.factory at 0x7fffac270f60> 
        
    @pytest.mark.parametrize("venv_backend", ["uv", "venv", "virtualenv"])
    @mock.patch(
        "nox.virtualenv.pbs_install_python",
        return_value="/.local/share/nox/[email protected]/bin/python3.11",
    )       
    @mock.patch(
        "nox.virtualenv.uv_install_python",
        return_value=True,
    )       
    @mock.patch.object(shutil, "which", return_value=None)
    def test_download_python_auto_missing_interpreter(
        which: mock.Mock,
        uv_install_mock: mock.Mock,
        pbs_install_mock: mock.Mock, 
        venv_backend: str,
        make_one: Callable[..., tuple[VirtualEnv, Path]],
    ) -> None:  
        venv, _ = make_one(
            interpreter="python3.11",
            venv_backend=venv_backend,
            download_python="auto",
        )   
            
>       resolved_interpreter = venv._resolved_interpreter
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^

/data/builds/ul-workspace/components/python/nox/build/amd64-3.14/tests/test_virtualenv.py:1455:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <nox.virtualenv.VirtualEnv object at 0x7fffac270c00>

    @property
    def _resolved_interpreter(self) -> str:
        """Return the interpreter, appropriately resolved for the platform.

        Based heavily on tox's implementation (tox/interpreters.py).
        """
        # If there is no assigned interpreter, then use the same one used by
        # Nox.
        if isinstance(self._resolved, Exception):
            raise self._resolved

        if self._resolved is not None:
            return self._resolved

        if self.interpreter is None:
            self._resolved = sys.executable
            return self._resolved

        # Otherwise we need to divine the path to the interpreter. This is
        # designed to accept strings in the form of "2", "2.7", "2.7.13",
        # "2.7.13-32", "python2", "python2.4", etc.
        xy_version = ""
        cleaned_interpreter = self.interpreter

        # If this is just a X, X.Y, or X.Y.Z string, extract just the X / X.Y
        # part and add Python to the front of it.
        match = re.match(r"^(?P<xy_ver>\d(\.\d+)?)(\.\d+)?(?P<t>t?)$", self.interpreter)
        if match:
            xy_version = match.group("xy_ver")
            t = match.group("t")
            cleaned_interpreter = f"python{xy_version}{t}"

        # never -> check for interpreters
        if self.download_python == "never":
            if resolved := _find_python(cleaned_interpreter, xy_version):
                self._resolved = resolved
                return self._resolved

        # always -> skip check, always install
        elif self.download_python == "always" and self.venv_backend == "uv":
            if HAS_UV and version.Version("0.4.16") <= UV_VERSION:
                uv_python_success = uv_install_python(cleaned_interpreter)
                if uv_python_success:
                    self._resolved = cleaned_interpreter
                    return self._resolved

        elif self.download_python == "always" and self.venv_backend in (
            "venv",
            "virtualenv",
        ):
            pbs_python_path = pbs_install_python(cleaned_interpreter)
            if pbs_python_path:
                self._resolved = pbs_python_path
                return self._resolved

        # auto -> check interpreters -> fallback to installing
        else:
            if resolved := _find_python(cleaned_interpreter, xy_version):
                self._resolved = resolved
                return self._resolved

            if (
                self.venv_backend == "uv"
                and HAS_UV
                and version.Version("0.4.16") <= UV_VERSION
            ):  
                uv_python_success = uv_install_python(cleaned_interpreter)
                if uv_python_success:
                    self._resolved = cleaned_interpreter
                    return self._resolved
            elif self.venv_backend in ("venv", "virtualenv"):
                pbs_python_path = pbs_install_python(cleaned_interpreter)
                if pbs_python_path:
                    self._resolved = pbs_python_path
                    return self._resolved

        self._resolved = InterpreterNotFound(self.interpreter)
>       raise self._resolved
E       nox.virtualenv.InterpreterNotFound: Python interpreter python3.11 not found

/data/builds/ul-workspace/components/python/nox/build/amd64-3.14/nox/virtualenv.py:767: InterpreterNotFound
___________ test_download_python_always_preexisting_interpreter[uv] ____________
        
which = <MagicMock name='which' id='140736071413984'>
uv_install_mock = <MagicMock name='uv_install_python' id='140736071413648'>
pbs_install_mock = <MagicMock name='pbs_install_python' id='140736071417008'>
venv_backend = 'uv'
make_one = <function make_one.<locals>.factory at 0x7fffac234eb0> 
        
    @pytest.mark.parametrize("venv_backend", ["uv", "venv", "virtualenv"])
    @mock.patch(
        "nox.virtualenv.pbs_install_python",
        return_value="/.local/share/nox/[email protected]/bin/python3.11",
    )       
    @mock.patch(
        "nox.virtualenv.uv_install_python",
        return_value=True,
    )       
    @mock.patch.object(shutil, "which", return_value="/usr/bin/python3.11")
    def test_download_python_always_preexisting_interpreter(
        which: mock.Mock,
        uv_install_mock: mock.Mock,
        pbs_install_mock: mock.Mock, 
        venv_backend: str,
        make_one: Callable[..., tuple[VirtualEnv, Path]],
    ) -> None:  
        venv, _ = make_one(
            interpreter="python3.11",
            venv_backend=venv_backend,
            download_python="always",
        )   
            
>       resolved_interpreter = venv._resolved_interpreter
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^

/data/builds/ul-workspace/components/python/nox/build/amd64-3.14/tests/test_virtualenv.py:1494:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <nox.virtualenv.VirtualEnv object at 0x7fffac235230>

    @property
    def _resolved_interpreter(self) -> str:
        """Return the interpreter, appropriately resolved for the platform.

        Based heavily on tox's implementation (tox/interpreters.py).
        """
        # If there is no assigned interpreter, then use the same one used by
        # Nox.
        if isinstance(self._resolved, Exception):
            raise self._resolved

        if self._resolved is not None:
            return self._resolved

        if self.interpreter is None:
            self._resolved = sys.executable
            return self._resolved

        # Otherwise we need to divine the path to the interpreter. This is
        # designed to accept strings in the form of "2", "2.7", "2.7.13",
        # "2.7.13-32", "python2", "python2.4", etc.
        xy_version = ""
        cleaned_interpreter = self.interpreter

        # If this is just a X, X.Y, or X.Y.Z string, extract just the X / X.Y
        # part and add Python to the front of it.
        match = re.match(r"^(?P<xy_ver>\d(\.\d+)?)(\.\d+)?(?P<t>t?)$", self.interpreter)
        if match:
            xy_version = match.group("xy_ver")
            t = match.group("t")
            cleaned_interpreter = f"python{xy_version}{t}"

        # never -> check for interpreters
        if self.download_python == "never":
            if resolved := _find_python(cleaned_interpreter, xy_version):
                self._resolved = resolved
                return self._resolved

        # always -> skip check, always install
        elif self.download_python == "always" and self.venv_backend == "uv":
            if HAS_UV and version.Version("0.4.16") <= UV_VERSION:
                uv_python_success = uv_install_python(cleaned_interpreter)
                if uv_python_success:
                    self._resolved = cleaned_interpreter
                    return self._resolved

        elif self.download_python == "always" and self.venv_backend in (
            "venv",
            "virtualenv",
        ):
            pbs_python_path = pbs_install_python(cleaned_interpreter)
            if pbs_python_path:
                self._resolved = pbs_python_path
                return self._resolved

        # auto -> check interpreters -> fallback to installing
        else:
            if resolved := _find_python(cleaned_interpreter, xy_version):
                self._resolved = resolved
                return self._resolved

            if (
                self.venv_backend == "uv"
                and HAS_UV
                and version.Version("0.4.16") <= UV_VERSION
            ):  
                uv_python_success = uv_install_python(cleaned_interpreter)
                if uv_python_success:
                    self._resolved = cleaned_interpreter
                    return self._resolved
            elif self.venv_backend in ("venv", "virtualenv"):
                pbs_python_path = pbs_install_python(cleaned_interpreter)
                if pbs_python_path:
                    self._resolved = pbs_python_path
                    return self._resolved

        self._resolved = InterpreterNotFound(self.interpreter)
>       raise self._resolved
E       nox.virtualenv.InterpreterNotFound: Python interpreter python3.11 not found

/data/builds/ul-workspace/components/python/nox/build/amd64-3.14/nox/virtualenv.py:767: InterpreterNotFound

OS: OpenIndiana
nox: 2025.11.12
Python: 3.14.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions