Repository: python-poetry/poetry

Issue:
UTF-8 path-chars Encoding Issue during poetry install
<!--
    Hi there! Thank you for submitting a bug report!

    Before you submit your issue, please review and follow the instructions at
    https://python-poetry.org/docs/contributing/#reporting-bugs. Fully fill out the template below; insufficient
    information or bad reproduction instructions will impair the ability of others to help you.
-->

<!-- All the below information must be provided for others to understand and help with your issue. -->
- **Poetry version**: 1.6.1
- **Python version**: 3.11.6
- **OS version and name**: Windows 11 Version	10.0.22621 Build 22621
- **pyproject.toml**:  https://gist.github.com/etaMS20/225f460367c540dfc7390a200ee370b8

<!-- All the below steps should be completed before submitting your issue. Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) stable Poetry version, installed using a recommended method.
- [X] I have searched the [issues](https://github.com/python-poetry/poetry/issues) of this repo and believe that this is not a duplicate.
- [X] I have consulted the [FAQ](https://python-poetry.org/docs/faq/) and [blog](https://python-poetry.org/blog/) for any relevant entries or release notes.
- [X] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option) and have included the output below.

## Issue
<!-- Now feel free to write your issue, and please be as descriptive as possible! Make sure to include detailed reproduction steps. -->
<!-- Thanks again 🙌 ❤ -->

Hello,

there seems to be an Issue with UTF-8 Encoding during dynamic installation process of packages.
My Path contains a special character (ä), seems like that caused the problem during reading from `stdin` (no encoding declared). 
I know its bad practice to have that in path but i use a company domain and user-path is auto-set by windows during startup :<.

(I was able to bypass this issue by downgrading to poetry 1.5.1)

**Trace back:**

```shell
poetry install
Installing dependencies from lock file

Package operations: 69 installs, 1 update, 0 removals

  • Installing certifi (2023.7.22)
  • Installing charset-normalizer (3.3.0)
  • Installing idna (3.4)
  • Installing urllib3 (2.0.6)

  CalledProcessError

  Command '['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-']' returned non-zero exit status 1.

  at C:\Python\Lib\subprocess.py:571 in run
       567|             # We don't call process.wait() as .__exit__ does that for us.
       568|             raise
       569|         retcode = process.poll()
       570|         if check and retcode:
    >  571|             raise CalledProcessError(retcode, process.args,
       572|                                      output=stdout, stderr=stderr)
       573|     return CompletedProcess(process.args, retcode, stdout, stderr)
       574| 
       575| 

The following error occurred when trying to handle this error:


  EnvCommandError

  Command ['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-'] errored with the following return code 1
  
  Error output:
  SyntaxError: Non-UTF-8 code starting with '\xe4' in file <stdin> on line 9, but no encoding declared; see https://peps.python.org/pep-0263/ for details
  
  
  Input:
  
  import importlib.util
  import json
  import sys
  
  from pathlib import Path
  
  spec = importlib.util.spec_from_file_location(
      "packaging", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\__init__.py")
  )
  packaging = importlib.util.module_from_spec(spec)
  sys.modules[spec.name] = packaging
  
  spec = importlib.util.spec_from_file_location(
      "packaging.tags", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\tags.py")
  )
  packaging_tags = importlib.util.module_from_spec(spec)
  spec.loader.exec_module(packaging_tags)
  
  print(
      json.dumps([(t.interpreter, t.abi, t.platform) for t in packaging_tags.sys_tags()])
  )
  

  at C:\Python\Lib\site-packages\poetry\utils\env\base_env.py:363 in _run
      359|                 output = subprocess.check_output(
      360|                     cmd, stderr=stderr, env=env, text=True, **kwargs
      361|                 )
      362|         except CalledProcessError as e:
    > 363|             raise EnvCommandError(e, input=input_)
      364| 
      365|         return output
      366| 
      367|     def execute(self, bin: str, *args: str, **kwargs: Any) -> int:


  CalledProcessError

  Command '['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-']' returned non-zero exit status 1.

  at C:\Python\Lib\subprocess.py:571 in run
       567|             # We don't call process.wait() as .__exit__ does that for us.
       568|             raise
       569|         retcode = process.poll()
       570|         if check and retcode:
    >  571|             raise CalledProcessError(retcode, process.args,
       572|                                      output=stdout, stderr=stderr)
       573|     return CompletedProcess(process.args, retcode, stdout, stderr)
       574| 
       575| 

The following error occurred when trying to handle this error:


  EnvCommandError

  Command ['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-'] errored with the following return code 1
  
  Error output:
  SyntaxError: Non-UTF-8 code starting with '\xe4' in file <stdin> on line 9, but no encoding declared; see https://peps.python.org/pep-0263/ for details
  
  
  Input:
  
  import importlib.util
  import json
  import sys
  
  from pathlib import Path
  
  spec = importlib.util.spec_from_file_location(
      "packaging", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\__init__.py")
  )
  packaging = importlib.util.module_from_spec(spec)
  sys.modules[spec.name] = packaging
  
  spec = importlib.util.spec_from_file_location(
      "packaging.tags", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\tags.py")
  )
  packaging_tags = importlib.util.module_from_spec(spec)
  spec.loader.exec_module(packaging_tags)
  
  print(
      json.dumps([(t.interpreter, t.abi, t.platform) for t in packaging_tags.sys_tags()])
  )
  

  at C:\Python\Lib\site-packages\poetry\utils\env\base_env.py:363 in _run
      359|                 output = subprocess.check_output(
      360|                     cmd, stderr=stderr, env=env, text=True, **kwargs
      361|                 )
      362|         except CalledProcessError as e:
    > 363|             raise EnvCommandError(e, input=input_)
      364| 
      365|         return output
      366| 
      367|     def execute(self, bin: str, *args: str, **kwargs: Any) -> int:


  CalledProcessError

  Command '['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-']' returned non-zero exit status 1.

  at C:\Python\Lib\subprocess.py:571 in run
       567|             # We don't call process.wait() as .__exit__ does that for us.
       568|             raise
       569|         retcode = process.poll()
       570|         if check and retcode:
    >  571|             raise CalledProcessError(retcode, process.args,
       572|                                      output=stdout, stderr=stderr)
       573|     return CompletedProcess(process.args, retcode, stdout, stderr)
       574| 
       575| 

The following error occurred when trying to handle this error:


  EnvCommandError

  Command ['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-'] errored with the following return code 1
  
  Error output:
  SyntaxError: Non-UTF-8 code starting with '\xe4' in file <stdin> on line 9, but no encoding declared; see https://peps.python.org/pep-0263/ for details
  
  
  Input:
  
  import importlib.util
  import json
  import sys
  
  from pathlib import Path
  
  spec = importlib.util.spec_from_file_location(
      "packaging", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\__init__.py")
  )
  packaging = importlib.util.module_from_spec(spec)
  sys.modules[spec.name] = packaging
  
  spec = importlib.util.spec_from_file_location(
      "packaging.tags", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\tags.py")
  )
  packaging_tags = importlib.util.module_from_spec(spec)
  spec.loader.exec_module(packaging_tags)
  
  print(
      json.dumps([(t.interpreter, t.abi, t.platform) for t in packaging_tags.sys_tags()])
  )
  

  at C:\Python\Lib\site-packages\poetry\utils\env\base_env.py:363 in _run
      359|                 output = subprocess.check_output(
      360|                     cmd, stderr=stderr, env=env, text=True, **kwargs
      361|                 )
      362|         except CalledProcessError as e:
    > 363|             raise EnvCommandError(e, input=input_)
      364| 
      365|         return output
      366| 
      367|     def execute(self, bin: str, *args: str, **kwargs: Any) -> int:


  CalledProcessError

  Command '['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-']' returned non-zero exit status 1.

  at C:\Python\Lib\subprocess.py:571 in run
       567|             # We don't call process.wait() as .__exit__ does that for us.
       568|             raise
       569|         retcode = process.poll()
       570|         if check and retcode:
    >  571|             raise CalledProcessError(retcode, process.args,
       572|                                      output=stdout, stderr=stderr)
       573|     return CompletedProcess(process.args, retcode, stdout, stderr)
       574| 
       575| 

The following error occurred when trying to handle this error:


  EnvCommandError

  Command ['C:\\Users\\MalvinSchädle\\AppData\\Local\\pypoetry\\Cache\\virtualenvs\\eta-control-fKGJYgDt-py3.11\\Scripts\\python.exe', '-I', '-W', 'ignore', '-'] errored with the following return code 1
  
  Error output:
  SyntaxError: Non-UTF-8 code starting with '\xe4' in file <stdin> on line 9, but no encoding declared; see https://peps.python.org/pep-0263/ for details
  
  
  Input:
  
  import importlib.util
  import json
  import sys
  
  from pathlib import Path
  
  spec = importlib.util.spec_from_file_location(
      "packaging", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\__init__.py")
  )
  packaging = importlib.util.module_from_spec(spec)
  sys.modules[spec.name] = packaging
  
  spec = importlib.util.spec_from_file_location(
      "packaging.tags", Path(r"C:\Users\MalvinSchädle\AppData\Roaming\Python\Python311\site-packages\packaging\tags.py")
  )
  packaging_tags = importlib.util.module_from_spec(spec)
  spec.loader.exec_module(packaging_tags)
  
  print(
      json.dumps([(t.interpreter, t.abi, t.platform) for t in packaging_tags.sys_tags()])
  )
  

  at C:\Python\Lib\site-packages\poetry\utils\env\base_env.py:363 in _run
      359|                 output = subprocess.check_output(
      360|                     cmd, stderr=stderr, env=env, text=True, **kwargs
      361|                 )
      362|         except CalledProcessError as e:
    > 363|             raise EnvCommandError(e, input=input_)
      364| 
      365|         return output
      366| 
      367|     def execute(self, bin: str, *args: str, **kwargs: Any) -> int:
``` 



Discussion:
probably wants an explicit `encoding="utf-8"` on the subprocess calls that pass `text=True`.  Suggest try that and if it works merge request surely welcome.
@dimbleby Hi. Thanks for addressing it. I've only checked `base_env` module, but [_run](https://github.com/python-poetry/poetry/blob/611033a7335f3c8e2b74dd58688fb9021cf84a5b/src/poetry/utils/env/base_env.py#L336) appears to be called only for invoking pip or python. So my suggestion is forcing Python to output everything in utf-8 by setting `env["PYTHONENCODING"] = "utf-8"` before calling  `subprocess.run`. This hack worked when I addressed a similar issue in [poethepoet](https://github.com/nat-n/poethepoet/pull/112). Any concerns?
I don't understand your concern - what do you think goes wrong if adding the parameter to subprocess calls?

prefer explicit parameters, clearer what they're for
also I don't _think_ that your suggestion addresses the issue reported here.  AIUI the question isn't whether the python subprocess is expecting or producing utf-8, the question is how the input to that python subprocess - `GET_SYS_TAGS` - is encoded.
@dimbleby  I completely misunderstood. OK, I see that the problem reported in this ticket is about the encoding which is handled not by the child python but by the _parent_ one. Thanks for explaining it and I apologize for troubling you.

Nevertheless, for your information, I'll put another potential problem here that might appear after you set encoding of subprocess. Please see the following script:

```python
# encoding_test.py
import os
import subprocess
import sys
from typing import Optional

env = dict(os.environ)
counter = 1

def run(enable_i_option: bool, encoding: Optional[str], input: str, env: dict):
    global counter
    print(counter)
    counter += 1
    cmd = [sys.executable] + (["-I"] if enable_i_option else []) + ['-W', 'ignore', '-']
    try:
        output = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            input=input,
            check=True,
            env=env,
            text=True,
            encoding=encoding,
        ).stdout
        print(output)
    except Exception:
        print(sys.exc_info()[1])


# ASCII input
run(True, None, 'print("OK")', env)
# Your solution here for non-ascii input
run(True, "utf-8", 'print("ÖK")', env)
# My suggestion
run(False, "utf-8", 'print("ÖK")', env | {"PYTHONIOENCODING": "utf-8"})
```

In my Windows (Japanese) environment, the output of `python encoding_test.py` is as follows:

```
1
OK

2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'cp932' codec can't encode character '\xd6' in position 0: illegal multibyte sequence
Command '['C:\\Users\\hugov\\.pyenv\\pyenv-win\\versions\\3.11.1\\python.exe', '-I', '-W', 'ignore', '-']' returned non-zero exit status 1.
3
ÖK
```

On the other hand, in Ubuntu (WSL), the output causes no problem.
```
1
OK

2
ÖK

3
ÖK
```

Your environment will produce the latter, I guess, while in some environment, the child python doesn't assume utf-8 unless forced.

I haven't checked if it __actually__ produces an error after fixing poetry as you suggest. Sorry if I still misunderstand all of that.
I'm not a windows user and don't have non-ascii characters in my path so I'm not well placed to do anything with this issue and also don't much care about it anyway.

I could believe that it might be necessary _both_ to encode strings as utf8 from the parent python, and also to ask the child python to do the same.  Or it might not, I'm really not sure.

Recommend that if you - or any other reader - are hitting problems here: try either or both fixes, and submit a merge request!
I will take a look at this when i find time.
I would also not prefer to have 'ä' in any path but as i use a company
domain for windows license, the user root path gets auto-named when
installing windows through the domain.
For now I just downgraded to poetry 1.5.1, which does not produce this
issue and consulted my domain admin to replace the special characters in
the name-reference of my windows license^^

Greetings

On Fri, Oct 20, 2023 at 12:46 PM David Hotham ***@***.***>
wrote:

> I'm not a windows user and don't have non-ascii characters in my path so
> I'm not well placed to do anything with this issue and also don't much care
> about it anyway.
>
> I could believe that it might be necessary *both* to encode strings as
> utf8 from the parent python, and also to ask the child python to do the
> same. Or it might not, I'm really not sure.
>
> Recommend that if you - or any other reader - are hitting problems here:
> try either or both fixes, and submit a merge request!
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/python-poetry/poetry/issues/8550#issuecomment-1772512695>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/A7K7SL4VWW2RXXV64QXSPATYAJI7XAVCNFSM6AAAAAA6FCXOXCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZSGUYTENRZGU>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>

FYI: I realized that I didn't need to drop `-I` option but just adding [-X utf8](https://docs.python.org/3/using/cmdline.html#cmdoption-X) and forcing the UTF-8 mode would suffice.

Resolving patch:
diff --git a/src/poetry/inspection/info.py b/src/poetry/inspection/info.py
--- a/src/poetry/inspection/info.py
+++ b/src/poetry/inspection/info.py
@@ -586,11 +586,7 @@ def get_pep517_metadata(path: Path) -> PackageInfo:
                 "--no-input",
                 *PEP517_META_BUILD_DEPS,
             )
