python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
31.02k stars 2.25k forks source link

[WinError 193] when `virtualenvs.prefer-active-python` is `true` #8229

Open IvanaGyro opened 1 year ago

IvanaGyro commented 1 year ago

Due to #8160 I can't install the latest stable version via the command in the document.

Issue

I got

[WinError 193] %1 is not a valid Win32 application.

with virtualenvs.prefer-active-python set to true. There may be a related thread #7075.

I use pyenv to manage my Python version. To use the different Python version from the version used to install poetry, I enable virtualenvs.prefer-active-python following the document.

poetry config virtualenvs.prefer-active-python true

My current Python versions are

pyenv global: 3.12.0b4
pyenv local: 3.10.11

However poetry doesn't use 3.10.11. Here is the output of poetry debug info -vvv


Poetry
Loading configuration file C:\Users\Ivana\AppData\Roaming\pypoetry\config.toml
Version: 1.6.0.dev0
Python:  3.12.0

  Stack trace:

  18  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:327 in run
       325β”‚
       326β”‚             try:
     β†’ 327β”‚                 exit_code = self._run(io)
       328β”‚             except BrokenPipeError:
       329β”‚                 # If we are piped to another process, it may close early and send a

  17  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\console\application.py:190 in _run
       188β”‚         self._load_plugins(io)
       189β”‚
     β†’ 190β”‚         exit_code: int = super()._run(io)
       191β”‚         return exit_code
       192β”‚

  16  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:431 in _run
       429β”‚             io.input.interactive(interactive)
       430β”‚
     β†’ 431β”‚         exit_code = self._run_command(command, io)
       432β”‚         self._running_command = None
       433β”‚

  15  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:473 in _run_command
       471β”‚
       472β”‚         if error is not None:
     β†’ 473β”‚             raise error
       474β”‚
       475β”‚         return terminate_event.exit_code

  14  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:457 in _run_command
       455β”‚
       456β”‚             if command_event.command_should_run():
     β†’ 457β”‚                 exit_code = command.run(io)
       458β”‚             else:
       459β”‚                 exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED

  13  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\commands\base_command.py:119 in run
       117β”‚         io.input.validate()
       118β”‚
     β†’ 119β”‚         status_code = self.execute(io)
       120β”‚
       121β”‚         if status_code is None:

  12  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\commands\command.py:62 in execute
        60β”‚
        61β”‚         try:
     β†’  62β”‚             return self.handle()
        63β”‚         except KeyboardInterrupt:
        64β”‚             return 1

  11  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\console\commands\debug\info.py:27 in handle
        25β”‚         command = self.get_application().get("env info")
        26β”‚
     β†’  27β”‚         exit_code: int = command.run(self.io)
        28β”‚         return exit_code
        29β”‚

  10  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\commands\base_command.py:119 in run
       117β”‚         io.input.validate()
       118β”‚
     β†’ 119β”‚         status_code = self.execute(io)
       120β”‚
       121β”‚         if status_code is None:

   9  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\commands\command.py:62 in execute
        60β”‚
        61β”‚         try:
     β†’  62β”‚             return self.handle()
        63β”‚         except KeyboardInterrupt:
        64β”‚             return 1

   8  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\console\commands\env\info.py:28 in handle
        26β”‚         from poetry.utils.env import EnvManager
        27β”‚
     β†’  28β”‚         env = EnvManager(self.poetry).get()
        29β”‚
        30β”‚         if self.option("path"):

   7  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:236 in get
       234β”‚             "virtualenvs.prefer-active-python"
       235β”‚         )
     β†’ 236β”‚         python_minor = self.get_python_version(
       237β”‚             precision=2, prefer_active_python=prefer_active_python, io=self._io
       238β”‚         ).to_string()

   6  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:108 in get_python_version
       106β”‚
       107β”‚         if prefer_active_python:
     β†’ 108β”‚             executable = EnvManager._detect_active_python(io)
       109β”‚
       110β”‚             if executable:

   5  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:86 in _detect_active_python
        84β”‚         )
        85β”‚
     β†’  86β”‚         executable = EnvManager._full_python_path("python")
        87β”‚
        88β”‚         if executable is not None:

   4  ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:69 in _full_python_path
        67β”‚
        68β”‚         try:
     β†’  69β”‚             executable = subprocess.check_output(
        70β”‚                 [path_python, "-c", "import sys; print(sys.executable)"], text=True
        71β”‚             ).strip()

   3  ~\.pyenv\pyenv-win\versions\3.12.0b4\Lib\subprocess.py:466 in check_output
        464β”‚         kwargs['input'] = empty
        465β”‚
     β†’  466β”‚     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
        467β”‚                **kwargs).stdout
        468β”‚

   2  ~\.pyenv\pyenv-win\versions\3.12.0b4\Lib\subprocess.py:548 in run
        546β”‚         kwargs['stderr'] = PIPE
        547β”‚
     β†’  548β”‚     with Popen(*popenargs, **kwargs) as process:
        549β”‚         try:
        550β”‚             stdout, stderr = process.communicate(input, timeout=timeout)

   1  ~\.pyenv\pyenv-win\versions\3.12.0b4\Lib\subprocess.py:1026 in __init__
       1024β”‚                             encoding=encoding, errors=errors)
       1025β”‚
     β†’ 1026β”‚             self._execute_child(args, executable, preexec_fn, close_fds,
       1027β”‚                                 pass_fds, cwd, env,
       1028β”‚                                 startupinfo, creationflags, shell,

  OSError

  [WinError 193] %1 δΈζ˜―ζœ‰ζ•ˆηš„ Win32 應用程式。

  at ~\.pyenv\pyenv-win\versions\3.12.0b4\Lib\subprocess.py:1538 in _execute_child
      1534β”‚             sys.audit("subprocess.Popen", executable, args, cwd, env)
      1535β”‚
      1536β”‚             # Start the process
      1537β”‚             try:
    β†’ 1538β”‚                 hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
      1539β”‚                                          # no special security
      1540β”‚                                          None, None,
      1541β”‚                                          int(not close_fds),
      1542β”‚                                          creationflags,
FabianToledo commented 10 months ago

It happens to me too, but is not only when virtualenvs.prefer-active-python is set to true.

for instance: Poetry version: 1.6.1 Python version: 3.12.0 OS version and name: Window 11 pyenv: 3.1.1 (installed when python 3.12.0 was configured as global in pyenv)

Changed to python 3.11.6

pyenv global 3.11.6 pyenv versions

  • 3.11.6 (set by %USERPROFILE%.pyenv\pyenv-win\version) 3.12.0

In a new folder run poetry new:

poetry new .

Then edit my newly generated pyproject.toml to use python ~3.11

[tool.poetry]
name = "test"
version = "0.1.0"
description = ""
authors = [""]
readme = "README.md"

[tool.poetry.dependencies]
python = "~3.11"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Then executing either poetry shell, poetry install or any command that tries to create the venv returns this:

The currently activated Python version 3.12.0 is not supported by the project (~3.11).
Trying to find and use a compatible version.

[WinError 193] %1 is not a valid Win32 application

poetry shell -vvv


Loading configuration file C:\Users\Fa\AppData\Roaming\pypoetry\config.toml
The currently activated Python version 3.12.0 is not supported by the project (~3.11).
Trying to find and use a compatible version.
Trying python3

Stack trace:

13 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:327 in run 325β”‚ 326β”‚ try: β†’ 327β”‚ exit_code = self._run(io) 328β”‚ except BrokenPipeError: 329β”‚ # If we are piped to another process, it may close early and send a

12 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\console\application.py:190 in _run 188β”‚ self._load_plugins(io) 189β”‚ β†’ 190β”‚ exit_code: int = super()._run(io) 191β”‚ return exit_code 192β”‚

11 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:431 in _run 429β”‚ io.input.interactive(interactive) 430β”‚ β†’ 431β”‚ exit_code = self._run_command(command, io) 432β”‚ self._running_command = None 433β”‚

10 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:473 in _run_command 471β”‚ 472β”‚ if error is not None: β†’ 473β”‚ raise error 474β”‚ 475β”‚ return terminate_event.exit_code

9 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\application.py:454 in _run_command 452β”‚ 453β”‚ try: β†’ 454β”‚ self._event_dispatcher.dispatch(command_event, COMMAND) 455β”‚ 456β”‚ if command_event.command_should_run():

8 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\events\event_dispatcher.py:26 in dispatch 24β”‚ 25β”‚ if listeners: β†’ 26β”‚ self._do_dispatch(listeners, event_name, event) 27β”‚ 28β”‚ return event

7 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\cleo\events\event_dispatcher.py:89 in _do_dispatch 87β”‚ break 88β”‚ β†’ 89β”‚ listener(event, event_name, self) 90β”‚ 91β”‚ def _sort_listeners(self, event_name: str) -> None:

6 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\console\application.py:299 in configure_env 297β”‚ 298β”‚ env_manager = EnvManager(poetry, io=io) β†’ 299β”‚ env = env_manager.create_venv() 300β”‚ 301β”‚ if env.is_venv() and io.is_verbose():

5 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:514 in create_venv 512β”‚ self._io.write_error_line(f"Trying {python_name}") 513β”‚ β†’ 514β”‚ python = self._full_python_path(python_name) 515β”‚ if python is None: 516β”‚ continue

4 ~\AppData\Roaming\pypoetry\venv\Lib\site-packages\poetry\utils\env\env_manager.py:69 in _full_python_path 67β”‚ 68β”‚ try: β†’ 69β”‚ executable = subprocess.check_output( 70β”‚ [path_python, "-c", "import sys; print(sys.executable)"], text=True 71β”‚ ).strip()

3 ~.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:466 in check_output 464β”‚ kwargs['input'] = empty 465β”‚ β†’ 466β”‚ return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, 467β”‚ **kwargs).stdout 468β”‚

