# Buggy code
def get_shell(pid=None, max_depth=4):
    """Get the shell that the supplied pid or os.getpid() is running in."""
    if not pid:
        pid = os.getpid()
    processes = get_all_processes()

    def check_parent(pid, lvl=0):
        ppid = processes[pid].get("parent_pid")
        if (
            ppid
            and processes[ppid]["executable"].lower().rsplit(".", 1)[0] in SHELL_NAMES
        ):
            return processes[ppid]["executable"]
        if lvl >= max_depth:
            return
        return check_parent(ppid, lvl=lvl + 1)

    if processes[pid]["executable"].lower().rsplit(".", 1)[0] in SHELL_NAMES:
        return processes[pid]["executable"]
    return check_parent(pid)


# Traceback (AttributeError)
PS C:\Users\brcan\Desktop\bunk> py -3 -m pipenv shell
Traceback (most recent call last):
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\core.py", line 2107, in do_shell
c = pexpect.spawn(
AttributeError: module 'pexpect' has no attribute 'spawn'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\brcan\AppData\Local\Programs\Python\Python36\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Users\brcan\AppData\Local\Programs\Python\Python36\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\__main__.py", line 4, in <module>
cli()
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\vendor\click\core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\vendor\click\core.py", line 697, in main
rv = self.invoke(ctx)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\vendor\click\core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\vendor\click\core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\vendor\click\core.py", line 535, in invoke
return callback(*args, **kwargs)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\cli.py", line 281, in shell
core.do_shell(three=three, python=python, fancy=fancy, shell_args=shell_args)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\core.py", line 2123, in do_shell
pew.workon_cmd([workon_name])
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\pew.py", line 368, in workon_cmd
shell(env, cwd=project_dir)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\pew.py", line 194, in shell
shell = _detect_shell()
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\pew.py", line 187, in _detect_shell
shell = get_shell(os.getpid())
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\_win_utils.py", line 111, in get_shell
return check_parent(pid)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\_win_utils.py", line 108, in check_parent
return check_parent(ppid, lvl=lvl+1)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\_win_utils.py", line 108, in check_parent
return check_parent(ppid, lvl=lvl+1)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\_win_utils.py", line 108, in check_parent
return check_parent(ppid, lvl=lvl+1)
File "C:\Users\brcan\AppData\Roaming\Python\Python36\site-packages\pipenv\patched\pew\_win_utils.py", line 104, in check_parent
if ppid and processes[ppid]['executable'].lower().rsplit('.', 1)[0] in SHELL_NAMES:
KeyError: 18064

# Fixed code
def get_shell(pid=None, max_depth=6):
    """Get the shell that the supplied pid or os.getpid() is running in."""
    if not pid:
        pid = os.getpid()
    processes = get_all_processes()

    def check_parent(pid, lvl=0):
        ppid = processes[pid].get("parent_pid")
        if ppid and _get_executable(processes.get(ppid)) in SHELL_NAMES:
            return processes[ppid]["executable"]
        if lvl >= max_depth:
            return
        return check_parent(ppid, lvl=lvl + 1)

    if _get_executable(processes.get([pid])) in SHELL_NAMES:
        return processes[pid]["executable"]
    return check_parent(pid)