aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'netlib')
-rw-r--r--netlib/basetypes.py4
-rw-r--r--netlib/certutils.py1
-rw-r--r--netlib/encoding.py3
-rw-r--r--netlib/http/headers.py28
-rw-r--r--netlib/http/message.py29
-rw-r--r--netlib/http/request.py26
-rw-r--r--netlib/http/response.py7
-rw-r--r--netlib/http/url.py28
-rw-r--r--netlib/multidict.py7
-rw-r--r--netlib/strutils.py43
-rw-r--r--netlib/tcp.py21
-rw-r--r--netlib/tutils.py11
-rw-r--r--netlib/version_check.py3
-rw-r--r--netlib/websockets/frame.py14
-rw-r--r--netlib/websockets/masker.py7
-rw-r--r--netlib/wsgi.py11
16 files changed, 75 insertions, 168 deletions
diff --git a/netlib/basetypes.py b/netlib/basetypes.py
index 9d6c60ba..49892ffc 100644
--- a/netlib/basetypes.py
+++ b/netlib/basetypes.py
@@ -1,9 +1,7 @@
-import six
import abc
-@six.add_metaclass(abc.ABCMeta)
-class Serializable(object):
+class Serializable(metaclass=abc.ABCMeta):
"""
Abstract Base Class that defines an API to save an object's state and restore it later on.
"""
diff --git a/netlib/certutils.py b/netlib/certutils.py
index bdc2b77e..23836cb5 100644
--- a/netlib/certutils.py
+++ b/netlib/certutils.py
@@ -3,7 +3,6 @@ import os
import ssl
import time
import datetime
-from six.moves import filter
import ipaddress
import sys
diff --git a/netlib/encoding.py b/netlib/encoding.py
index 9b8b3868..f0f7381d 100644
--- a/netlib/encoding.py
+++ b/netlib/encoding.py
@@ -5,7 +5,6 @@ from __future__ import absolute_import
import codecs
import collections
-import six
from io import BytesIO
import gzip
@@ -91,7 +90,7 @@ def encode(decoded, encoding, errors='strict'):
try:
try:
value = decoded
- if not six.PY2 and isinstance(value, six.string_types):
+ if isinstance(value, str):
value = decoded.encode()
encoded = custom_encode[encoding](value)
except KeyError:
diff --git a/netlib/http/headers.py b/netlib/http/headers.py
index b55874ca..7d46a88e 100644
--- a/netlib/http/headers.py
+++ b/netlib/http/headers.py
@@ -3,26 +3,19 @@ from __future__ import absolute_import, print_function, division
import re
import collections
-import six
from netlib import multidict
from netlib import strutils
# See also: http://lucumr.pocoo.org/2013/7/2/the-updated-guide-to-unicode/
-if six.PY2: # pragma: no cover
- def _native(x):
- return x
- def _always_bytes(x):
- strutils.always_bytes(x, "utf-8", "replace") # raises a TypeError if x != str/bytes/None.
- return x
-else:
- # While headers _should_ be ASCII, it's not uncommon for certain headers to be utf-8 encoded.
- def _native(x):
- return x.decode("utf-8", "surrogateescape")
+# While headers _should_ be ASCII, it's not uncommon for certain headers to be utf-8 encoded.
+def _native(x):
+ return x.decode("utf-8", "surrogateescape")
- def _always_bytes(x):
- return strutils.always_bytes(x, "utf-8", "surrogateescape")
+
+def _always_bytes(x):
+ return strutils.always_bytes(x, "utf-8", "surrogateescape")
class Headers(multidict.MultiDict):
@@ -93,7 +86,7 @@ class Headers(multidict.MultiDict):
# content_type -> content-type
headers = {
_always_bytes(name).replace(b"_", b"-"): _always_bytes(value)
- for name, value in six.iteritems(headers)
+ for name, value in headers.items()
}
self.update(headers)
@@ -113,9 +106,6 @@ class Headers(multidict.MultiDict):
else:
return b""
- if six.PY2: # pragma: no cover
- __str__ = __bytes__
-
def __delitem__(self, key):
key = _always_bytes(key)
super(Headers, self).__delitem__(key)
@@ -167,9 +157,9 @@ class Headers(multidict.MultiDict):
Returns:
The number of replacements made.
"""
- if isinstance(pattern, six.text_type):
+ if isinstance(pattern, str):
pattern = strutils.escaped_str_to_bytes(pattern)
- if isinstance(repl, six.text_type):
+ if isinstance(repl, str):
repl = strutils.escaped_str_to_bytes(repl)
pattern = re.compile(pattern, flags)
replacements = 0
diff --git a/netlib/http/message.py b/netlib/http/message.py
index 0b64d4a6..13f908ca 100644
--- a/netlib/http/message.py
+++ b/netlib/http/message.py
@@ -3,24 +3,17 @@ from __future__ import absolute_import, print_function, division
import re
import warnings
-import six
-
from netlib import encoding, strutils, basetypes
from netlib.http import headers
-if six.PY2: # pragma: no cover
- def _native(x):
- return x
- def _always_bytes(x):
- return x
-else:
- # While headers _should_ be ASCII, it's not uncommon for certain headers to be utf-8 encoded.
- def _native(x):
- return x.decode("utf-8", "surrogateescape")
+# While headers _should_ be ASCII, it's not uncommon for certain headers to be utf-8 encoded.
+def _native(x):
+ return x.decode("utf-8", "surrogateescape")
+
- def _always_bytes(x):
- return strutils.always_bytes(x, "utf-8", "surrogateescape")
+def _always_bytes(x):
+ return strutils.always_bytes(x, "utf-8", "surrogateescape")
class MessageData(basetypes.Serializable):
@@ -194,7 +187,7 @@ class Message(basetypes.Serializable):
return "latin-1"
def get_text(self, strict=True):
- # type: (bool) -> six.text_type
+ # type: (bool) -> str
"""
The HTTP message body decoded with both content-encoding header (e.g. gzip)
and content-type header charset.
@@ -214,7 +207,7 @@ class Message(basetypes.Serializable):
except ValueError:
if strict:
raise
- return content.decode("utf8", "replace" if six.PY2 else "surrogateescape")
+ return content.decode("utf8", "surrogateescape")
def set_text(self, text):
if text is None:
@@ -230,7 +223,7 @@ class Message(basetypes.Serializable):
ct[2]["charset"] = "utf-8"
self.headers["content-type"] = headers.assemble_content_type(*ct)
enc = "utf8"
- self.content = text.encode(enc, "replace" if six.PY2 else "surrogateescape")
+ self.content = text.encode(enc, "surrogateescape")
text = property(get_text, set_text)
@@ -269,9 +262,9 @@ class Message(basetypes.Serializable):
Returns:
The number of replacements made.
"""
- if isinstance(pattern, six.text_type):
+ if isinstance(pattern, str):
pattern = strutils.escaped_str_to_bytes(pattern)
- if isinstance(repl, six.text_type):
+ if isinstance(repl, str):
repl = strutils.escaped_str_to_bytes(repl)
replacements = 0
if self.content:
diff --git a/netlib/http/request.py b/netlib/http/request.py
index e0aaa8a9..cccda13e 100644
--- a/netlib/http/request.py
+++ b/netlib/http/request.py
@@ -1,9 +1,7 @@
from __future__ import absolute_import, print_function, division
import re
-
-import six
-from six.moves import urllib
+import urllib
from netlib import multidict
from netlib import strutils
@@ -34,19 +32,19 @@ class RequestData(message.MessageData):
timestamp_start=None,
timestamp_end=None
):
- if isinstance(method, six.text_type):
+ if isinstance(method, str):
method = method.encode("ascii", "strict")
- if isinstance(scheme, six.text_type):
+ if isinstance(scheme, str):
scheme = scheme.encode("ascii", "strict")
- if isinstance(host, six.text_type):
+ if isinstance(host, str):
host = host.encode("idna", "strict")
- if isinstance(path, six.text_type):
+ if isinstance(path, str):
path = path.encode("ascii", "strict")
- if isinstance(http_version, six.text_type):
+ if isinstance(http_version, str):
http_version = http_version.encode("ascii", "strict")
if not isinstance(headers, nheaders.Headers):
headers = nheaders.Headers(headers)
- if isinstance(content, six.text_type):
+ if isinstance(content, str):
raise ValueError("Content must be bytes, not {}".format(type(content).__name__))
self.first_line_format = first_line_format
@@ -89,9 +87,9 @@ class Request(message.Message):
Returns:
The number of replacements made.
"""
- if isinstance(pattern, six.text_type):
+ if isinstance(pattern, str):
pattern = strutils.escaped_str_to_bytes(pattern)
- if isinstance(repl, six.text_type):
+ if isinstance(repl, str):
repl = strutils.escaped_str_to_bytes(repl)
c = super(Request, self).replace(pattern, repl, flags, count)
@@ -147,10 +145,6 @@ class Request(message.Message):
Setting the host attribute also updates the host header, if present.
"""
-
- if six.PY2: # pragma: no cover
- return self.data.host
-
if not self.data.host:
return self.data.host
try:
@@ -160,7 +154,7 @@ class Request(message.Message):
@host.setter
def host(self, host):
- if isinstance(host, six.text_type):
+ if isinstance(host, str):
try:
# There's no non-strict mode for IDNA encoding.
# We don't want this operation to fail though, so we try
diff --git a/netlib/http/response.py b/netlib/http/response.py
index ec19640d..30bec2df 100644
--- a/netlib/http/response.py
+++ b/netlib/http/response.py
@@ -1,6 +1,5 @@
from __future__ import absolute_import, print_function, division
-import six
import time
from email.utils import parsedate_tz, formatdate, mktime_tz
from netlib import human
@@ -27,13 +26,13 @@ class ResponseData(message.MessageData):
timestamp_start=None,
timestamp_end=None
):
- if isinstance(http_version, six.text_type):
+ if isinstance(http_version, str):
http_version = http_version.encode("ascii", "strict")
- if isinstance(reason, six.text_type):
+ if isinstance(reason, str):
reason = reason.encode("ascii", "strict")
if not isinstance(headers, nheaders.Headers):
headers = nheaders.Headers(headers)
- if isinstance(content, six.text_type):
+ if isinstance(content, str):
raise ValueError("Content must be bytes, not {}".format(type(content).__name__))
self.http_version = http_version
diff --git a/netlib/http/url.py b/netlib/http/url.py
index 076854b9..2878734a 100644
--- a/netlib/http/url.py
+++ b/netlib/http/url.py
@@ -1,5 +1,4 @@
-import six
-from six.moves import urllib
+import urllib
from netlib import utils
@@ -41,7 +40,7 @@ def parse(url):
if not parsed.hostname:
raise ValueError("No hostname given")
- if isinstance(url, six.binary_type):
+ if isinstance(url, bytes):
host = parsed.hostname
# this should not raise a ValueError,
@@ -86,20 +85,14 @@ def encode(s):
"""
Takes a list of (key, value) tuples and returns a urlencoded string.
"""
- if six.PY2:
- return urllib.parse.urlencode(s, False)
- else:
- return urllib.parse.urlencode(s, False, errors="surrogateescape")
+ return urllib.parse.urlencode(s, False, errors="surrogateescape")
def decode(s):
"""
Takes a urlencoded string and returns a list of surrogate-escaped (key, value) tuples.
"""
- if six.PY2:
- return urllib.parse.parse_qsl(s, keep_blank_values=True)
- else:
- return urllib.parse.parse_qsl(s, keep_blank_values=True, errors='surrogateescape')
+ return urllib.parse.parse_qsl(s, keep_blank_values=True, errors='surrogateescape')
def quote(b, safe="/"):
@@ -108,10 +101,7 @@ def quote(b, safe="/"):
An ascii-encodable str.
"""
# type: (str) -> str
- if six.PY2:
- return urllib.parse.quote(b, safe=safe)
- else:
- return urllib.parse.quote(b, safe=safe, errors="surrogateescape")
+ return urllib.parse.quote(b, safe=safe, errors="surrogateescape")
def unquote(s):
@@ -122,11 +112,7 @@ def unquote(s):
A surrogate-escaped str
"""
# type: (str) -> str
-
- if six.PY2:
- return urllib.parse.unquote(s)
- else:
- return urllib.parse.unquote(s, errors="surrogateescape")
+ return urllib.parse.unquote(s, errors="surrogateescape")
def hostport(scheme, host, port):
@@ -136,7 +122,7 @@ def hostport(scheme, host, port):
if (port, scheme) in [(80, "http"), (443, "https"), (80, b"http"), (443, b"https")]:
return host
else:
- if isinstance(host, six.binary_type):
+ if isinstance(host, bytes):
return b"%s:%d" % (host, port)
else:
return "%s:%d" % (host, port)
diff --git a/netlib/multidict.py b/netlib/multidict.py
index e9fec155..b8626731 100644
--- a/netlib/multidict.py
+++ b/netlib/multidict.py
@@ -8,12 +8,10 @@ try:
except ImportError: # pragma: no cover
from collections import MutableMapping # Workaround for Python < 3.3
-import six
from netlib import basetypes
-@six.add_metaclass(ABCMeta)
-class _MultiDict(MutableMapping, basetypes.Serializable):
+class _MultiDict(MutableMapping, basetypes.Serializable, metaclass=ABCMeta):
def __repr__(self):
fields = (
repr(field)
@@ -231,8 +229,7 @@ class MultiDict(_MultiDict):
return key
-@six.add_metaclass(ABCMeta)
-class ImmutableMultiDict(MultiDict):
+class ImmutableMultiDict(MultiDict, metaclass=ABCMeta):
def _immutable(self, *_):
raise TypeError('{} objects are immutable'.format(self.__class__.__name__))
diff --git a/netlib/strutils.py b/netlib/strutils.py
index d43c2aab..81e95792 100644
--- a/netlib/strutils.py
+++ b/netlib/strutils.py
@@ -2,11 +2,9 @@ from __future__ import absolute_import, print_function, division
import re
import codecs
-import six
-
def always_bytes(unicode_or_bytes, *encode_args):
- if isinstance(unicode_or_bytes, six.text_type):
+ if isinstance(unicode_or_bytes, str):
return unicode_or_bytes.encode(*encode_args)
elif isinstance(unicode_or_bytes, bytes) or unicode_or_bytes is None:
return unicode_or_bytes
@@ -21,14 +19,10 @@ def native(s, *encoding_opts):
https://www.python.org/dev/peps/pep-3333/#a-note-on-string-types
"""
- if not isinstance(s, (six.binary_type, six.text_type)):
+ if not isinstance(s, (bytes, str)):
raise TypeError("%r is neither bytes nor unicode" % s)
- if six.PY2:
- if isinstance(s, six.text_type):
- return s.encode(*encoding_opts)
- else:
- if isinstance(s, six.binary_type):
- return s.decode(*encoding_opts)
+ if isinstance(s, bytes):
+ return s.decode(*encoding_opts)
return s
@@ -45,11 +39,8 @@ for x in ("\r", "\n", "\t"):
del _control_char_trans_newline[ord(x)]
-if six.PY2:
- pass
-else:
- _control_char_trans = str.maketrans(_control_char_trans)
- _control_char_trans_newline = str.maketrans(_control_char_trans_newline)
+_control_char_trans = str.maketrans(_control_char_trans)
+_control_char_trans_newline = str.maketrans(_control_char_trans_newline)
def escape_control_characters(text, keep_spacing=True):
@@ -59,16 +50,11 @@ def escape_control_characters(text, keep_spacing=True):
Args:
keep_spacing: If True, tabs and newlines will not be replaced.
"""
- # type: (six.string_types) -> six.text_type
- if not isinstance(text, six.string_types):
+ # type: (str) -> str
+ if not isinstance(text, str):
raise ValueError("text type must be unicode but is {}".format(type(text).__name__))
trans = _control_char_trans_newline if keep_spacing else _control_char_trans
- if six.PY2:
- return u"".join(
- six.unichr(trans.get(ord(ch), ord(ch)))
- for ch in text
- )
return text.translate(trans)
@@ -107,16 +93,9 @@ def escaped_str_to_bytes(data):
Raises:
ValueError, if the escape sequence is invalid.
"""
- if not isinstance(data, six.string_types):
- if six.PY2:
- raise ValueError("data must be str or unicode, but is {}".format(data.__class__.__name__))
+ if not isinstance(data, str):
raise ValueError("data must be str, but is {}".format(data.__class__.__name__))
- if six.PY2:
- if isinstance(data, unicode):
- data = data.encode("utf8")
- return data.decode("string-escape")
-
# This one is difficult - we use an undocumented Python API here
# as per http://stackoverflow.com/a/23151714/934719
return codecs.escape_decode(data)[0]
@@ -129,7 +108,7 @@ def is_mostly_bin(s):
return sum(
i < 9 or 13 < i < 32 or 126 < i
- for i in six.iterbytes(s[:100])
+ for i in s[:100]
) / len(s[:100]) > 0.3
@@ -158,7 +137,7 @@ def hexdump(s):
for i in range(0, len(s), 16):
offset = "{:0=10x}".format(i)
part = s[i:i + 16]
- x = " ".join("{:0=2x}".format(i) for i in six.iterbytes(part))
+ x = " ".join("{:0=2x}".format(i) for i in part)
x = x.ljust(47) # 16*2 + 15
part_repr = native(escape_control_characters(
part.decode("ascii", "replace").replace(u"\ufffd", u"."),
diff --git a/netlib/tcp.py b/netlib/tcp.py
index 64b9ce3b..e4e134c4 100644
--- a/netlib/tcp.py
+++ b/netlib/tcp.py
@@ -12,11 +12,9 @@ import binascii
from typing import Optional # noqa
from netlib import strutils
-from six.moves import range
import certifi
from backports import ssl_match_hostname
-import six
import OpenSSL
from OpenSSL import SSL
@@ -30,10 +28,7 @@ from netlib import basethread
# the latest version of pyOpenSSL is actually installed.
version_check.check_pyopenssl_version()
-if six.PY2:
- socket_fileobject = socket._fileobject
-else:
- socket_fileobject = socket.SocketIO
+socket_fileobject = socket.SocketIO
EINTR = 4
if os.environ.get("NO_ALPN"):
@@ -293,7 +288,7 @@ class Reader(_FileLike):
try:
return self.o.recv(length, socket.MSG_PEEK)
except SSL.Error as e:
- six.reraise(exceptions.TlsException, exceptions.TlsException(str(e)), sys.exc_info()[2])
+ raise exceptions.TlsException(str(e))
else:
raise NotImplementedError("Can only peek into (pyOpenSSL) sockets")
@@ -445,12 +440,8 @@ class _Connection(object):
# as it may just return what's left in the buffer and not all the bytes we want.
# As a workaround, we just use unbuffered sockets directly.
# https://mail.python.org/pipermail/python-dev/2009-June/089986.html
- if six.PY2:
- self.rfile = Reader(self.connection.makefile('rb', self.rbufsize))
- self.wfile = Writer(self.connection.makefile('wb', self.wbufsize))
- else:
- self.rfile = Reader(socket.SocketIO(self.connection, "rb"))
- self.wfile = Writer(socket.SocketIO(self.connection, "wb"))
+ self.rfile = Reader(socket.SocketIO(self.connection, "rb"))
+ self.wfile = Writer(socket.SocketIO(self.connection, "wb"))
def __init__(self, connection):
if connection:
@@ -968,8 +959,8 @@ class TCPServer(object):
"""
# If a thread has persisted after interpreter exit, the module might be
# none.
- if traceback and six:
- exc = six.text_type(traceback.format_exc())
+ if traceback:
+ exc = str(traceback.format_exc())
print(u'-' * 40, file=fp)
print(
u"Error in processing of request from %s" % repr(client_address), file=fp)
diff --git a/netlib/tutils.py b/netlib/tutils.py
index 452766d6..5f598fa9 100644
--- a/netlib/tutils.py
+++ b/netlib/tutils.py
@@ -4,7 +4,6 @@ import os
import time
import shutil
from contextlib import contextmanager
-import six
import sys
from netlib import utils, tcp, http
@@ -31,20 +30,20 @@ def tmpdir(*args, **kwargs):
def _check_exception(expected, actual, exc_tb):
- if isinstance(expected, six.string_types):
+ if isinstance(expected, str):
if expected.lower() not in str(actual).lower():
- six.reraise(AssertionError, AssertionError(
+ raise AssertionError(
"Expected %s, but caught %s" % (
repr(expected), repr(actual)
)
- ), exc_tb)
+ )
else:
if not isinstance(actual, expected):
- six.reraise(AssertionError, AssertionError(
+ raise AssertionError(
"Expected %s, but caught %s %s" % (
expected.__name__, actual.__class__.__name__, repr(actual)
)
- ), exc_tb)
+ )
def raises(expected_exception, obj=None, *args, **kwargs):
diff --git a/netlib/version_check.py b/netlib/version_check.py
index 63f3e876..7091146d 100644
--- a/netlib/version_check.py
+++ b/netlib/version_check.py
@@ -7,7 +7,6 @@ from __future__ import division, absolute_import, print_function
import sys
import inspect
import os.path
-import six
import OpenSSL
@@ -15,7 +14,7 @@ PYOPENSSL_MIN_VERSION = (0, 15)
def check_pyopenssl_version(min_version=PYOPENSSL_MIN_VERSION, fp=sys.stderr):
- min_version_str = u".".join(six.text_type(x) for x in min_version)
+ min_version_str = u".".join(str(x) for x in min_version)
try:
v = tuple(int(x) for x in OpenSSL.__version__.split(".")[:2])
except ValueError:
diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py
index e62d0e87..2b36d461 100644
--- a/netlib/websockets/frame.py
+++ b/netlib/websockets/frame.py
@@ -3,8 +3,6 @@ import os
import struct
import io
-import six
-
from netlib import tcp
from netlib import strutils
from netlib import utils
@@ -129,7 +127,7 @@ class FrameHeader(object):
second_byte = utils.setbit(self.length_code, 7, self.mask)
- b = six.int2byte(first_byte) + six.int2byte(second_byte)
+ b = bytes([first_byte, second_byte])
if self.payload_length < 126:
pass
@@ -148,17 +146,12 @@ class FrameHeader(object):
b += self.masking_key
return b
- if six.PY2:
- __str__ = __bytes__
-
@classmethod
def from_file(cls, fp):
"""
read a websockets frame header
"""
- first_byte = six.byte2int(fp.safe_read(1))
- second_byte = six.byte2int(fp.safe_read(1))
-
+ first_byte, second_byte = fp.safe_read(2)
fin = utils.getbit(first_byte, 7)
rsv1 = utils.getbit(first_byte, 6)
rsv2 = utils.getbit(first_byte, 5)
@@ -257,9 +250,6 @@ class Frame(object):
b += self.payload
return b
- if six.PY2:
- __str__ = __bytes__
-
@classmethod
def from_file(cls, fp):
"""
diff --git a/netlib/websockets/masker.py b/netlib/websockets/masker.py
index bd39ed6a..03b8f435 100644
--- a/netlib/websockets/masker.py
+++ b/netlib/websockets/masker.py
@@ -1,7 +1,5 @@
from __future__ import absolute_import
-import six
-
class Masker(object):
"""
@@ -19,10 +17,7 @@ class Masker(object):
def mask(self, offset, data):
result = bytearray(data)
for i in range(len(data)):
- if six.PY2:
- result[i] ^= ord(self.key[offset % 4])
- else:
- result[i] ^= self.key[offset % 4]
+ result[i] ^= self.key[offset % 4]
offset += 1
result = bytes(result)
return result
diff --git a/netlib/wsgi.py b/netlib/wsgi.py
index 0def75b5..17cbbf00 100644
--- a/netlib/wsgi.py
+++ b/netlib/wsgi.py
@@ -2,9 +2,8 @@ from __future__ import (absolute_import, print_function, division)
import time
import traceback
-import six
-from io import BytesIO
-from six.moves import urllib
+import urllib
+import io
from netlib import http, tcp, strutils
@@ -67,7 +66,7 @@ class WSGIAdaptor(object):
environ = {
'wsgi.version': (1, 0),
'wsgi.url_scheme': strutils.native(flow.request.scheme, "latin-1"),
- 'wsgi.input': BytesIO(flow.request.content or b""),
+ 'wsgi.input': io.BytesIO(flow.request.content or b""),
'wsgi.errors': errsoc,
'wsgi.multithread': True,
'wsgi.multiprocess': False,
@@ -139,7 +138,7 @@ class WSGIAdaptor(object):
def start_response(status, headers, exc_info=None):
if exc_info:
if state["headers_sent"]:
- six.reraise(*exc_info)
+ raise exc_info[1]
elif state["status"]:
raise AssertionError('Response already started')
state["status"] = status
@@ -148,7 +147,7 @@ class WSGIAdaptor(object):
self.error_page(soc, state["headers_sent"], traceback.format_tb(exc_info[2]))
state["headers_sent"] = True
- errs = six.BytesIO()
+ errs = io.BytesIO()
try:
dataiter = self.app(
self.make_environ(request, errs, **env), start_response