golang_str: Fix bstr/ustr .__str__ to always return bstr/ustr even for subclasses
This behaviour is provided by builtin str and we were not following it: $ python3 Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> class SSS(str): pass ... >>> z = SSS('abc') >>> z 'abc' >>> type(z) <class '__main__.SSS'> >>> q = str(z) >>> q 'abc' >>> type(q) <class 'str'> >>> r = z.__str__() >>> r 'abc' >>> type(r) <class 'str'> <-- NOTE str, not __main__.SSS $ gpython # with str patched to be ustr >>> class SSS(str): pass >>> z = SSS('abc') >>> z 'abc' >>> type(z) <class '__main__.SSS'> >>> q = str(z) >>> q 'abc' >>> type(q) <class 'str'> >>> r = z.__str__() >>> r 'abc' >>> type(r) <class '__main__.SSS'> <-- NOTE not str which leads to crash during IPython startup on py3.11: $ gpython -m IPython # with str patched to be ustr Traceback (most recent call last): File "/home/kirr/src/tools/go/py3.venv/bin/gpython", line 8, in <module> sys.exit(main()) ^^^^^^ File "/home/kirr/src/tools/go/pygolang-master/gpython/__init__.py", line 478, in main pymain(argv, init) File "/home/kirr/src/tools/go/pygolang-master/gpython/__init__.py", line 291, in pymain run(mmain) File "/home/kirr/src/tools/go/pygolang-master/gpython/__init__.py", line 162, in run runpy._run_module_as_main(mod) File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/__main__.py", line 15, in <module> start_ipython() File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/__init__.py", line 128, in start_ipython return launch_new_instance(argv=argv, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/traitlets/config/application.py", line 1042, in launch_instance app.initialize(argv) File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/traitlets/config/application.py", line 113, in inner return method(app, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/ipapp.py", line 279, in initialize self.init_shell() File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/ipapp.py", line 293, in init_shell self.shell = self.interactive_shell_class.instance(parent=self, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/traitlets/config/configurable.py", line 551, in instance inst = cls(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/interactiveshell.py", line 856, in __init__ self.init_prompt_toolkit_cli() File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/interactiveshell.py", line 648, in init_prompt_toolkit_cli **self._extra_prompt_options(), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/interactiveshell.py", line 751, in _extra_prompt_options "lexer": IPythonPTLexer(), ^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/IPython/terminal/ptutils.py", line 177, in __init__ self.python_lexer = PygmentsLexer(l.Python3Lexer) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/prompt_toolkit/lexers/pygments.py", line 198, in __init__ self.pygments_lexer = pygments_lexer_cls( ^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/pygments/lexer.py", line 647, in __call__ cls._tokens = cls.process_tokendef('', cls.get_tokendefs()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/pygments/lexer.py", line 586, in process_tokendef cls._process_state(tokendefs, processed, state) File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/pygments/lexer.py", line 549, in _process_state tokens.extend(cls._process_state(unprocessed, processed, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/pygments/lexer.py", line 533, in _process_state assert type(state) is str, "wrong state name %r (%r)" % (state, type(state)) ^^^^^^^^^^^^^^^^^^ AssertionError: wrong state name 'keywords' (<class 'pygments.lexer.include'>) If you suspect this is an IPython 8.12.0 bug, please report it at: https://github.com/ipython/ipython/issues or send an email to the mailing list at ipython-dev@python.org You can print a more detailed traceback right now with "%tb", or use "%debug" to interactively debug it. Extra-detailed tracebacks for bug-reporting purposes can be enabled via: c.Application.verbose_crash=True Here pygments define class include(str): pass and wants `str(obj)` to return str, not include if obj was instance of include. -> Adjust bstr/ustr .__str__() to always return bstr/ustr even for subclassed. For consistency, do the same for .__unicode__ . In case a subclass wants its __str__, or __unicode__ to return self without casting to bstr/ustr, it can override those methods.
Showing
Please register or sign in to comment