Tracebacks in Jupyter notebooks¶
Andreas Freise, 16/04/2020
The following demonstrates how Finesse handles parse errors. When run from IPython or Jupyter the full traceback is suppressed and only the parser error itself is shown. When run from Python it always returns the full traceback.
You can print the latest full traceback with finesse.tb().
If you want to always see the full traceback, for example, during debugging, you can set this with finesse.show_tracebacks()
We use a very simple example model for the demonstration:
from finesse.env import is_interactive
print(is_interactive())
True
import finesse
code = """
l laser P=1
pd tmp laser.p1.o
"""
kat = finesse.Model()
kat.parse(code)
A syntax error in the katscript gives a parser error:
code = """
l1 laser P=1
pd tmp laser.p1.o
"""
kat = finesse.Model()
kat.parse(code)
KatSyntaxError: (use finesse.tb() to see the full traceback)
line 2: unknown element 'l1'
Did you mean 'l'?
1:
-->2: l1 laser P=1
^^
3: pd tmp laser.p1.o
We can print the full traceback:
finesse.tb(colors=False)
---------------------------------------------------------------------------
KatSyntaxError Traceback (most recent call last)
Cell In[3], line 7
1 code = """
2 l1 laser P=1
3 pd tmp laser.p1.o
4 """
6 kat = finesse.Model()
----> 7 kat.parse(code)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:78, in locked_when_built.<locals>.wrapper(self, *args, **kwargs)
74 if self.is_built:
75 raise Exception(
76 f"Model has been built for a simulation, cannot use {func} here"
77 )
---> 78 return func(self, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:2229, in Model.parse(self, text, spec)
2210 """Parses kat script and adds the resulting objects to the model.
2211
2212 Parameters
(...)
2225 parse_legacy_file : Parse Finesse 2 kat script file.
2226 """
2227 from .script import parse
-> 2229 parse(text, model=self, spec=spec)
File /usr/local/lib/python3.12/site-packages/finesse/script/__init__.py:44, in parse(text, model, spec)
41 from .compiler import KatCompiler
43 compiler = KatCompiler(spec=spec)
---> 44 return compiler.compile(text, model=model)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:154, in KatCompiler.compile(self, string, **kwargs)
136 def compile(self, string, **kwargs):
137 """Compile the contents of `string`.
138
139 Parameters
(...)
152 The model compiled from reading `string`.
153 """
--> 154 return self.compile_file(StringIO(string), **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:203, in KatCompiler.compile_file(self, fobj, model, resolve, build)
200 self._reraise_parser_error_in_spec_context(e)
202 # Build the parse graph.
--> 203 self._fill(script, ROOT_NODE_NAME)
205 # At this stage there shouldn't be any dependencies between branches.
206 assert self.graph.is_tree()
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:262, in KatCompiler._fill(self, value, path, **attributes)
260 for order, argument in enumerate(value.arguments):
261 argument_path = self.graph.item_node_name(order, path)
--> 262 self._fill(argument, argument_path)
263 self.graph.add_edge(
264 argument_path, path, type=KatEdgeType.ARGUMENT, order=order
265 )
267 return attributes
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:254, in KatCompiler._fill(self, value, path, **attributes)
252 def _fill(self, value, path, **attributes):
253 attributes = merge_attributes(
--> 254 attributes, self._item_node_attributes(value, path)
255 )
256 self.graph.add_node(path, **attributes)
258 if hasattr(value, "arguments"):
259 # Assemble arguments.
File /usr/local/lib/python3.12/functools.py:946, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
944 def _method(*args, **kwargs):
945 method = self.dispatcher.dispatch(args[0].__class__)
--> 946 return method.__get__(obj, cls)(*args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:329, in KatCompiler._(self, element, path)
325 else:
326 msg = _get_unknown_token_message(
327 "element", directive_token.raw_value, self.spec.elements.keys()
328 )
--> 329 raise KatSyntaxError(
330 msg,
331 self.script,
332 directive_token,
333 )
334 return {
335 "token": element.directive,
336 "name_token": element.name,
337 "type": KatNodeType.ELEMENT,
338 "extra_tokens": element.extra,
339 }
KatSyntaxError: (use finesse.tb() to see the full traceback)
line 2: unknown element 'l1'
Did you mean 'l'?
1:
-->2: l1 laser P=1
^^
3: pd tmp laser.p1.o
To switch tracebacks on globally:
finesse.show_tracebacks(True)
False
code = """
l1 laser P=1
pd tmp laser.p1.o
"""
kat = finesse.Model()
kat.parse(code)
---------------------------------------------------------------------------
KatSyntaxError Traceback (most recent call last)
Cell In[6], line 7
1 code = """
2 l1 laser P=1
3 pd tmp laser.p1.o
4 """
6 kat = finesse.Model()
----> 7 kat.parse(code)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:78, in locked_when_built.<locals>.wrapper(self, *args, **kwargs)
74 if self.is_built:
75 raise Exception(
76 f"Model has been built for a simulation, cannot use {func} here"
77 )
---> 78 return func(self, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:2229, in Model.parse(self, text, spec)
2210 """Parses kat script and adds the resulting objects to the model.
2211
2212 Parameters
(...)
2225 parse_legacy_file : Parse Finesse 2 kat script file.
2226 """
2227 from .script import parse
-> 2229 parse(text, model=self, spec=spec)
File /usr/local/lib/python3.12/site-packages/finesse/script/__init__.py:44, in parse(text, model, spec)
41 from .compiler import KatCompiler
43 compiler = KatCompiler(spec=spec)
---> 44 return compiler.compile(text, model=model)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:154, in KatCompiler.compile(self, string, **kwargs)
136 def compile(self, string, **kwargs):
137 """Compile the contents of `string`.
138
139 Parameters
(...)
152 The model compiled from reading `string`.
153 """
--> 154 return self.compile_file(StringIO(string), **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:203, in KatCompiler.compile_file(self, fobj, model, resolve, build)
200 self._reraise_parser_error_in_spec_context(e)
202 # Build the parse graph.
--> 203 self._fill(script, ROOT_NODE_NAME)
205 # At this stage there shouldn't be any dependencies between branches.
206 assert self.graph.is_tree()
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:262, in KatCompiler._fill(self, value, path, **attributes)
260 for order, argument in enumerate(value.arguments):
261 argument_path = self.graph.item_node_name(order, path)
--> 262 self._fill(argument, argument_path)
263 self.graph.add_edge(
264 argument_path, path, type=KatEdgeType.ARGUMENT, order=order
265 )
267 return attributes
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:254, in KatCompiler._fill(self, value, path, **attributes)
252 def _fill(self, value, path, **attributes):
253 attributes = merge_attributes(
--> 254 attributes, self._item_node_attributes(value, path)
255 )
256 self.graph.add_node(path, **attributes)
258 if hasattr(value, "arguments"):
259 # Assemble arguments.
File /usr/local/lib/python3.12/functools.py:946, in singledispatchmethod.__get__.<locals>._method(*args, **kwargs)
944 def _method(*args, **kwargs):
945 method = self.dispatcher.dispatch(args[0].__class__)
--> 946 return method.__get__(obj, cls)(*args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:329, in KatCompiler._(self, element, path)
325 else:
326 msg = _get_unknown_token_message(
327 "element", directive_token.raw_value, self.spec.elements.keys()
328 )
--> 329 raise KatSyntaxError(
330 msg,
331 self.script,
332 directive_token,
333 )
334 return {
335 "token": element.directive,
336 "name_token": element.name,
337 "type": KatNodeType.ELEMENT,
338 "extra_tokens": element.extra,
339 }
KatSyntaxError:
line 2: unknown element 'l1'
Did you mean 'l'?
1:
-->2: l1 laser P=1
^^
3: pd tmp laser.p1.o
finesse.show_tracebacks() can also switch tracebacks off again:
finesse.show_tracebacks(False)
True