Skip to content

Commit

Permalink
Merge pull request #2066 from Textualize/windows-capture-fix
Browse files Browse the repository at this point in the history
Handle recording on legacy mode Windows consoles
  • Loading branch information
willmcgugan committed Mar 18, 2022
2 parents 7a0310f + 98969ab commit 0c24e4f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 15 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fix capturing stdout on legacy Windows https://github.com/Textualize/rich/pull/2055
- Fix capturing stdout on legacy Windows https://github.com/Textualize/rich/pull/2066

## [12.0.0] - 2022-03-10

Expand Down
2 changes: 1 addition & 1 deletion rich/_win32_console.py
Expand Up @@ -334,7 +334,7 @@ class LegacyWindowsTerm:
15, # bright white
]

def __init__(self, file: IO[str]) -> None:
def __init__(self, file: "IO[str]") -> None:
handle = GetStdHandle(STDOUT)
self._handle = handle
default_text = GetConsoleScreenBufferInfo(handle).wAttributes
Expand Down
42 changes: 29 additions & 13 deletions rich/console.py
Expand Up @@ -82,6 +82,15 @@ class NoChange:

NO_CHANGE = NoChange()

try:
_STDOUT_FILENO = sys.__stdout__.fileno()
except Exception:
_STDOUT_FILENO = 1

try:
_STDERR_FILENO = sys.__stderr__.fileno()
except Exception:
_STDERR_FILENO = 2

CONSOLE_HTML_FORMAT = """\
<!DOCTYPE html>
Expand Down Expand Up @@ -1909,12 +1918,21 @@ def log(
buffer_extend(line)

def _check_buffer(self) -> None:
"""Check if the buffer may be rendered."""
"""Check if the buffer may be rendered. Render it if it can (e.g. Console.quiet is False)
Rendering is supported on Windows, Unix and Jupyter environments. For
legacy Windows consoles, the win32 API is called directly.
This method will also record what it renders if recording is enabled via Console.record.
"""
if self.quiet:
del self._buffer[:]
return
with self._lock:
if self._buffer_index == 0:

if self.record:
with self._record_buffer_lock:
self._record_buffer.extend(self._buffer[:])

if self.is_jupyter: # pragma: no cover
from .jupyter import display

Expand All @@ -1927,18 +1945,19 @@ def _check_buffer(self) -> None:
except (ValueError, io.UnsupportedOperation):
file_no = -1

legacy_windows_stdout = self.legacy_windows and file_no == 1
if legacy_windows_stdout:
stdout_num = _STDOUT_FILENO
stderr_num = _STDERR_FILENO
is_std_stream = file_no in (stdout_num, stderr_num)
legacy_windows_std = self.legacy_windows and is_std_stream
if legacy_windows_std:
from rich._win32_console import LegacyWindowsTerm
from rich._windows_renderer import legacy_windows_render

with open(file_no, "w") as output_file:
legacy_windows_render(
self._buffer[:], LegacyWindowsTerm(output_file)
)

output_capture_enabled = bool(self._buffer_index)
if not legacy_windows_stdout or output_capture_enabled:
legacy_windows_render(
self._buffer[:], LegacyWindowsTerm(self.file)
)
else:
# Either a non-std stream on legacy Windows, or modern Windows.
text = self._render_buffer(self._buffer[:])
# https://bugs.python.org/issue37871
write = self.file.write
Expand All @@ -1965,9 +1984,6 @@ def _render_buffer(self, buffer: Iterable[Segment]) -> str:
append = output.append
color_system = self._color_system
legacy_windows = self.legacy_windows
if self.record:
with self._record_buffer_lock:
self._record_buffer.extend(buffer)
not_terminal = not self.is_terminal
if self.no_color and color_system:
buffer = Segment.remove_color(buffer)
Expand Down

0 comments on commit 0c24e4f

Please sign in to comment.