Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions repos/kaleido/py/kaleido/scopes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io
import os
import sys
import locale

try:
from json import JSONDecodeError
Expand Down Expand Up @@ -34,7 +35,7 @@ def __init__(self, disable_gpu=True):
self._disable_gpu = disable_gpu

# Internal Properties
self._std_error = io.StringIO()
self._std_error = io.BytesIO()
self._std_error_thread = None
self._proc = None
self._proc_lock = Lock()
Expand Down Expand Up @@ -71,7 +72,7 @@ def _collect_standard_error(self):
"""
while True:
if self._proc is not None:
val = self._proc.stderr.readline().decode('utf-8')
val = self._proc.stderr.readline()
self._std_error.write(val)

def _ensure_kaleido(self):
Expand All @@ -88,7 +89,7 @@ def _ensure_kaleido(self):
self._proc.wait()

# Reset _std_error buffer
self._std_error = io.StringIO()
self._std_error = io.BytesIO()

# Launch kaleido subprocess
# Note: shell=True seems to be needed on Windows to handle executable path with
Expand All @@ -114,7 +115,7 @@ def _ensure_kaleido(self):
if not startup_response_string:
message = (
"Failed to start Kaleido subprocess. Error stream:\n\n" +
self._std_error.getvalue()
self._get_decoded_std_error()
)
raise ValueError(message)
else:
Expand All @@ -123,6 +124,29 @@ def _ensure_kaleido(self):
self._proc.wait()
raise ValueError(startup_response.get("message", "Failed to start Kaleido subprocess"))

def _get_decoded_std_error(self):
"""
Attempt to decode standard error bytes stream to a string
"""
std_err_str = None
try:
encoding = sys.stderr.encoding
std_err_str = self._std_error.getvalue().decode(encoding)
except Exception:
pass

if std_err_str is None:
try:
encoding = locale.getpreferredencoding(False)
std_err_str = self._std_error.getvalue().decode(encoding)
except Exception:
pass

if std_err_str is None:
std_err_str = "Failed to decode Chromium's standard error stream"

return std_err_str

def _shutdown_kaleido(self):
"""
Shut down the kaleido subprocess, if any, and self the _proc property to None
Expand Down Expand Up @@ -185,7 +209,7 @@ def _perform_transform(self, data, **kwargs):
# sure we're reading the response to our request
with self._proc_lock:
# Reset _std_error buffer
self._std_error = io.StringIO()
self._std_error = io.BytesIO()

# Write and flush spec
self._proc.stdin.write(export_spec)
Expand All @@ -197,7 +221,7 @@ def _perform_transform(self, data, **kwargs):
if not response_string:
message = (
"Transform failed. Error stream:\n\n" +
self._std_error.getvalue()
self._get_decoded_std_error()
)
raise ValueError(message)
try:
Expand Down