mirror of
				https://github.com/python/cpython.git
				synced 2025-11-01 06:01:29 +00:00 
			
		
		
		
	[3.13] gh-82378 fix sys.tracebacklimit in pyrepl, approach 2 (GH-123062) (#123252)
Make sure that pyrepl uses the same logic for sys.tracebacklimit as both
the basic repl and the standard sys.excepthook
(cherry picked from commit 63603bca35)
			
			
This commit is contained in:
		
							parent
							
								
									95b4f9c9ad
								
							
						
					
					
						commit
						0955db1bd8
					
				
					 4 changed files with 53 additions and 12 deletions
				
			
		|  | @ -164,8 +164,13 @@ def __init__( | |||
|     def showsyntaxerror(self, filename=None, **kwargs): | ||||
|         super().showsyntaxerror(filename=filename, **kwargs) | ||||
| 
 | ||||
|     def showtraceback(self): | ||||
|         super().showtraceback(colorize=self.can_colorize) | ||||
|     def _excepthook(self, typ, value, tb): | ||||
|         import traceback | ||||
|         lines = traceback.format_exception( | ||||
|                 typ, value, tb, | ||||
|                 colorize=self.can_colorize, | ||||
|                 limit=traceback.BUILTIN_EXCEPTION_LIMIT) | ||||
|         self.write(''.join(lines)) | ||||
| 
 | ||||
|     def runsource(self, source, filename="<input>", symbol="single"): | ||||
|         try: | ||||
|  |  | |||
							
								
								
									
										20
									
								
								Lib/code.py
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								Lib/code.py
									
										
									
									
									
								
							|  | @ -107,17 +107,16 @@ def showsyntaxerror(self, filename=None, **kwargs): | |||
|         The output is written by self.write(), below. | ||||
| 
 | ||||
|         """ | ||||
|         colorize = kwargs.pop('colorize', False) | ||||
|         try: | ||||
|             typ, value, tb = sys.exc_info() | ||||
|             if filename and issubclass(typ, SyntaxError): | ||||
|                 value.filename = filename | ||||
|             source = kwargs.pop('source', "") | ||||
|             self._showtraceback(typ, value, None, colorize, source) | ||||
|             self._showtraceback(typ, value, None, source) | ||||
|         finally: | ||||
|             typ = value = tb = None | ||||
| 
 | ||||
|     def showtraceback(self, **kwargs): | ||||
|     def showtraceback(self): | ||||
|         """Display the exception that just occurred. | ||||
| 
 | ||||
|         We remove the first stack item because it is our own code. | ||||
|  | @ -125,14 +124,13 @@ def showtraceback(self, **kwargs): | |||
|         The output is written by self.write(), below. | ||||
| 
 | ||||
|         """ | ||||
|         colorize = kwargs.pop('colorize', False) | ||||
|         try: | ||||
|             typ, value, tb = sys.exc_info() | ||||
|             self._showtraceback(typ, value, tb.tb_next, colorize, '') | ||||
|             self._showtraceback(typ, value, tb.tb_next, '') | ||||
|         finally: | ||||
|             typ = value = tb = None | ||||
| 
 | ||||
|     def _showtraceback(self, typ, value, tb, colorize, source): | ||||
|     def _showtraceback(self, typ, value, tb, source): | ||||
|         sys.last_type = typ | ||||
|         sys.last_traceback = tb | ||||
|         value = value.with_traceback(tb) | ||||
|  | @ -143,9 +141,7 @@ def _showtraceback(self, typ, value, tb, colorize, source): | |||
|             value.text = lines[value.lineno - 1] | ||||
|         sys.last_exc = sys.last_value = value = value.with_traceback(tb) | ||||
|         if sys.excepthook is sys.__excepthook__: | ||||
|             lines = traceback.format_exception(typ, value, tb, | ||||
|                                                colorize=colorize) | ||||
|             self.write(''.join(lines)) | ||||
|             self._excepthook(typ, value, tb) | ||||
|         else: | ||||
|             # If someone has set sys.excepthook, we let that take precedence | ||||
|             # over self.write | ||||
|  | @ -162,6 +158,12 @@ def _showtraceback(self, typ, value, tb, colorize, source): | |||
|                 print('Original exception was:', file=sys.stderr) | ||||
|                 sys.__excepthook__(typ, value, tb) | ||||
| 
 | ||||
|     def _excepthook(self, typ, value, tb): | ||||
|         # This method is being overwritten in | ||||
|         # _pyrepl.console.InteractiveColoredConsole | ||||
|         lines = traceback.format_exception(typ, value, tb) | ||||
|         self.write(''.join(lines)) | ||||
| 
 | ||||
|     def write(self, data): | ||||
|         """Write a string. | ||||
| 
 | ||||
|  |  | |||
|  | @ -1020,7 +1020,7 @@ def test_dumb_terminal_exits_cleanly(self): | |||
|         env.update({"TERM": "dumb"}) | ||||
|         output, exit_code = self.run_repl("exit()\n", env=env) | ||||
|         self.assertEqual(exit_code, 0) | ||||
|         self.assertIn("warning: can\'t use pyrepl", output) | ||||
|         self.assertIn("warning: can't use pyrepl", output) | ||||
|         self.assertNotIn("Exception", output) | ||||
|         self.assertNotIn("Traceback", output) | ||||
| 
 | ||||
|  | @ -1114,6 +1114,38 @@ def test_correct_filename_in_syntaxerrors(self): | |||
|         self.assertIn("IndentationError: unexpected indent", output) | ||||
|         self.assertIn("<python-input-0>", output) | ||||
| 
 | ||||
|     @force_not_colorized | ||||
|     def test_proper_tracebacklimit(self): | ||||
|         env = os.environ.copy() | ||||
|         for set_tracebacklimit in [True, False]: | ||||
|             commands = ("import sys\n" + | ||||
|                         ("sys.tracebacklimit = 1\n" if set_tracebacklimit else "") + | ||||
|                         "def x1(): 1/0\n\n" | ||||
|                         "def x2(): x1()\n\n" | ||||
|                         "def x3(): x2()\n\n" | ||||
|                         "x3()\n" | ||||
|                         "exit()\n") | ||||
| 
 | ||||
|             for basic_repl in [True, False]: | ||||
|                 if basic_repl: | ||||
|                     env["PYTHON_BASIC_REPL"] = "1" | ||||
|                 else: | ||||
|                     env.pop("PYTHON_BASIC_REPL", None) | ||||
|                 with self.subTest(set_tracebacklimit=set_tracebacklimit, | ||||
|                                   basic_repl=basic_repl): | ||||
|                     output, exit_code = self.run_repl(commands, env=env) | ||||
|                     if "can't use pyrepl" in output: | ||||
|                         self.skipTest("pyrepl not available") | ||||
|                     self.assertIn("in x1", output) | ||||
|                     if set_tracebacklimit: | ||||
|                         self.assertNotIn("in x2", output) | ||||
|                         self.assertNotIn("in x3", output) | ||||
|                         self.assertNotIn("in <module>", output) | ||||
|                     else: | ||||
|                         self.assertIn("in x2", output) | ||||
|                         self.assertIn("in x3", output) | ||||
|                         self.assertIn("in <module>", output) | ||||
| 
 | ||||
|     def run_repl( | ||||
|         self, | ||||
|         repl_input: str | list[str], | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| Make sure that the new :term:`REPL` interprets :data:`sys.tracebacklimit` in | ||||
| the same way that the classic REPL did. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 CF Bolz-Tereick
						CF Bolz-Tereick