MutaFix run: boltons-001
ranker nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B · patcher nvidia/nemotron-3-super-120b-a12b · via Nebius Token Factory
- if not (type_mod not in ('__main__', '__builtin__', 'exceptions', 'builtins')): (injected bug)+ if type_mod not in ("__main__", "__builtin__", "exceptions", "builtins"): (original)retriever rank 15 of 20 · ranker position not in top 5 · patched the right function no · exact restore no
Trace
failing tests and errors
tests/test_tbutils.py::test_contextualtests/test_tbutils.py::test_contextual
E AssertionError: assert 'builtins.Exc...c_a exception' == 'Exception: func_a exception' E E - Exception: func_a exception E + builtins.Exception: func_a exception E ? +++++++++
tests/test_tbutils.py::test_contextual in the static call graph. Kept 20 candidates, ranked by spectrum score (Ochiai), call graph and BM25 break ties.candidates in retriever order
boltons/tbutils.py::ContextualCallpoint.to_dictboltons/tbutils.py::ExceptionInfo.get_formattedboltons/tbutils.py::ContextualCallpoint.__init__boltons/tbutils.py::Callpoint.to_dictboltons/tbutils.py::Callpoint.from_currentboltons/tbutils.py::ContextualCallpoint.from_frameboltons/tbutils.py::Callpoint.from_frameboltons/tbutils.py::_DeferredLine.__repr__boltons/tbutils.py::ContextualCallpoint._populate_local_reprsboltons/tbutils.py::ContextualCallpoint._populate_context_linesboltons/tbutils.py::ContextualCallpoint.from_tbboltons/tbutils.py::Callpoint.__repr__boltons/tbutils.py::TracebackInfo.get_formattedboltons/tbutils.py::ExceptionInfo.from_currentboltons/tbutils.py::ExceptionInfo.from_exc_infoboltons/tbutils.py::Callpoint.tb_frame_strboltons/tbutils.py::ExceptionInfo.__init__boltons/tbutils.py::_DeferredLine.__str__boltons/tbutils.py::Callpoint.__init__boltons/tbutils.py::TracebackInfo.__init__
boltons/tbutils.py::ContextualCallpoint.to_dictboltons/tbutils.py::ExceptionInfo.get_formattedboltons/tbutils.py::ContextualCallpoint.__init__boltons/tbutils.py::Callpoint.to_dictboltons/tbutils.py::Callpoint.from_current
read boltons/tbutils.py::ExceptionInfo.get_formatted
The failing test checks that ctx_ei_str.splitlines()[-1] equals 'Exception: func_a exception', but the actual output starts with 'builtins.Exception: func_a exception'. This suggests that ExceptionInfo.get_formatted is including the full qualified name of the exception type (including the module) instead of just the simple name. The method currently concatenates tb_str and f'{self.exc_type}: {self.exc_msg}', but self.exc_type is likely the full class path (e.g., 'builtins.Exception') rather than just 'Exception'. The fix should ensure only the simple exception name is used in the formatted string.
The test expects the last line to be exactly 'Exception: func_a exception', but the current code uses self.exc_type directly, which includes the full qualified name (e.g., 'builtins.Exception'). By using self.exc_type.__name__, we extract only the simple exception name ('Exception'), matching the expected output.
--- a/boltons/tbutils.py+++ b/boltons/tbutils.py@@ -435,5 +435,5 @@ # TODO: add SyntaxError formatting tb_str = self.tb_info.get_formatted()- return ''.join([tb_str, f'{self.exc_type}: {self.exc_msg}'])+ return ''.join([tb_str, f'{self.exc_type.__name__}: {self.exc_msg}']) def get_formatted_exception_only(self):
tests: 1 failing (target tests)
tests/test_tbutils.py::test_contextual
read boltons/tbutils.py::ExceptionInfo.__init__
To understand how exc_type is stored in ExceptionInfo, we need to look at its __init__ method.
model reasoning (excerpt)
We need to examine what self.exc_type actually is. It might be a string already? Let's look at ExceptionInfo class definition. We'll read candidate 14 maybe? Actually we have candidate 14: ExceptionInfo.from_current, but we need ExceptionInfo itself. Not listed yet. But we can infer: ExceptionInfo probably stores exc_type as a type (class) or as a string? The error says "'str' object has no attribute '__name__'", meaning self.exc_type is a string. So we cannot use __name__ on a string. Instead, if it's already a string representing the full name, we need to extract the last part after the last dot. Or perhaps we want just the class name without module. For builtins.Exception, the string is 'builtins.Exception', we want 'Exception'. Alternatively, maybe exc_type is the actual type object, but then why would it be a string? Could be that in some contexts it's stored as string? Let's check the ExceptionInfo class. We'll read it. But note: The test also passes in some cases? There were passing tests earlier? The candidate list shows some functions ran in 1/1 failing and 1/1 passing tests. That indicates there is at least one passing test. So the bug might be that sometimes exc_type is a type, sometimes a string? Unlikely. Better to look at ExceptionInfo definition. Let's read the file around that area. We'll do a read for the file boltons/tbutils.py to see ExceptionInfo. But we can only read specific candidates? The action read can take a candidate number, which refers to a fu
read boltons/tbutils.py::ExceptionInfo.from_current
Check ExceptionInfo.from_current to see how exc_type is obtained.
model reasoning (excerpt)
We have seen that ExceptionInfo.__init__ stores exc_type as passed in. We need to know what is passed in from ExceptionInfo.from_current or from_exc_info. Let's look at those methods.
read boltons/tbutils.py::TracebackInfo.__init__
We need to see the definition of ContextualExceptionInfo to understand if it overrides __init__ or any methods that might affect exc_type.
model reasoning (excerpt)
We need to see what sys.exc_info returns: (type, value, traceback). So exc_type is a type object (like Exception), not a string. Then why did our patch cause AttributeError? Because maybe sometimes exc_type is a string? But the error said: AttributeError: 'str' object has no attribute '__name__'. That indicates that in some case, self.exc_type is a string. However, looking at the test, they raise a plain Exception, so exc_type should be the built-in Exception class. Unless there's something else. Wait, the error message from the test after our patch was: E Exception: func_a exception E AttributeError: 'str' object has no attribute '__name__'. Did you mean: '__ne__'? That suggests that when we tried to access __name__ on self.exc_type, it was a string. But why would self.exc_type be a string? Let's check the ExceptionInfo.__init__ again: it sets self.exc_type = exc_type, where exc_type comes from sys.exc_info()[0], which is a class, not a string. Unless there's another place where ExceptionInfo is instantiated with a string? Or maybe the test is also using some other code path? But the test uses ContextualExceptionInfo.from_current(), which eventually calls ExceptionInfo.from_current(). Let's look at ContextualExceptionInfo. We haven't seen that yet. It might be a subclass. Let's check if it overrides __init__ or something. But we don't have it in the candidates list. However, we can read it if needed. But first, let's see the test again: it uses ContextualExceptionI
To extract the simple name of the exception type, whether exc_type is a class or a string representing the qualified name.
--- a/boltons/tbutils.py+++ b/boltons/tbutils.py@@ -435,5 +435,5 @@ # TODO: add SyntaxError formatting tb_str = self.tb_info.get_formatted()- return ''.join([tb_str, f'{self.exc_type}: {self.exc_msg}'])+ return ''.join([tb_str, f'{str(self.exc_type).split(".")[-1]}: {self.exc_msg}']) def get_formatted_exception_only(self):
tests: all tests pass
model reasoning (excerpt)
We have exhausted our reads. Let's think about the problem again.
From the error message:
E Exception: func_a exception
E AttributeError: 'str' object has no attribute '__name__'
This indicates that in the patched version, we tried to access `__name__` on a string. So `self.exc_type` is a string, not a type.
Looking at the `__init__` of ExceptionInfo (candidate 17), we see:
self.exc_type = exc_type
And from `from_current` -> `from_exc_info` (which we haven't seen, but we know from the traceback that it uses `sys.exc_info()`).
In standard Python, `sys.exc_info()` returns a tuple: (type, value, traceback). The first element is the exception type (a class), not a string.
However, note that the test is using `ContextualExceptionInfo.from_current()`. We haven't looked at `ContextualExceptionInfo` because it wasn't in the candidates. But note that the test says:
ctx_ei = ContextualExceptionInfo.from_current()
So we must consider that `ContextualExceptionInfo` might be a subclass of `ExceptionInfo` and might override something.
But wait, we don't have `ContextualExceptionInfo` in the candidates. However, note that the test imports from `boltons.tbutils` and we have been looking at `boltons/tbutils.py`. It's possible that `ContextualExceptionInfo` is defined in the same file.
Given that we have no more reads, we must rely on what we have.
Alternatively, let's look at the `ExceptionInfo.from_exc_info` method (candidate 15) even though we didn't get to read iFinal patch
--- a/boltons/tbutils.py+++ b/boltons/tbutils.py@@ -435,5 +435,5 @@ # TODO: add SyntaxError formatting tb_str = self.tb_info.get_formatted()- return ''.join([tb_str, f'{self.exc_type}: {self.exc_msg}'])+ return ''.join([tb_str, f'{str(self.exc_type).split(".")[-1]}: {self.exc_msg}']) def get_formatted_exception_only(self):