Skip to content

Commit 94bd66d

Browse files
committed
Revert StreamWrapper removal to restore Python 3.9.{0,6} compat
Partial revert of commit 502d08c which is incompatible with Python 3.9.6 and older.
1 parent 38253a6 commit 94bd66d

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

news/13364.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash on Python 3.9.6 and lower when pip failed to compile a Python module
2+
during installation.

src/pip/_internal/operations/install/wheel.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import warnings
1414
from base64 import urlsafe_b64encode
1515
from email.message import Message
16-
from io import StringIO
1716
from itertools import chain, filterfalse, starmap
1817
from typing import (
1918
IO,
@@ -50,7 +49,7 @@
5049
from pip._internal.models.direct_url import DIRECT_URL_METADATA_NAME, DirectUrl
5150
from pip._internal.models.scheme import SCHEME_KEYS, Scheme
5251
from pip._internal.utils.filesystem import adjacent_tmp_file, replace
53-
from pip._internal.utils.misc import ensure_dir, hash_file, partition
52+
from pip._internal.utils.misc import StreamWrapper, ensure_dir, hash_file, partition
5453
from pip._internal.utils.unpacking import (
5554
current_umask,
5655
is_within_directory,
@@ -607,7 +606,9 @@ def pyc_output_path(path: str) -> str:
607606

608607
# Compile all of the pyc files for the installed files
609608
if pycompile:
610-
with contextlib.redirect_stdout(StringIO()) as stdout:
609+
with contextlib.redirect_stdout(
610+
StreamWrapper.from_stream(sys.stdout)
611+
) as stdout:
611612
with warnings.catch_warnings():
612613
warnings.filterwarnings("ignore")
613614
for path in pyc_source_file_paths():

src/pip/_internal/utils/misc.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import urllib.parse
1212
from dataclasses import dataclass
1313
from functools import partial
14+
from io import StringIO
1415
from itertools import filterfalse, tee, zip_longest
1516
from pathlib import Path
1617
from types import FunctionType, TracebackType
@@ -25,6 +26,7 @@
2526
Mapping,
2627
Optional,
2728
Sequence,
29+
TextIO,
2830
Tuple,
2931
Type,
3032
TypeVar,
@@ -373,6 +375,22 @@ def write_output(msg: Any, *args: Any) -> None:
373375
logger.info(msg, *args)
374376

375377

378+
class StreamWrapper(StringIO):
379+
orig_stream: TextIO
380+
381+
@classmethod
382+
def from_stream(cls, orig_stream: TextIO) -> "StreamWrapper":
383+
ret = cls()
384+
ret.orig_stream = orig_stream
385+
return ret
386+
387+
# compileall.compile_dir() needs stdout.encoding to print to stdout
388+
# type ignore is because TextIOBase.encoding is writeable
389+
@property
390+
def encoding(self) -> str: # type: ignore
391+
return self.orig_stream.encoding
392+
393+
376394
# Simulates an enum
377395
def enum(*sequential: Any, **named: Any) -> Type[Any]:
378396
enums = dict(zip(sequential, range(len(sequential))), **named)

0 commit comments

Comments
 (0)