# Buggy code
def do_shell(three=None, python=False, compat=False, shell_args=None):
    # Ensure that virtualenv is available.
    ensure_project(three=three, python=python, validate=False)

    # Set an environment variable, so we know we're in the environment.
    os.environ["PIPENV_ACTIVE"] = "1"

    # Support shell compatibility mode.
    if PIPENV_SHELL_COMPAT:
        compat = True

    # Compatibility mode:
    if compat:
        try:
            shell = os.environ["SHELL"]
        except KeyError:
            click.echo(
                crayons.red(
                    "Please ensure that the {0} environment variable "
                    "is set before activating shell.".format(
                        crayons.white("SHELL", bold=True)
                    )
                ),
                err=True,
            )
            sys.exit(1)

        click.echo(
            crayons.white(
                "Spawning environment shell ({0}).".format(crayons.red(shell)),
                bold=True,
            ),
            err=True,
        )

        cmd = "{0} -i'".format(shell)
        args = []

    # Standard (properly configured shell) mode:
    else:
        cmd = "pew"
        args = ["workon", project.virtualenv_name]

    # Grab current terminal dimensions to replace the hardcoded default
    # dimensions of pexpect
    terminal_dimensions = get_terminal_size()

    try:
        c = pexpect.spawn(
            cmd,
            args,
            dimensions=(terminal_dimensions.lines, terminal_dimensions.columns),
        )

    # Windows!
    except AttributeError:
        import subprocess

        p = subprocess.Popen([cmd] + list(args), shell=True, universal_newlines=True)
        p.communicate()
        sys.exit(p.returncode)

    # Activate the virtualenv if in compatibility mode.
    if compat:
        c.sendline(activate_virtualenv())

    # Send additional arguments to the subshell.
    if shell_args:
        c.sendline(" ".join(shell_args))

    # Handler for terminal resizing events
    # Must be defined here to have the shell process in its context, since we
    # can't pass it as an argument
    def sigwinch_passthrough(sig, data):
        terminal_dimensions = get_terminal_size()
        c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns)

    signal.signal(signal.SIGWINCH, sigwinch_passthrough)

    # Interact with the new shell.
    c.interact(escape_character=None)
    c.close()
    sys.exit(c.exitstatus)


# Traceback (TypeError)
kim@kimberly-whom-death-forgot:~$ pipenv shell
Traceback (most recent call last):
File "/usr/local/bin/pipenv", line 11, in <module>
sys.exit(cli())
File "/usr/local/lib/python3.5/dist-packages/pipenv/vendor/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/pipenv/vendor/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.5/dist-packages/pipenv/vendor/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.5/dist-packages/pipenv/vendor/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.5/dist-packages/pipenv/vendor/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/pipenv/cli.py", line 1785, in shell
load_dot_env()
File "/usr/local/lib/python3.5/dist-packages/pipenv/cli.py", line 117, in load_dot_env
denv = dotenv.find_dotenv(os.sep.join([project.project_directory, '.env']))
File "/usr/local/lib/python3.5/dist-packages/pipenv/project.py", line 62, in project_directory
return os.path.abspath(os.path.join(self.pipfile_location, os.pardir))
File "/usr/lib/python3.5/posixpath.py", line 89, in join
genericpath._check_arg_types('join', a, *p)
File "/usr/lib/python3.5/genericpath.py", line 143, in _check_arg_types
(funcname, s.__class__.__name__)) from None
TypeError: join() argument must be str or bytes, not 'NoneType'

# Fixed code
def do_shell(three=None, python=False, compat=False, shell_args=None):
    # Set an environment variable, so we know we're in the environment.
    os.environ["PIPENV_ACTIVE"] = "1"

    # Support shell compatibility mode.
    if PIPENV_SHELL_COMPAT:
        compat = True

    # Compatibility mode:
    if compat:
        try:
            shell = os.environ["SHELL"]
        except KeyError:
            click.echo(
                crayons.red(
                    "Please ensure that the {0} environment variable "
                    "is set before activating shell.".format(
                        crayons.white("SHELL", bold=True)
                    )
                ),
                err=True,
            )
            sys.exit(1)

        click.echo(
            crayons.white(
                "Spawning environment shell ({0}).".format(crayons.red(shell)),
                bold=True,
            ),
            err=True,
        )

        cmd = "{0} -i'".format(shell)
        args = []

    # Standard (properly configured shell) mode:
    else:
        cmd = "pew"
        args = ["workon", project.virtualenv_name]

    # Grab current terminal dimensions to replace the hardcoded default
    # dimensions of pexpect
    terminal_dimensions = get_terminal_size()

    try:
        c = pexpect.spawn(
            cmd,
            args,
            dimensions=(terminal_dimensions.lines, terminal_dimensions.columns),
        )

    # Windows!
    except AttributeError:
        import subprocess

        p = subprocess.Popen([cmd] + list(args), shell=True, universal_newlines=True)
        p.communicate()
        sys.exit(p.returncode)

    # Activate the virtualenv if in compatibility mode.
    if compat:
        c.sendline(activate_virtualenv())

    # Send additional arguments to the subshell.
    if shell_args:
        c.sendline(" ".join(shell_args))

    # Handler for terminal resizing events
    # Must be defined here to have the shell process in its context, since we
    # can't pass it as an argument
    def sigwinch_passthrough(sig, data):
        terminal_dimensions = get_terminal_size()
        c.setwinsize(terminal_dimensions.lines, terminal_dimensions.columns)

    signal.signal(signal.SIGWINCH, sigwinch_passthrough)

    # Interact with the new shell.
    c.interact(escape_character=None)
    c.close()
    sys.exit(c.exitstatus)