# Buggy code
def _start_connection(self):
    """
    Starts the persistent connection
    """
    master, slave = pty.openpty()
    p = subprocess.Popen(
        ["ansible-connection", to_text(os.getppid())],
        stdin=slave,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    stdin = os.fdopen(master, "wb", 0)
    os.close(slave)

    # Need to force a protocol that is compatible with both py2 and py3.
    # That would be protocol=2 or less.
    # Also need to force a protocol that excludes certain control chars as
    # stdin in this case is a pty and control chars will cause problems.
    # that means only protocol=0 will work.
    src = cPickle.dumps(self._play_context.serialize(), protocol=0)
    stdin.write(src)

    stdin.write(b"\n#END_INIT#\n")

    (stdout, stderr) = p.communicate()
    stdin.close()

    if p.returncode == 0:
        result = json.loads(to_text(stdout, errors="surrogate_then_replace"))
    else:
        result = json.loads(to_text(stderr, errors="surrogate_then_replace"))

    if "messages" in result:
        for msg in result.get("messages"):
            display.vvvv("%s" % msg, host=self._play_context.remote_addr)

    if "error" in result:
        if self._play_context.verbosity > 2:
            msg = "The full traceback is:\n" + result["exception"]
            display.display(result["exception"], color=C.COLOR_ERROR)
        raise AnsibleError(result["error"])

    return result["socket_path"]


# Traceback (ValueError)
The full traceback is:
Traceback (most recent call last):
File "/Users/gnalawad/ansible/ganeshrn/ansible/lib/ansible/executor/task_executor.py", line 119, in run
res = self._execute()
File "/Users/gnalawad/ansible/ganeshrn/ansible/lib/ansible/executor/task_executor.py", line 523, in _execute
result = self._handler.run(task_vars=variables)
File "/Users/gnalawad/ansible/ganeshrn/ansible/lib/ansible/plugins/action/junos.py", line 73, in run
socket_path = connection.run()
File "/Users/gnalawad/ansible/ganeshrn/ansible/lib/ansible/plugins/connection/persistent.py", line 68, in run
socket_path = self._start_connection()
File "/Users/gnalawad/ansible/ganeshrn/ansible/lib/ansible/plugins/connection/persistent.py", line 96, in _start_connection
result = json.loads(to_text(stdout, errors='surrogate_then_replace'))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 369, in decode
raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 8 - line 4 column 121 (char 7 - 405)

fatal: [38.145.35.195]: FAILED! => {
"msg": "Unexpected failure during module execution.",
"stdout": ""
}

# Fixed code
def _start_connection(self):
    """
    Starts the persistent connection
    """
    master, slave = pty.openpty()
    p = subprocess.Popen(
        ["ansible-connection", to_text(os.getppid())],
        stdin=slave,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    stdin = os.fdopen(master, "wb", 0)
    os.close(slave)

    # Need to force a protocol that is compatible with both py2 and py3.
    # That would be protocol=2 or less.
    # Also need to force a protocol that excludes certain control chars as
    # stdin in this case is a pty and control chars will cause problems.
    # that means only protocol=0 will work.
    src = cPickle.dumps(self._play_context.serialize(), protocol=0)
    stdin.write(src)

    stdin.write(b"\n#END_INIT#\n")
    stdin.flush()

    (stdout, stderr) = p.communicate()
    stdin.close()

    if p.returncode == 0:
        result = json.loads(to_text(stdout, errors="surrogate_then_replace"))
    else:
        result = json.loads(to_text(stderr, errors="surrogate_then_replace"))

    if "messages" in result:
        for msg in result.get("messages"):
            display.vvvv("%s" % msg, host=self._play_context.remote_addr)

    if "error" in result:
        if self._play_context.verbosity > 2:
            msg = "The full traceback is:\n" + result["exception"]
            display.display(msg, color=C.COLOR_ERROR)
        raise AnsibleError(result["error"])

    return result["socket_path"]