message: Load source code of lambdas in a way that works in interactive shells like Jupyter.
diff: @@ -22,6 +22,7 @@ from __future__ import division
  from __future__ import print_function
  import inspect
  +import linecache
  import re
  import sys
  import textwrap
  @@ -183,7 +184,6 @@ def _without_context(node, lines, minl, maxl):
  if end_col_offset is not None:
  # This is only available in 3.8.
  code_lines[-1] = code_lines[-1][:end_col_offset]
  - code_block = '\n'.join(lines[minl - 1:maxl])
  col_offset = getattr(node, 'col_offset', None)
  if col_offset is None:
  @@ -195,7 +195,7 @@ def _without_context(node, lines, minl, maxl):
  if col_offset is not None:
  code_lines[0] = code_lines[0][col_offset:]
  - code_block = '\n'.join(code_lines)
  + code_block = '\n'.join([c.rstrip() for c in code_lines])
  return node, code_block
  @@ -247,9 +247,15 @@ def _parse_lambda(lam):
  # potential multi-line definition.
  mod = inspect.getmodule(lam)
  + f = inspect.getsourcefile(lam)
  def_line = lam.__code__.co_firstlineno
  - source = inspect.getsource(mod)
  - lines = source.split('\n')
  +
  + # This method is more robust that just calling inspect.getsource(mod), as it
  + # works in interactive shells, where getsource would fail. This is the
  + # same procedure followed by inspect for non-modules:
  + # https://github.com/python/cpython/blob/3.8/Lib/inspect.py#L772
  + lines = linecache.getlines(f, mod.__dict__)
  + source = ''.join(lines)
  # Narrow down to the last node starting before our definition node.
  all_nodes = parse(source, preamble_len=0, single_node=False)
  