88import io
99import re
1010import sys
11+ import inspect
1112
1213from IPython .display import IFrame , display
1314from IPython .core .ultratb import FormattedTB
@@ -299,28 +300,39 @@ def _wrap_errors(_):
299300 self ._traceback = sys .exc_info ()[2 ]
300301
301302 # Compute number of stack frames to skip to get down to callback
302- tb = get_current_traceback ()
303+ tb_werkzeug = get_current_traceback ()
303304 skip = 0
304305 if dev_tools_prune_errors :
305- for i , line in enumerate (tb .plaintext .splitlines ()):
306+ for i , line in enumerate (tb_werkzeug .plaintext .splitlines ()):
306307 if "%% callback invoked %%" in line :
307308 skip = int ((i + 1 ) / 2 )
308309 break
309310
310- # Use IPython traceback formatting to build colored ANSI traceback string
311- ostream = io .StringIO ()
312- ipytb = FormattedTB (
313- tb_offset = skip ,
314- mode = "Verbose" ,
315- color_scheme = "Linux" ,
316- include_vars = True ,
317- ostream = ostream
318- )
319- ipytb ()
311+ # Customized formatargvalues function so we can place function parameters
312+ # on separate lines
313+ original_formatargvalues = inspect .formatargvalues
314+ inspect .formatargvalues = custom_formatargvalues
315+ try :
316+ # Use IPython traceback formatting to build colored ANSI traceback
317+ # string
318+ ostream = io .StringIO ()
319+ ipytb = FormattedTB (
320+ tb_offset = skip ,
321+ mode = "Verbose" ,
322+ color_scheme = "Linux" ,
323+ include_vars = True ,
324+ ostream = ostream
325+ )
326+ ipytb ()
327+ finally :
328+ # Restore formatargvalues
329+ inspect .formatargvalues = original_formatargvalues
320330
321331 # Print colored ANSI representation if requested
332+ ansi_stacktrace = ostream .getvalue ()
333+
322334 if inline_exceptions :
323- print (ostream . getvalue () )
335+ print (ansi_stacktrace )
324336
325337 # Use ansi2html to convert the colored ANSI string to HTML
326338 conv = Ansi2HTMLConverter (scheme = "ansi2html" , dark_bg = False )
@@ -346,3 +358,32 @@ def _terminate_server_for_port(cls, host, port):
346358 response = requests .get (shutdown_url )
347359 except Exception as e :
348360 pass
361+
362+
363+ def custom_formatargvalues (
364+ args , varargs , varkw , locals ,
365+ formatarg = str ,
366+ formatvarargs = lambda name : '*' + name ,
367+ formatvarkw = lambda name : '**' + name ,
368+ formatvalue = lambda value : '=' + repr (value )):
369+
370+ """Copied from inspect.formatargvalues, modified to place function
371+ arguments on separate lines"""
372+ def convert (name , locals = locals ,
373+ formatarg = formatarg , formatvalue = formatvalue ):
374+ return formatarg (name ) + formatvalue (locals [name ])
375+ specs = []
376+ for i in range (len (args )):
377+ specs .append (convert (args [i ]))
378+ if varargs :
379+ specs .append (formatvarargs (varargs ) + formatvalue (locals [varargs ]))
380+ if varkw :
381+ specs .append (formatvarkw (varkw ) + formatvalue (locals [varkw ]))
382+
383+ result = '(' + ', ' .join (specs ) + ')'
384+
385+ if len (result ) < 40 :
386+ return result
387+ else :
388+ # Put each arg on a separate line
389+ return '(\n ' + ',\n ' .join (specs ) + '\n )'
0 commit comments