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:79, in locked_when_built.<locals>.wrapper(self, *args, **kwargs)
75 if self.is_built:
76 raise Exception(
77 f"Model has been built for a simulation, cannot use {func} here"
78 )
---> 79 return func(self, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:2236, in Model.parse(self, text, spec)
2217 """Parses kat script and adds the resulting objects to the model.
2218
2219 Parameters
(...)
2232 parse_legacy_file : Parse Finesse 2 kat script file.
2233 """
2234 from .script import parse
-> 2236 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:165, in KatCompiler.compile(self, string, **kwargs)
147 def compile(self, string, **kwargs):
148 """Compile the contents of `string`.
149
150 Parameters
(...)
163 The model compiled from reading `string`.
164 """
--> 165 return self.compile_file(StringIO(string), **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:214, in KatCompiler.compile_file(self, fobj, model, resolve, build)
211 self._reraise_parser_error_in_spec_context(e)
213 # Build the parse graph.
--> 214 self._fill(script, ROOT_NODE_NAME)
216 # At this stage there shouldn't be any dependencies between branches.
217 assert self.graph.is_tree()
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:273, in KatCompiler._fill(self, value, path, **attributes)
271 for order, argument in enumerate(value.arguments):
272 argument_path = self.graph.item_node_name(order, path)
--> 273 self._fill(argument, argument_path)
274 self.graph.add_edge(
275 argument_path, path, type=KatEdgeType.ARGUMENT, order=order
276 )
278 return attributes
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:265, in KatCompiler._fill(self, value, path, **attributes)
263 def _fill(self, value, path, **attributes):
264 attributes = merge_attributes(
--> 265 attributes, self._item_node_attributes(value, path)
266 )
267 self.graph.add_node(path, **attributes)
269 if hasattr(value, "arguments"):
270 # 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:340, in KatCompiler._(self, element, path)
336 else:
337 msg = _get_unknown_token_message(
338 "element", directive_token.raw_value, self.spec.elements.keys()
339 )
--> 340 raise KatSyntaxError(
341 msg,
342 self.script,
343 directive_token,
344 )
345 return {
346 "token": element.directive,
347 "name_token": element.name,
348 "type": KatNodeType.ELEMENT,
349 "extra_tokens": element.extra,
350 }
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:79, in locked_when_built.<locals>.wrapper(self, *args, **kwargs)
75 if self.is_built:
76 raise Exception(
77 f"Model has been built for a simulation, cannot use {func} here"
78 )
---> 79 return func(self, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/model.py:2236, in Model.parse(self, text, spec)
2217 """Parses kat script and adds the resulting objects to the model.
2218
2219 Parameters
(...)
2232 parse_legacy_file : Parse Finesse 2 kat script file.
2233 """
2234 from .script import parse
-> 2236 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:165, in KatCompiler.compile(self, string, **kwargs)
147 def compile(self, string, **kwargs):
148 """Compile the contents of `string`.
149
150 Parameters
(...)
163 The model compiled from reading `string`.
164 """
--> 165 return self.compile_file(StringIO(string), **kwargs)
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:214, in KatCompiler.compile_file(self, fobj, model, resolve, build)
211 self._reraise_parser_error_in_spec_context(e)
213 # Build the parse graph.
--> 214 self._fill(script, ROOT_NODE_NAME)
216 # At this stage there shouldn't be any dependencies between branches.
217 assert self.graph.is_tree()
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:273, in KatCompiler._fill(self, value, path, **attributes)
271 for order, argument in enumerate(value.arguments):
272 argument_path = self.graph.item_node_name(order, path)
--> 273 self._fill(argument, argument_path)
274 self.graph.add_edge(
275 argument_path, path, type=KatEdgeType.ARGUMENT, order=order
276 )
278 return attributes
File /usr/local/lib/python3.12/site-packages/finesse/script/compiler.py:265, in KatCompiler._fill(self, value, path, **attributes)
263 def _fill(self, value, path, **attributes):
264 attributes = merge_attributes(
--> 265 attributes, self._item_node_attributes(value, path)
266 )
267 self.graph.add_node(path, **attributes)
269 if hasattr(value, "arguments"):
270 # 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:340, in KatCompiler._(self, element, path)
336 else:
337 msg = _get_unknown_token_message(
338 "element", directive_token.raw_value, self.spec.elements.keys()
339 )
--> 340 raise KatSyntaxError(
341 msg,
342 self.script,
343 directive_token,
344 )
345 return {
346 "token": element.directive,
347 "name_token": element.name,
348 "type": KatNodeType.ELEMENT,
349 "extra_tokens": element.extra,
350 }
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