2 ~.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:548 in run 546β”‚ kwargs['stderr'] = PIPE 547β”‚ β†’ 548β”‚ with Popen(*popenargs, **kwargs) as process: 549β”‚ try: 550β”‚ stdout, stderr = process.communicate(input, timeout=timeout)

1 ~.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:1026 in init 1024β”‚ encoding=encoding, errors=errors) 1025β”‚ β†’ 1026β”‚ self._execute_child(args, executable, preexec_fn, close_fds, 1027β”‚ pass_fds, cwd, env, 1028β”‚ startupinfo, creationflags, shell,

OSError

[WinError 193] %1 is not a valid Win32 application

at ~.pyenv\pyenv-win\versions\3.12.0\Lib\subprocess.py:1538 in _execute_child 1534β”‚ sys.audit("subprocess.Popen", executable, args, cwd, env) 1535β”‚ 1536β”‚ # Start the process 1537β”‚ try: β†’ 1538β”‚ hp, ht, pid, tid = _winapi.CreateProcess(executable, args, 1539β”‚ # no special security 1540β”‚ None, None, 1541β”‚ int(not close_fds), 1542β”‚ creationflags,


I have found a workaround if (having configured global in pyenv 3.11.6) execute:

> poetry env use python.bat

Note that the extension `.bat` is added to the end of `python`

Creating virtualenv test in D:\Python\test.venv Using virtualenv: D:\Python\test.venv

> poetry env info

Virtualenv Python: 3.11.6 Implementation: CPython Path: D:\Python\test.venv Executable: D:\Python\test.venv\Scripts\python.exe Valid: True

System Platform: win32 OS: nt Python: 3.11.6 Path: C:\Users*.pyenv\pyenv-win\versions\3.11.6 Executable: C:\Users*.pyenv\pyenv-win\versions\3.11.6\python.exe


The location of `python.bat` and its contents are:
> where python.bat

C:\Users**.pyenv\pyenv-win\shims\python.bat

Contents:

@echo off chcp 1250 > NUL call pyenv exec %~n0 %*

dimbleby commented 10 months ago

if I were you I would put some print statements in EnvManager._full_python_path() to see what it is doing. The windows error is strangely unhelpful (what is %1?)

perhaps that method should catch OSError?

franceschiniandrea commented 9 months ago

I get the same error, I'm on Windows 10

gsfaller commented 5 months ago

I also get the same error. I'm on Windows 11.

tamireinhorn commented 5 months ago

Having the same issue as well on Windows 11.

dimbleby commented 5 months ago

Folks, "I am also hitting this" does not make any progress.

One of you who is having a problem will need to put in some work to debug eg https://github.com/python-poetry/poetry/issues/8229#issuecomment-1774626721

rfaels commented 4 months ago

Having the same issue as well on Windows 11.

the-xentropy commented 1 month ago

I was hitting this also, but to progress this along a bit ;) let me leave a bit more info:

