usdview Python interpreter fails on Windows with Python 3.14
Description
Opening the embedded Python interpreter in usdview on Windows with Python 3.14 fails.
There appear to be two separate issues in pxr/Usdviewq/pythonInterpreter.py:
PYTHONSTARTUPpaths are inserted directly into generated Python source code without escaping Windows backslashes.- The custom
Interpreter.showsyntaxerror()override is incompatible with Python 3.14, which now passes asourcekeyword argument.
Environment
OS: Windows
Python: 3.14.7
OpenUSD: built from source
usdview: PySide6
OpenUSD install path:
D:\Bibliotheken\OpenUSD\install_py314
Steps to reproduce
Build OpenUSD with Python 3.14 on Windows.
Start
usdview.Open the embedded Python interpreter.
Have
PYTHONSTARTUPset to a Windows path, for example:C:\Users\Jonas\AppData\Roaming\Code\User\workspaceStorage\...\ms-python.python\pythonrc.py
In my case PYTHONSTARTUP is set by the VS Code Python extension.
Actual result
The interpreter fails while executing the startup file:
Traceback (most recent call last):
File "C:\Users\Jonas\AppData\Local\Python\pythoncore-3.14-64\Lib\code.py", line 64, in runsource
code = self.compile(source, filename, symbol)
File "C:\Users\Jonas\AppData\Local\Python\pythoncore-3.14-64\Lib\codeop.py", line 154, in __call__
return _maybe_compile(self.compiler, source, filename, symbol, flags=self.compiler.flags)
...
File "<input>", line 1
g = dict(globals());g["__file__"] = "C:\Users\Jonas\AppData\Roaming\Code\..."
^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escapeWhile handling that syntax error, a second exception occurs:
Traceback (most recent call last):
File "...pxr\Usdviewq\appController.py", line 2706, in _showInterpreter
self._console = Myconsole(self._interpreter, self._usdviewApi)
...
File "...pxr\Usdviewq\pythonInterpreter.py", line 298, in ExecStartupFile
self.interpreter.runsource(...)
File "...\Python\pythoncore-3.14-64\Lib\code.py", line 67, in runsource
self.showsyntaxerror(filename, source=source)
TypeError: Interpreter.showsyntaxerror() got an unexpected keyword argument 'source'Expected result
The usdview Python interpreter should open normally and execute the configured PYTHONSTARTUP file.
Issue 1: Windows path escaping
ExecStartupFile() currently generates Python source containing the startup path:
'g["__file__"] = "{0}";'
'f = open("{0}", "rb");'
'exec(compile(f.read(), "{0}", "exec"), g);'For a Windows path such as:
C:\Users\Jonas\...this produces a Python string containing \U, which is interpreted as the start of a Unicode escape sequence.
Using the repr() formatting conversion should avoid this:
self.interpreter.runsource(
'g = dict(globals());'
'g["__file__"] = {0!r};'
'f = open({0!r}, "rb");'
'exec(compile(f.read(), {0!r}, "exec"), g);'
'f.close();'
'del g["__file__"];'
'globals().update(g);'.format(path))Issue 2: Python 3.14 showsyntaxerror() API change
Python 3.14's InteractiveInterpreter.runsource() calls:
self.showsyntaxerror(filename, source=source)The usdview interpreter overrides showsyntaxerror() without accepting this argument.
For example, changing:
def showsyntaxerror(self, filename=None):
self._outputBrush = QtGui.QBrush(QtGui.QColor('#ffcc63'))
try:
InteractiveInterpreter.showsyntaxerror(self, filename)
finally:
self._outputBrush = Noneto something like:
def showsyntaxerror(self, filename=None, **kwargs):
self._outputBrush = QtGui.QBrush(QtGui.QColor('#ffcc63'))
try:
InteractiveInterpreter.showsyntaxerror(self, filename, **kwargs)
finally:
self._outputBrush = Noneappears to make the override compatible with Python 3.14 while remaining backwards compatible.
Workaround
Clearing PYTHONSTARTUP before launching usdview avoids the first problem:
set "PYTHONSTARTUP="
python "%USD_ROOT%\bin\\\usdview" %*However, the showsyntaxerror() incompatibility can still occur whenever a syntax error is processed by the interpreter.
Additional notes
The two problems seem independent:
- The Windows path issue is exposed when
PYTHONSTARTUPcontains a normal Windows path. - The
showsyntaxerror()issue is caused by an API change in Python 3.14.
I can provide a PR with the changes above if this approach is considered appropriate.
Source: PixarAnimationStudios/OpenUSD