[Scons-users] TypeError writing to stderror in MSCommon/Common.py [reformatted]
Joseph C. Brill
jbrill at mindspring.com
Wed Dec 4 09:55:17 EST 2019
There is a problem writing the stderr message returned by a subprocess. The
subprocess return message is a byte string while the write method for the
system stderr expects a string.
Python 3.7.4
SCons v3.1.1
Windows 7, 32-bit
SCons MSCommon/common.py Error:
TypeError: write() argument must be str, not bytes
master/src/engine/SCons/Tool/MSCommon/common.py (lines 228-238):
with popen.stderr:
stderr = popen.stderr.read()
# Extra debug logic, uncomment if necessary
# debug('get_output():stdout:%s'%stdout)
# debug('get_output():stderr:%s'%stderr)
if stderr:
# TODO: find something better to do with stderr;
# this at least prevents errors from getting swallowed.
sys.stderr.write(stderr)
In Python 3, popen.stderr.read() returns a byte sequence while
sys.stderr.write(stderr) expects a string.
As a quick fix, the following seems to work:
sys.stderr.write(stderr.decode('ascii'))
A recent upgrade of MSVS 2019 to 16.4 has not gone as smoothly as hoped.
During initialization of MSVC 2019, vcvarsall.bat ultimately calls
vsdevcmd.exe. In the 16.4 update, vsdevcmd.bat contains:
@REM Send Telemetry if user's VS is opted-in
if "%VSCMD_SKIP_SENDTELEMETRY%"=="" (
if "%VSCMD_DEBUG%" NEQ "" (
@echo [DEBUG:%~nx0] Sending telemetry
powershell.exe ... [command text removed]
) else (
START "" /B powershell.exe ... [command text removed]
)
)
Effectively, without the environment variable VSCMD_SKIP_SENDTELEMETRY
defined to be not empty, vsdevcmd.bat is launching powershell.exe to send
telemetry information to Microsoft.
The problem is that the powershell folder is not on the path. This causes a
pop-up message from windows indicating that powershell.exe cannot be found
and an error message written to stderr. It is this error message that
triggers the TypeError above. When the byte string is decoded to ascii the
message The system cannot find the file powershell.exe. is correctly
written to stderr.
Unfortunately, the windows pop-up requires user intervention to acknowledge
the message (i.e., clicking on OK to dismiss the dialog).
The larger problem is two-fold:
- Powershell.exe is not on the path by default
- The environment variable VSCMD_SKIP_SENDTELEMETRY is not passed to the
scons environment by default
If one would really like the telemetry information sent, then the powershell
folder needs to be added to the path in common.py:
# Without powershell in PATH, vcvarsall.bat has a
# "The system cannot find the file powershell.exe" error starting with
# Visual Studio 2019 16.4.
sys32_powershell_dir = os.path.join(sys32_dir, 'WindowsPowerShell',
'v1.0')
if sys32_powershell_dir not in normenv['PATH']:
normenv['PATH'] = normenv['PATH'] + os.pathsep +
sys32_powershell_dir
If one does not want telemetry information sent there are two options:
- Hard-code set VSCMD_SKIP_SENDTELEMETRY=1 in vsdevcmd.bat
- Pass the VSCMD_SKIP_SENDTELEMETRY variable to the scons environment
Neither is particularly palatable.
One solution to pass VSCMD_SKIP_SENDTELEMETRY to the scons environment is to
add VSCMD_SKIP_SENDTELEMETRY to the vs_vc_vars list:
vs_vc_vars = [
'COMSPEC',
... [variables removed]
# VS 2019 16.4 calls powershell.exe unless VSCMD_SKIP_SENDTELEMETRY
is not empty
# need to either import from user environment or add powershell to
path
'VSCMD_SKIP_SENDTELEMETRY',
]
For the life of me, I cannot figure out if MSVS 2019 16.4 is supposed to set
VSCMD_SKIP_SENDTELEMETRY anywhere.
More information about the Scons-users
mailing list