Virtualenv
Python:         3.12.0
Implementation: CPython
Path:           C:\Users\x\AppData\Local\pypoetry\Cache\virtualenvs\x-O5vkSaiN-py3.12
Executable:     C:\Users\x\AppData\Local\pypoetry\Cache\virtualenvs\x-O5vkSaiN-py3.12\Scripts\python.exe
Valid:          True

Base
Platform:   win32
OS:         nt
Python:     3.12.0
Path:       C:\Users\x\.conda\envs\pipx
Executable: C:\Users\x\.conda\envs\pipx\python.exe

I was getting this cryptic [WinError 193] %1 is not a valid Win32 application. error in association with trying to switch the Python interpreter (poetry env use 3.10) to a version I know is installed but it seems poetry was struggling to find it. I solved it by first deleting the poetry environment (poetry env list and then poetry env remove x-O5vkSaiN-py3.12), then running poetry env use "C:\Users\x\.pyenv\pyenv-win\versions\3.10.11\python.exe" - i.e. using the full path. I had to delete the environment because I was running into an circular dependency catch-22 where it was refusing to let me change the version because I didn't have a valid version in my pyproject.toml - or maybe I misunderstood something, but either way deleting it before switching the python executable worked for me.

To the best of my knowledge, WinError 193 occurs when an attempt to execute a non-executable file is made, and given that my problem was resolved by more explicitly pointing it to a correct python.exe, I think this issue is from failing to resolve to the correct python interpreter. The %1 hints that the executable path/filename provided wasn't valid (first argument to spawn a process), so I imagine the error message occurred for the OP because the behavior virtualenvs.prefer-active-python enables fails to point to fill in a valid value for that argument.

I'd encourage everyone running into this issue to try find the python.exe they explicitly want to use and then using poetry env use "<path>\python.exe", rather than relying on any built-in python resolution mechanisms.

the-xentropy commented 1 month ago

As an aside, it took me embarrassingly long to realize that I could use an absolute path for the python executable in 'env use'.

Description:
  Activates or creates a new virtualenv for the current project.

Usage:
  env use [options] [--] <python>

Arguments:
  python                     The python executable to use.

Part of the confusion is because in documentation online values like 3.12 are valid values for the python argument but this doesn't map to any actual executable on my system, so I naturally assumed it was a more ambiguous definition of 'executable'. Could we perhaps change the documentation to e.g:

Description:
  Activates or creates a new virtualenv for the current project.

Usage:
  env use [options] [--] <python>

Arguments:
  python                     The python executable to use. Accepts an absolute path, or a version string.
                                   If version string is used, poetry will try but may fail to find the corresponding version.