From 1c3678bf1debbc6abd19fe94f4c574b329f3c749 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 8 Nov 2022 17:04:51 -0700 Subject: [PATCH] Make the formatting of a code block name extendable Currently the user display of a code block requires a tight coupling between the caching compiler and the ultratb file, i.e., ultratb needs to know internal private variables of the caching compiler. This change makes the user-visible display of the code block name the responsibility of the caching compiler. A nice result is that the caching compiler can be overridden to have custom terminology in different systems for code blocks executed. --- IPython/core/compilerop.py | 15 +++++++++++++++ IPython/core/ultratb.py | 26 ++++++++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/IPython/core/compilerop.py b/IPython/core/compilerop.py index 228f705666f..7799a4fc99e 100644 --- a/IPython/core/compilerop.py +++ b/IPython/core/compilerop.py @@ -116,6 +116,21 @@ def get_code_name(self, raw_code, transformed_code, number): """ return code_name(transformed_code, number) + def format_code_name(self, name): + """Return a user-friendly label and name for a code block. + + Parameters + ---------- + name : str + The name for the code block returned from get_code_name + + Returns + ------- + A (label, name) pair that can be used in tracebacks, or None if the default formatting should be used. + """ + if name in self._filename_map: + return "Cell", "In[%s]" % self._filename_map[name] + def cache(self, transformed_code, number=0, raw_code=None): """Make a name for a block of code, and cache the code. diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index e83e2b4a0c1..18eff270829 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -173,7 +173,7 @@ def _format_traceback_lines(lines, Colors, has_colors: bool, lvals): def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None): """ - Format filename lines with `In [n]` if it's the nth code cell or `File *.py` if it's a module. + Format filename lines with custom formatting from caching compiler or `File *.py` by default Parameters ---------- @@ -184,23 +184,29 @@ def _format_filename(file, ColorFilename, ColorNormal, *, lineno=None): ColorScheme's normal coloring to be used. """ ipinst = get_ipython() - - if ipinst is not None and file in ipinst.compile._filename_map: - file = "[%s]" % ipinst.compile._filename_map[file] + if ( + ipinst is not None + and (data := ipinst.compile.format_code_name(file)) is not None + ): + label, name = data if lineno is None: - tpl_link = f"Cell {ColorFilename}In {{file}}{ColorNormal}" + tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}" else: - tpl_link = f"Cell {ColorFilename}In {{file}}, line {{lineno}}{ColorNormal}" + tpl_link = ( + f"{{label}} {ColorFilename}{{name}}, line {{lineno}}{ColorNormal}" + ) else: - file = util_path.compress_user( + label = "File" + name = util_path.compress_user( py3compat.cast_unicode(file, util_path.fs_encoding) ) if lineno is None: - tpl_link = f"File {ColorFilename}{{file}}{ColorNormal}" + tpl_link = f"{{label}} {ColorFilename}{{name}}{ColorNormal}" else: - tpl_link = f"File {ColorFilename}{{file}}:{{lineno}}{ColorNormal}" + # can we make this the more friendly ", line {{lineno}}", or do we need to preserve the formatting with the colon? + tpl_link = f"{{label}} {ColorFilename}{{name}}:{{lineno}}{ColorNormal}" - return tpl_link.format(file=file, lineno=lineno) + return tpl_link.format(label=label, name=name, lineno=lineno) #--------------------------------------------------------------------------- # Module classes