Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions IPython/core/ultratb.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,10 @@ def _format_exception_only(
)
)
if textline == "":
textline = py3compat.cast_unicode(value.text, "utf-8")
# sep 2025:
# textline = py3compat.cast_unicode(value.text, "utf-8")
assert isinstance(value.text, str)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think value.text may also be None:

>>> err = SyntaxError('Interface magics have no options, got ')
>>> err
SyntaxError('Interface magics have no options, got ')
>>> err.msg
'Interface magics have no options, got '
>>> err.text
>>> type(err.text)
<class 'NoneType'>

at least with the latest version we now get:

ile ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/interactiveshell.py:3350, in InteractiveShell.run_cell_async(self, raw_cell, store_history, silent, shell_futures, transformed_cell, preprocessing_exc_tuple, cell_id)
   3348 # Display the exception if input processing failed.
   3349 if preprocessing_exc_tuple is not None:
-> 3350     self.showtraceback(preprocessing_exc_tuple)
   3351     if store_history:
   3352         self.execution_count += 1

File ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/interactiveshell.py:2164, in InteractiveShell.showtraceback(self, exc_tuple, filename, tb_offset, exception_only, running_compiled_code)
   2159     return
   2161 if issubclass(etype, SyntaxError):
   2162     # Though this won't be called by syntax errors in the input
   2163     # line, there may be SyntaxError cases with imported code.
-> 2164     self.showsyntaxerror(filename, running_compiled_code)
   2165 elif etype is UsageError:
   2166     self.show_usage_error(value)

File ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/interactiveshell.py:2254, in InteractiveShell.showsyntaxerror(self, filename, running_compiled_code)
   2252 # If the error occurred when executing compiled code, we should provide full stacktrace.
   2253 elist = traceback.extract_tb(last_traceback) if running_compiled_code else []
-> 2254 stb = self.SyntaxTB.structured_traceback(etype, value, elist)
   2255 self._showtraceback(etype, value, stb)

File ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/ultratb.py:1243, in SyntaxTB.structured_traceback(self, etype, evalue, etb, tb_offset, context)
   1241         value.text = newtext
   1242 self.last_syntax_error = value
-> 1243 return super(SyntaxTB, self).structured_traceback(
   1244     etype, value, etb, tb_offset=tb_offset, context=context
   1245 )

File ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/ultratb.py:212, in ListTB.structured_traceback(self, etype, evalue, etb, tb_offset, context)
    210     out_list.extend(self._format_list(elist))
    211 # The exception info should be a single entry in the list.
--> 212 lines = "".join(self._format_exception_only(etype, evalue))
    213 out_list.append(lines)
    215 # Find chained exceptions if we have a traceback (not for exception-only mode)

File ~/miniconda3/envs/sage-dev/lib/python3.12/site-packages/IPython/core/ultratb.py:341, in ListTB._format_exception_only(self, etype, value)
    327 output_list.append(
    328     theme_table[self._theme_name].format(
    329         [(Token, "  ")]
   (...)    336     )
    337 )
    338 if textline == "":
    339     # sep 2025:
    340     # textline = py3compat.cast_unicode(value.text, "utf-8")
--> 341     assert isinstance(value.text, str)
    342     textline = value.text
    344 if textline is not None:

AssertionError: 

    shell.run_cell(bad_syntax)

textline = value.text

if textline is not None:
i = 0
Expand Down Expand Up @@ -425,7 +428,7 @@ def show_exception_only(
def _some_str(self, value: Any) -> str:
# Lifted from traceback.py
try:
return py3compat.cast_unicode(str(value))
return str(value)
except:
return "<unprintable %s object>" % type(value).__name__

Expand Down Expand Up @@ -704,16 +707,19 @@ def format_exception(self, etype, evalue):
if not isinstance(notes, Sequence) or isinstance(notes, (str, bytes)):
notes = [_safe_string(notes, "__notes__", func=repr)]

for note in notes:
assert isinstance(note, str)

str_notes: Sequence[str] = notes

# ... and format it
return [
theme_table[self._theme_name].format(
[(Token.ExcName, etype_str), (Token, ": "), (Token, evalue_str)]
),
*(
theme_table[self._theme_name].format(
[(Token, _safe_string(py3compat.cast_unicode(n), "note"))]
)
for n in notes
theme_table[self._theme_name].format([(Token, note)])
for note in str_notes
),
]

Expand Down
4 changes: 2 additions & 2 deletions IPython/utils/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,9 @@ def match_target(s: str) -> str:
else:
pred = pattern
if not prune:
return type(self)([el for el in self if pred(match_target(el))])
return type(self)([el for el in self if pred(match_target(el))]) # type: ignore [no-untyped-call]
else:
return type(self)([el for el in self if not pred(match_target(el))])
return type(self)([el for el in self if not pred(match_target(el))]) # type: ignore [no-untyped-call]

def fields(self, *fields: List[str]) -> List[List[str]]:
"""Collect whitespace-separated fields from string list
Expand Down
22 changes: 8 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ exclude = [
'IPython/sphinxext/ipython_directive.py',
'IPython/terminal/ipapp.py',
'IPython/utils/path.py',
'IPython/core/debugger_backport.py',
]
# check_untyped_defs = true
check_untyped_defs = true
# disallow_untyped_calls = true
# disallow_untyped_decorators = true
# ignore_errors = false
Expand All @@ -127,6 +128,7 @@ enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
[[tool.mypy.overrides]]
module = [
"IPython.core.crashhandler",
"IPython.utils.text",
]
check_untyped_defs = true
disallow_incomplete_defs = true
Expand All @@ -136,25 +138,17 @@ disallow_untyped_defs = true
ignore_errors = false
ignore_missing_imports = false

[[tool.mypy.overrides]]
module = [
"IPython.utils.text",
]
disallow_untyped_defs = true
check_untyped_defs = false
disallow_untyped_decorators = true

[[tool.mypy.overrides]]
module = [
"IPython.core.ultratb",
]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_untyped_calls = false
disallow_untyped_decorators = true
disallow_untyped_defs = false
ignore_errors = false
ignore_missing_imports = false
disallow_untyped_calls = false
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true

[[tool.mypy.overrides]]
module = [
Expand Down Expand Up @@ -316,7 +310,7 @@ ignore_errors = true
ignore_missing_imports = true
disallow_untyped_calls = false
disallow_incomplete_defs = false
check_untyped_defs = false
check_untyped_defs = true
disallow_untyped_decorators = false

[tool.pytest.ini_options]
Expand Down
Loading