-            venv.run(
-                "python",
-                "-",
-                input_=pep517_meta_build_script,
-            )
+            venv.run_python_script(pep517_meta_build_script)
             info = PackageInfo.from_metadata(dest_dir)
         except EnvCommandError as e:
             # something went wrong while attempting pep517 metadata build
diff --git a/src/poetry/utils/env/base_env.py b/src/poetry/utils/env/base_env.py
--- a/src/poetry/utils/env/base_env.py
+++ b/src/poetry/utils/env/base_env.py
@@ -327,8 +327,8 @@ def run_python_script(self, content: str, **kwargs: Any) -> str:
             "-I",
             "-W",
             "ignore",
-            "-",
-            input_=content,
+            "-c",
+            content,
             stderr=subprocess.PIPE,
             **kwargs,
         )
@@ -338,23 +338,11 @@ def _run(self, cmd: list[str], **kwargs: Any) -> str:
         Run a command inside the Python environment.
         """
         call = kwargs.pop("call", False)
-        input_ = kwargs.pop("input_", None)
         env = kwargs.pop("env", dict(os.environ))
         stderr = kwargs.pop("stderr", subprocess.STDOUT)
 
         try:
-            if input_:
-                output: str = subprocess.run(
-                    cmd,
-                    stdout=subprocess.PIPE,
-                    stderr=stderr,
-                    input=input_,
-                    check=True,
-                    env=env,
-                    text=True,
-                    **kwargs,
-                ).stdout
-            elif call:
+            if call:
                 assert stderr != subprocess.PIPE
                 subprocess.check_call(cmd, stderr=stderr, env=env, **kwargs)
                 output = ""
@@ -363,7 +351,7 @@ def _run(self, cmd: list[str], **kwargs: Any) -> str:
                     cmd, stderr=stderr, env=env, text=True, **kwargs
                 )
         except CalledProcessError as e:
-            raise EnvCommandError(e, input=input_)
+            raise EnvCommandError(e)
 
         return output
 
diff --git a/src/poetry/utils/env/exceptions.py b/src/poetry/utils/env/exceptions.py
--- a/src/poetry/utils/env/exceptions.py
+++ b/src/poetry/utils/env/exceptions.py
@@ -20,7 +20,7 @@ def __init__(self, env_name: str) -> None:
 
 
 class EnvCommandError(EnvError):
-    def __init__(self, e: CalledProcessError, input: str | None = None) -> None:
+    def __init__(self, e: CalledProcessError) -> None:
         self.e = e
 
         message_parts = [
@@ -30,8 +30,6 @@ def __init__(self, e: CalledProcessError, input: str | None = None) -> None:
             message_parts.append(f"Output:\n{decode(e.output)}")
         if e.stderr:
             message_parts.append(f"Error output:\n{decode(e.stderr)}")
-        if input:
-            message_parts.append(f"Input:\n{input}")
         super().__init__("\n\n".join(message_parts))
 
 


Test patch:
diff --git a/tests/console/commands/env/helpers.py b/tests/console/commands/env/helpers.py
--- a/tests/console/commands/env/helpers.py
+++ b/tests/console/commands/env/helpers.py
@@ -24,17 +24,28 @@ def check_output_wrapper(
 ) -> Callable[[list[str], Any, Any], str]:
     def check_output(cmd: list[str], *args: Any, **kwargs: Any) -> str:
         # cmd is a list, like ["python", "-c", "do stuff"]
-        python_cmd = cmd[2]
+        python_cmd = cmd[-1]
+        if "print(json.dumps(env))" in python_cmd:
+            return (
+                f'{{"version_info": [{version.major}, {version.minor},'
+                f" {version.patch}]}}"
+            )
+
         if "sys.version_info[:3]" in python_cmd:
             return version.text
-        elif "sys.version_info[:2]" in python_cmd:
+
+        if "sys.version_info[:2]" in python_cmd:
             return f"{version.major}.{version.minor}"
-        elif "import sys; print(sys.executable)" in python_cmd:
+
+        if "import sys; print(sys.executable)" in python_cmd:
             executable = cmd[0]
             basename = os.path.basename(executable)
             return f"/usr/bin/{basename}"
-        else:
-            assert "import sys; print(sys.prefix)" in python_cmd
-            return "/prefix"
+
+        if "print(sys.base_prefix)" in python_cmd:
+            return "/usr"
+
+        assert "import sys; print(sys.prefix)" in python_cmd
+        return "/prefix"
 
     return check_output
diff --git a/tests/utils/test_env.py b/tests/utils/test_env.py
--- a/tests/utils/test_env.py
+++ b/tests/utils/test_env.py
@@ -21,7 +21,6 @@
 from poetry.toml.file import TOMLFile
 from poetry.utils._compat import WINDOWS
 from poetry.utils._compat import metadata
-from poetry.utils.env import GET_BASE_PREFIX
 from poetry.utils.env import GET_PYTHON_VERSION_ONELINER
 from poetry.utils.env import EnvCommandError
 from poetry.utils.env import EnvManager
@@ -134,17 +133,6 @@ def test_env_commands_with_spaces_in_their_arg_work_as_expected(
     )
 
 
-def test_env_shell_commands_with_stdinput_in_their_arg_work_as_expected(
-    tmp_path: Path, manager: EnvManager
-) -> None:
-    venv_path = tmp_path / "Virtual Env"
-    manager.build_venv(venv_path)
-    venv = VirtualEnv(venv_path)
-    run_output_path = Path(venv.run("python", "-", input_=GET_BASE_PREFIX).strip())
-    venv_base_prefix_path = Path(str(venv.get_base_prefix()))
-    assert run_output_path.resolve() == venv_base_prefix_path.resolve()
-
-
 def test_env_get_supported_tags_matches_inside_virtualenv(
     tmp_path: Path, manager: EnvManager
 ) -> None:
@@ -195,18 +183,29 @@ def check_output_wrapper(
 ) -> Callable[[list[str], Any, Any], str]:
     def check_output(cmd: list[str], *args: Any, **kwargs: Any) -> str:
         # cmd is a list, like ["python", "-c", "do stuff"]
-        python_cmd = cmd[2]
+        python_cmd = cmd[-1]
+        if "print(json.dumps(env))" in python_cmd:
+            return (
+                f'{{"version_info": [{version.major}, {version.minor},'
+                f" {version.patch}]}}"
+            )
+
         if "sys.version_info[:3]" in python_cmd:
             return version.text
-        elif "sys.version_info[:2]" in python_cmd:
+
+        if "sys.version_info[:2]" in python_cmd:
             return f"{version.major}.{version.minor}"
-        elif "import sys; print(sys.executable)" in python_cmd:
+
+        if "import sys; print(sys.executable)" in python_cmd:
             executable = cmd[0]
             basename = os.path.basename(executable)
             return f"/usr/bin/{basename}"
-        else:
-            assert "import sys; print(sys.prefix)" in python_cmd
-            return "/prefix"
+
+        if "print(sys.base_prefix)" in python_cmd:
+            return "/usr"
+
+        assert "import sys; print(sys.prefix)" in python_cmd
+        return "/prefix"
 
     return check_output
 
@@ -224,22 +223,12 @@ def test_activate_in_project_venv_no_explicit_config(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[
-            ("/prefix", None),
-            ('{"version_info": [3, 7, 0]}', None),
-            ("/prefix", None),
-            ("/prefix", None),
-            ("/prefix", None),
-        ],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv)
 
     env = manager.activate("python3.7")
 
     assert env.path == tmp_path / "poetry-fixture-simple" / ".venv"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
     m.assert_called_with(
         tmp_path / "poetry-fixture-simple" / ".venv",
@@ -276,10 +265,6 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None), ("/prefix", None)],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv)
 
     env = manager.activate("python3.7")
@@ -299,7 +284,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
     assert envs[venv_name]["patch"] == "3.7.1"
 
     assert env.path == tmp_path / f"{venv_name}-py3.7"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
 
 def test_activate_fails_when_python_cannot_be_found(
@@ -346,10 +331,6 @@ def test_activate_activates_existing_virtualenv_no_envs_file(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None)],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv)
 
     env = manager.activate("python3.7")
@@ -363,7 +344,7 @@ def test_activate_activates_existing_virtualenv_no_envs_file(
     assert envs[venv_name]["patch"] == "3.7.1"
 
     assert env.path == tmp_path / f"{venv_name}-py3.7"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
 
 def test_activate_activates_same_virtualenv_with_envs_file(
@@ -391,10 +372,6 @@ def test_activate_activates_same_virtualenv_with_envs_file(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None)],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.create_venv")
 
     env = manager.activate("python3.7")
@@ -407,7 +384,7 @@ def test_activate_activates_same_virtualenv_with_envs_file(
     assert envs[venv_name]["patch"] == "3.7.1"
 
     assert env.path == tmp_path / f"{venv_name}-py3.7"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
 
 def test_activate_activates_different_virtualenv_with_envs_file(
@@ -436,10 +413,6 @@ def test_activate_activates_different_virtualenv_with_envs_file(
         "subprocess.check_output",
         side_effect=check_output_wrapper(Version.parse("3.6.6")),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv)
 
     env = manager.activate("python3.6")
@@ -457,7 +430,7 @@ def test_activate_activates_different_virtualenv_with_envs_file(
     assert envs[venv_name]["patch"] == "3.6.6"
 
     assert env.path == tmp_path / f"{venv_name}-py3.6"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
 
 def test_activate_activates_recreates_for_different_patch(
@@ -486,16 +459,6 @@ def test_activate_activates_recreates_for_different_patch(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[
-            ("/prefix", None),
-            ('{"version_info": [3, 7, 0]}', None),
-            ("/prefix", None),
-            ("/prefix", None),
-            ("/prefix", None),
-        ],
-    )
     build_venv_m = mocker.patch(
         "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv
     )
@@ -519,7 +482,7 @@ def test_activate_activates_recreates_for_different_patch(
     assert envs[venv_name]["patch"] == "3.7.1"
 
     assert env.path == tmp_path / f"{venv_name}-py3.7"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
     assert (tmp_path / f"{venv_name}-py3.7").exists()
 
 
@@ -549,10 +512,6 @@ def test_activate_does_not_recreate_when_switching_minor(
         "subprocess.check_output",
         side_effect=check_output_wrapper(Version.parse("3.6.6")),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)],
-    )
     build_venv_m = mocker.patch(
         "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv
     )
@@ -571,7 +530,7 @@ def test_activate_does_not_recreate_when_switching_minor(
     assert envs[venv_name]["patch"] == "3.6.6"
 
     assert env.path == tmp_path / f"{venv_name}-py3.6"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
     assert (tmp_path / f"{venv_name}-py3.6").exists()
 
 
@@ -664,15 +623,11 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None)],
-    )
 
     env = manager.get()
 
     assert env.path == tmp_path / f"{venv_name}-py3.7"
-    assert env.base == Path("/prefix")
+    assert env.base == Path("/usr")
 
 
 def test_list(
@@ -968,40 +923,16 @@ def test_env_has_symlinks_on_nix(tmp_path: Path, tmp_venv: VirtualEnv) -> None:
     assert os.path.islink(tmp_venv.python)
 
 
-def test_run_with_input(tmp_path: Path, tmp_venv: VirtualEnv) -> None:
-    result = tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT)
-
-    assert result == "Minimal Output\n"
-
-
-def test_run_with_input_non_zero_return(tmp_path: Path, tmp_venv: VirtualEnv) -> None:
-    with pytest.raises(EnvCommandError) as process_error:
-        # Test command that will return non-zero returncode.
-        tmp_venv.run("python", "-", input_=ERRORING_SCRIPT)
-
-    assert process_error.value.e.returncode == 1
-
-
 def test_run_with_keyboard_interrupt(
     tmp_path: Path, tmp_venv: VirtualEnv, mocker: MockerFixture
 ) -> None:
-    mocker.patch("subprocess.run", side_effect=KeyboardInterrupt())
+    mocker.patch("subprocess.check_output", side_effect=KeyboardInterrupt())
     with pytest.raises(KeyboardInterrupt):
-        tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT)
-    subprocess.run.assert_called_once()  # type: ignore[attr-defined]
-
-
-def test_call_with_input_and_keyboard_interrupt(
-    tmp_path: Path, tmp_venv: VirtualEnv, mocker: MockerFixture
-) -> None:
-    mocker.patch("subprocess.run", side_effect=KeyboardInterrupt())
-    kwargs = {"call": True}
-    with pytest.raises(KeyboardInterrupt):
-        tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT, **kwargs)
-    subprocess.run.assert_called_once()  # type: ignore[attr-defined]
+        tmp_venv.run("python", "-c", MINIMAL_SCRIPT)
+    subprocess.check_output.assert_called_once()  # type: ignore[attr-defined]
 
 
-def test_call_no_input_with_keyboard_interrupt(
+def test_call_with_keyboard_interrupt(
     tmp_path: Path, tmp_venv: VirtualEnv, mocker: MockerFixture
 ) -> None:
     mocker.patch("subprocess.check_call", side_effect=KeyboardInterrupt())
@@ -1015,31 +946,14 @@ def test_run_with_called_process_error(
     tmp_path: Path, tmp_venv: VirtualEnv, mocker: MockerFixture
 ) -> None:
     mocker.patch(
-        "subprocess.run",
-        side_effect=subprocess.CalledProcessError(
-            42, "some_command", "some output", "some error"
-        ),
-    )
-    with pytest.raises(EnvCommandError) as error:
-        tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT)
-    subprocess.run.assert_called_once()  # type: ignore[attr-defined]
-    assert "some output" in str(error.value)
-    assert "some error" in str(error.value)
-
-
-def test_call_with_input_and_called_process_error(
-    tmp_path: Path, tmp_venv: VirtualEnv, mocker: MockerFixture
-) -> None:
-    mocker.patch(
-        "subprocess.run",
+        "subprocess.check_output",
         side_effect=subprocess.CalledProcessError(
             42, "some_command", "some output", "some error"
         ),
     )
-    kwargs = {"call": True}
     with pytest.raises(EnvCommandError) as error:
-        tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT, **kwargs)
-    subprocess.run.assert_called_once()  # type: ignore[attr-defined]
+        tmp_venv.run("python", "-c", MINIMAL_SCRIPT)
+    subprocess.check_output.assert_called_once()  # type: ignore[attr-defined]
     assert "some output" in str(error.value)
     assert "some error" in str(error.value)
 
@@ -1204,7 +1118,13 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
     mocker.patch("shutil.which", side_effect=lambda py: f"/usr/bin/{py}")
     mocker.patch(
         "subprocess.check_output",
-        side_effect=["/usr/bin/python3", "3.5.3", "/usr/bin/python3.9", "3.9.0"],
+        side_effect=[
+            "/usr/bin/python3",
+            "3.5.3",
+            "/usr/bin/python3.9",
+            "3.9.0",
+            "/usr",
+        ],
     )
     m = mocker.patch(
         "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: ""
@@ -1291,7 +1211,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
 
     assert version.patch is not None
     mocker.patch("sys.version_info", (version.major, version.minor, version.patch + 1))
-    check_output = mocker.patch(
+    mocker.patch(
         "subprocess.check_output",
         side_effect=check_output_wrapper(Version.parse("3.6.9")),
     )
@@ -1301,7 +1221,6 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
 
     manager.create_venv()
 
-    assert not check_output.called
     m.assert_called_with(
         config_virtualenvs_path / f"{venv_name}-py{version.major}.{version.minor}",
         executable=None,
@@ -1403,10 +1322,6 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
         "subprocess.check_output",
         side_effect=check_output_wrapper(),
     )
-    mocker.patch(
-        "subprocess.Popen.communicate",
-        side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)],
-    )
     m = mocker.patch("poetry.utils.env.EnvManager.build_venv")
 
     manager.activate("python3.7")