# Buggy code
def _get_frame_info(stacklevel: int, context: int = 1) -> inspect.FrameInfo:
    """Get a Traceback for the given `stacklevel`.

    For example:
    `stacklevel=0` means this function's frame (_get_frame_info()).
    `stacklevel=1` means the calling function's frame.
    See https://docs.python.org/2/library/inspect.html#inspect.getouterframes for more info.

    NB: If `stacklevel` is greater than the number of actual frames, the outermost frame is used
    instead.
    """
    frame_list = inspect.getouterframes(inspect.currentframe(), context=context)
    frame_stack_index = (
        stacklevel if stacklevel < len(frame_list) else len(frame_list) - 1
    )
    return frame_list[frame_stack_index]


# Traceback (RecursionError)
Traceback (most recent call last):
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/engine/mapper.py", line 55, in parse
objects = parser.parse(filepath, filecontent)
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/engine/legacy/parser.py", line 177, in parse
self.check_for_deprecated_globs_usage(token_str, filepath, lineno)
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/engine/legacy/parser.py", line 152, in check_for_deprecated_globs_usage
hint=warning,
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/base/deprecated.py", line 211, in warn_or_error
lineno=line_number)
File "<python_dist>/lib/python3.6/warnings.py", line 99, in _showwarnmsg
msg.file, msg.line)
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/base/deprecated.py", line 127, in wrapped
line=(line or context_lines_string))
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/base/deprecated.py", line 127, in wrapped
line=(line or context_lines_string))
File "<example>/pantsbuild.pants-1.25.0.dev3+git951fbda1-cp36-abi3-macosx_10_11_x86_64.whl/pants/base/deprecated.py", line 127, in wrapped
line=(line or context_lines_string))
[Previous line repeated 968 more times]
File "<python_dist>/lib/python3.6/logging/__init__.py", line 2003, in _showwarning
logger.warning("%s", s)
File "<python_dist>/lib/python3.6/logging/__init__.py", line 1318, in warning
self._log(WARNING, msg, args, **kwargs)
File "<python_dist>/lib/python3.6/logging/__init__.py", line 1441, in _log
exc_info, func, extra, sinfo)
File "<python_dist>/lib/python3.6/logging/__init__.py", line 1411, in makeRecord
sinfo)
File "<python_dist>/lib/python3.6/logging/__init__.py", line 277, in __init__
if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
File "<python_dist>/lib/python3.6/abc.py", line 188, in __instancecheck__
subclass in cls._abc_negative_cache):
File "<python_dist>/lib/python3.6/_weakrefset.py", line 75, in __contains__
return wr in self.data
RecursionError: maximum recursion depth exceeded in comparison

# Fixed code
def _get_frame_info(stacklevel: int) -> inspect.FrameInfo:
    """Get a Traceback for the given `stacklevel`.

    For example:
    `stacklevel=0` means this function's frame (_get_frame_info()).
    `stacklevel=1` means the calling function's frame.
    See https://docs.python.org/3/library/inspect.html#inspect.getouterframes for more info.

    NB: If `stacklevel` is greater than the number of actual frames, the outermost frame is used
    instead.
    """
    frame_list = inspect.getouterframes(inspect.currentframe())
    frame_stack_index = (
        stacklevel if stacklevel < len(frame_list) else len(frame_list) - 1
    )
    return frame_list[frame_stack_index]