# Buggy code
def tcp(
    q,
    where,
    timeout=None,
    port=53,
    af=None,
    source=None,
    source_port=0,
    one_rr_per_rrset=False,
):
    """Return the response obtained after sending a query via TCP.

    *q*, a ``dns.message.message``, the query to send

    *where*, a ``text`` containing an IPv4 or IPv6 address,  where
    to send the message.

    *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
    query times out.  If ``None``, the default, wait forever.

    *port*, an ``int``, the port send the message to.  The default is 53.

    *af*, an ``int``, the address family to use.  The default is ``None``,
    which causes the address family to use to be inferred from the form of
    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

    *source*, a ``text`` containing an IPv4 or IPv6 address, specifying
    the source address.  The default is the wildcard address.

    *source_port*, an ``int``, the port from which to send the message.
    The default is 0.

    *one_rr_per_rrset*, a ``bool``.  If ``True``, put each RR into its own
    RRset.

    Returns a ``dns.message.Message``.
    """

    wire = q.to_wire()
    (af, destination, source) = _destination_and_source(
        af, where, port, source, source_port
    )
    s = socket_factory(af, socket.SOCK_STREAM, 0)
    begin_time = None
    try:
        expiration = _compute_expiration(timeout)
        s.setblocking(0)
        begin_time = time.time()
        if source is not None:
            s.bind(source)
        _connect(s, destination)
        send_tcp(s, wire, expiration)
        (r, received_time) = receive_tcp(
            s, expiration, one_rr_per_rrset, q.keyring, q.request_mac
        )
    finally:
        if begin_time is None or received_time is None:
            response_time = 0
        else:
            response_time = received_time - begin_time
        s.close()
    r.time = response_time
    if not q.is_response(r):
        raise BadResponse
    return r


# Traceback (UnboundLocalError)
Traceback (most recent call last):
File "/home/frost/.local/lib/python3.5/site-packages/dns/query.py", line 464, in tcp
q.keyring, q.request_mac)
File "/home/frost/.local/lib/python3.5/site-packages/dns/query.py", line 402, in receive_tcp
one_rr_per_rrset=one_rr_per_rrset)
File "/home/frost/.local/lib/python3.5/site-packages/dns/message.py", line 821, in from_wire
reader.read()
File "/home/frost/.local/lib/python3.5/site-packages/dns/message.py", line 749, in read
self._get_section(self.message.additional, adcount)
File "/home/frost/.local/lib/python3.5/site-packages/dns/message.py", line 701, in _get_section
self.message.first)
File "/home/frost/.local/lib/python3.5/site-packages/dns/tsig.py", line 198, in validate
raise BadSignature
dns.tsig.BadSignature: The TSIG signature fails to verify.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "./runtests.py", line 195, in main
importlib.import_module("%s.%s.%s.test" % (TESTS_DIR, test, case))
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/media/frost/StaticDataT420/work/ragel/master/tests-extra/tests/tsig/ddns/test.py", line 17, in <mod
update.send("NOERROR")
File "/media/frost/StaticDataT420/work/ragel/master/tests-extra/tools/dnstest/update.py", line 38, in send
resp = dns.query.tcp(self.upd, self.server.addr, port=self.server.port)
File "/home/frost/.local/lib/python3.5/site-packages/dns/query.py", line 466, in tcp
if begin_time is None or received_time is None:
UnboundLocalError: local variable 'received_time' referenced before assignment

# Fixed code
def tcp(
    q,
    where,
    timeout=None,
    port=53,
    af=None,
    source=None,
    source_port=0,
    one_rr_per_rrset=False,
):
    """Return the response obtained after sending a query via TCP.

    *q*, a ``dns.message.message``, the query to send

    *where*, a ``text`` containing an IPv4 or IPv6 address,  where
    to send the message.

    *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
    query times out.  If ``None``, the default, wait forever.

    *port*, an ``int``, the port send the message to.  The default is 53.

    *af*, an ``int``, the address family to use.  The default is ``None``,
    which causes the address family to use to be inferred from the form of
    *where*.  If the inference attempt fails, AF_INET is used.  This
    parameter is historical; you need never set it.

    *source*, a ``text`` containing an IPv4 or IPv6 address, specifying
    the source address.  The default is the wildcard address.

    *source_port*, an ``int``, the port from which to send the message.
    The default is 0.

    *one_rr_per_rrset*, a ``bool``.  If ``True``, put each RR into its own
    RRset.

    Returns a ``dns.message.Message``.
    """

    wire = q.to_wire()
    (af, destination, source) = _destination_and_source(
        af, where, port, source, source_port
    )
    s = socket_factory(af, socket.SOCK_STREAM, 0)
    begin_time = None
    received_time = None
    try:
        expiration = _compute_expiration(timeout)
        s.setblocking(0)
        begin_time = time.time()
        if source is not None:
            s.bind(source)
        _connect(s, destination)
        send_tcp(s, wire, expiration)
        (r, received_time) = receive_tcp(
            s, expiration, one_rr_per_rrset, q.keyring, q.request_mac
        )
    finally:
        if begin_time is None or received_time is None:
            response_time = 0
        else:
            response_time = received_time - begin_time
        s.close()
    r.time = response_time
    if not q.is_response(r):
        raise BadResponse
    return r