Ticket #6833: amp-python3-6822-3.patch

File amp-python3-6822-3.patch, 74.2 KB (added by Gavin Panella, 4 years ago)
  • twisted/protocols/amp.py

    diff --git a/twisted/protocols/amp.py b/twisted/protocols/amp.py
    index a744882..5b353e3 100644
    a b has several features: 
    171171      which always issue NUL as the first byte.
    172172"""
    173173
     174from __future__ import unicode_literals
     175
    174176__metaclass__ = type
    175177
    176178import types, warnings
    177179
    178 from cStringIO import StringIO
     180from io import BytesIO
    179181from struct import pack
    180182import decimal, datetime
     183from functools import partial
    181184from itertools import count
    182185
    183 from zope.interface import Interface, implements
     186from zope.interface import Interface, implementer
    184187
    185188from twisted.python.reflect import accumulateClassDict
    186189from twisted.python.failure import Failure
    from twisted.internet.error import PeerVerifyError, ConnectionLost 
    196199from twisted.internet.error import ConnectionClosed
    197200from twisted.internet.defer import Deferred, maybeDeferred, fail
    198201from twisted.protocols.basic import Int16StringReceiver, StatefulStringProtocol
     202from twisted.python.compat import (
     203    iteritems, unicode, nativeString, intToBytes, _PY3, long,
     204)
    199205
    200206try:
    201207    from twisted.internet import ssl
    __all__ = [ 
    269275
    270276
    271277
    272 ASK = '_ask'
    273 ANSWER = '_answer'
    274 COMMAND = '_command'
    275 ERROR = '_error'
    276 ERROR_CODE = '_error_code'
    277 ERROR_DESCRIPTION = '_error_description'
    278 UNKNOWN_ERROR_CODE = 'UNKNOWN'
    279 UNHANDLED_ERROR_CODE = 'UNHANDLED'
     278ASK = b'_ask'
     279ANSWER = b'_answer'
     280COMMAND = b'_command'
     281ERROR = b'_error'
     282ERROR_CODE = b'_error_code'
     283ERROR_DESCRIPTION = b'_error_description'
     284UNKNOWN_ERROR_CODE = b'UNKNOWN'
     285UNHANDLED_ERROR_CODE = b'UNHANDLED'
    280286
    281287MAX_KEY_LENGTH = 0xff
    282288MAX_VALUE_LENGTH = 0xffff
    283289
    284290
     291
     292def byteString(string, encoding="ascii"):
     293    """Coerce C{string} to a byte string.
     294
     295    If C{string} is already a byte string, it is returned unchanged. If it's a
     296    Unicode string, it is encoded with C{encoding}, ASCII by default.
     297
     298    @raise TypeError: If C{string} is neither a Unicode nor a byte string.
     299    @raise LookupError: If C{encoding} is not a recognised encoding.
     300    @raise UnicodeEncodeError: If encoding C{string} fails.
     301
     302    @rtype: C{bytes}
     303    """
     304    if isinstance(string, bytes):
     305        return string
     306    elif isinstance(string, unicode):
     307        return string.encode(encoding)
     308    else:
     309        raise TypeError(
     310            "Expected Unicode string or byte string, got: %r (%r)"
     311            % (string, type(string)))
     312
     313
     314
    285315class IArgumentType(Interface):
    286316    """
    287317    An L{IArgumentType} can serialize a Python object into an AMP box and
    class AmpBox(dict): 
    588618                                # acquire a __dict__...
    589619
    590620
     621    def __init__(self, *args, **kw):
     622        super(AmpBox, self).__init__(*args, **kw)
     623        if _PY3:
     624            non_byte_names = [n for n in self if not isinstance(n, bytes)]
     625            for non_byte_name in non_byte_names:
     626                byte_name = byteString(non_byte_name)
     627                self[byte_name] = self.pop(non_byte_name)
     628
     629
    591630    def copy(self):
    592631        """
    593632        Return another AmpBox just like me.
    class AmpBox(dict): 
    604643        @return: a str encoded according to the rules described in the module
    605644        docstring.
    606645        """
    607         i = self.items()
    608         i.sort()
     646        i = sorted(iteritems(self))
    609647        L = []
    610648        w = L.append
    611649        for k, v in i:
    class AmpBox(dict): 
    622660                w(pack("!H", len(kv)))
    623661                w(kv)
    624662        w(pack("!H", 0))
    625         return ''.join(L)
     663        return b''.join(L)
    626664
    627665
    628666    def _sendTo(self, proto):
    class _SwitchBox(AmpBox): 
    703741
    704742
    705743
     744@implementer(IBoxReceiver)
    706745class BoxDispatcher:
    707746    """
    708747    A L{BoxDispatcher} dispatches '_ask', '_answer', and '_error' L{AmpBox}es,
    class BoxDispatcher: 
    728767    @type boxSender: L{IBoxSender}
    729768    """
    730769
    731     implements(IBoxReceiver)
    732 
    733770    _failAllReason = None
    734771    _outstandingRequests = None
    735     _counter = 0L
     772    _counter = long(0)
    736773    boxSender = None
    737774
    738775    def __init__(self, locator):
    class BoxDispatcher: 
    778815        @return: a string that has not yet been used on this connection.
    779816        """
    780817        self._counter += 1
    781         return '%x' % (self._counter,)
     818        if _PY3:
     819            # Python 3.4 cannot do % interpolation on byte strings so we must
     820            # work with a Unicode string and then encode.
     821            return (u'%x' % self._counter).encode("ascii")
     822        else:
     823            return (b'%x' % self._counter)
    782824
    783825
    784826    def _sendBoxCommand(self, command, box, requiresAnswer=True):
    class BoxDispatcher: 
    918960        question.addErrback(self.unhandledError)
    919961        errorCode = box[ERROR_CODE]
    920962        description = box[ERROR_DESCRIPTION]
     963        if _PY3 and isinstance(description, bytes):
     964            description = description.decode("utf-8", "replace")
    921965        if errorCode in PROTOCOL_ERRORS:
    922966            exc = PROTOCOL_ERRORS[errorCode](errorCode, description)
    923967        else:
    class BoxDispatcher: 
    937981            if error.check(RemoteAmpError):
    938982                code = error.value.errorCode
    939983                desc = error.value.description
     984                if _PY3 and isinstance(desc, unicode):
     985                    desc = desc.encode("utf-8", "replace")
    940986                if error.value.fatal:
    941987                    errorBox = QuitBox()
    942988                else:
    class BoxDispatcher: 
    946992                log.err(error) # here is where server-side logging happens
    947993                               # if the error isn't handled
    948994                code = UNKNOWN_ERROR_CODE
    949                 desc = "Unknown Error"
     995                desc = b"Unknown Error"
    950996            errorBox[ERROR] = box[ASK]
    951997            errorBox[ERROR_DESCRIPTION] = desc
    952998            errorBox[ERROR_CODE] = code
    class BoxDispatcher: 
    10051051        if responder is None:
    10061052            return fail(RemoteAmpError(
    10071053                    UNHANDLED_ERROR_CODE,
    1008                     "Unhandled Command: %r" % (cmd,),
     1054                    byteString("Unhandled Command: %r" % (cmd,)),
    10091055                    False,
    10101056                    local=Failure(UnhandledCommand())))
    10111057        return maybeDeferred(responder, box)
    10121058
    10131059
    10141060
     1061@implementer(IResponderLocator)
    10151062class CommandLocator:
    10161063    """
    10171064    A L{CommandLocator} is a collection of responders to AMP L{Command}s, with
    class CommandLocator: 
    10591106            return subcls
    10601107
    10611108
    1062     implements(IResponderLocator)
    1063 
    1064 
    10651109    def _wrapWithSerialization(self, aCallable, command):
    10661110        """
    10671111        Wrap aCallable with its command's argument de-serialization
    class CommandLocator: 
    11311175        cd = self._commandDispatch
    11321176        if name in cd:
    11331177            commandClass, responderFunc = cd[name]
    1134             responderMethod = types.MethodType(
    1135                 responderFunc, self, self.__class__)
     1178            if _PY3:
     1179                responderMethod = types.MethodType(
     1180                    responderFunc, self)
     1181            else:
     1182                responderMethod = types.MethodType(
     1183                    responderFunc, self, self.__class__)
    11361184            return self._wrapWithSerialization(responderMethod, commandClass)
    11371185
    11381186
    11391187
     1188if _PY3:
     1189    # Apply __metaclass__ to CommandLocator.
     1190    CommandLocator = CommandLocator.__metaclass__(
     1191        "CommandLocator", (CommandLocator, ), {})
     1192
     1193
     1194
     1195@implementer(IResponderLocator)
    11401196class SimpleStringLocator(object):
    11411197    """
    11421198    Implement the L{locateResponder} method to do simple, string-based
    11431199    dispatch.
    11441200    """
    11451201
    1146     implements(IResponderLocator)
    1147 
    1148     baseDispatchPrefix = 'amp_'
     1202    baseDispatchPrefix = b'amp_'
    11491203
    11501204    def locateResponder(self, name):
    11511205        """
    class SimpleStringLocator(object): 
    11571211
    11581212        @param name: the normalized name (from the wire) of the command.
    11591213        """
    1160         fName = self.baseDispatchPrefix + (name.upper())
     1214        fName = nativeString(self.baseDispatchPrefix + name.upper())
    11611215        return getattr(self, fName, None)
    11621216
    11631217
    def _wireNameToPythonIdentifier(key): 
    11931247    @return: a str which is a valid python identifier, looking something like
    11941248    'foo_bar_baz' or 'From'.
    11951249    """
    1196     lkey = key.replace("-", "_")
     1250    assert isinstance(key, bytes), repr(key)
     1251    lkey = nativeString(key.replace(b"-", b"_"))
    11971252    if lkey in PYTHON_KEYWORDS:
    11981253        return lkey.title()
    11991254    return lkey
    12001255
    12011256
    12021257
     1258@implementer(IArgumentType)
    12031259class Argument:
    12041260    """
    12051261    Base-class of all objects that take values from Amp packets and convert
    class Argument: 
    12101266    which will be used to define the behavior of L{IArgumentType.toBox} and
    12111267    L{IArgumentType.fromBox}, respectively.
    12121268    """
    1213     implements(IArgumentType)
    12141269
    12151270    optional = False
    12161271
    class Argument: 
    12711326        if self.optional and st is None:
    12721327            objects[nk] = None
    12731328        else:
     1329            assert isinstance(st, bytes), (
     1330                "%s.fromStringProto(...) should only receive byte strings, "
     1331                "got: %r" % (self.__class__.__name__, st))
    12741332            objects[nk] = self.fromStringProto(st, proto)
    12751333
    12761334
    class Argument: 
    12991357            # strings[name] = None
    13001358            pass
    13011359        else:
    1302             strings[name] = self.toStringProto(obj, proto)
     1360            value = self.toStringProto(obj, proto)
     1361            assert not isinstance(value, unicode), (
     1362                "%s.toStringProto(...) should not return Unicode strings, "
     1363                "got: %r" % (self.__class__.__name__, value))
     1364            strings[name] = value
    13031365
    13041366
    13051367    def fromStringProto(self, inString, proto):
    class Integer(Argument): 
    13611423    """
    13621424    fromString = int
    13631425    def toString(self, inObject):
    1364         return str(int(inObject))
     1426        return intToBytes(inObject)
    13651427
    13661428
    13671429
    class String(Argument): 
    13721434    def toString(self, inObject):
    13731435        return inObject
    13741436
    1375 
    13761437    def fromString(self, inString):
     1438        assert isinstance(inString, bytes), repr(inString)
    13771439        return inString
    13781440
    13791441
    class Boolean(Argument): 
    13921454    Encode True or False as "True" or "False" on the wire.
    13931455    """
    13941456    def fromString(self, inString):
    1395         if inString == 'True':
     1457        if inString == b'True':
    13961458            return True
    1397         elif inString == 'False':
     1459        elif inString == b'False':
    13981460            return False
    13991461        else:
    14001462            raise TypeError("Bad boolean value: %r" % (inString,))
    class Boolean(Argument): 
    14021464
    14031465    def toString(self, inObject):
    14041466        if inObject:
    1405             return 'True'
     1467            return b'True'
    14061468        else:
    1407             return 'False'
     1469            return b'False'
    14081470
    14091471
    14101472
    class Unicode(String): 
    14141476    """
    14151477
    14161478    def toString(self, inObject):
    1417         # assert isinstance(inObject, unicode)
     1479        assert isinstance(inObject, unicode), repr(inObject)
    14181480        return String.toString(self, inObject.encode('utf-8'))
    14191481
    14201482
    14211483    def fromString(self, inString):
    1422         # assert isinstance(inString, str)
     1484        assert isinstance(inString, bytes), repr(inString)
    14231485        return String.fromString(self, inString).decode('utf-8')
    14241486
    14251487
    class Path(Unicode): 
    14381500
    14391501
    14401502    def toString(self, inObject):
    1441         return Unicode.toString(self, inObject.path)
     1503        return Unicode.toString(self, inObject.asTextMode().path)
    14421504
    14431505
    14441506
    class ListOf(Argument): 
    14831545        parser = Int16StringReceiver()
    14841546        parser.stringReceived = strings.append
    14851547        parser.dataReceived(inString)
    1486         return map(self.elementType.fromString, strings)
     1548        elementFromString = self.elementType.fromString
     1549        return [elementFromString(string) for string in strings]
    14871550
    14881551
    14891552    def toString(self, inObject):
    class ListOf(Argument): 
    14951558            serialized = self.elementType.toString(obj)
    14961559            strings.append(pack('!H', len(serialized)))
    14971560            strings.append(serialized)
    1498         return ''.join(strings)
     1561        return b''.join(strings)
    14991562
    15001563
    15011564
    class AmpList(Argument): 
    15221585        @param optional: a boolean indicating whether this argument can be
    15231586        omitted in the protocol.
    15241587        """
     1588        assert all(isinstance(name, bytes) for name, _ in subargs), repr(subargs)
    15251589        self.subargs = subargs
    15261590        Argument.__init__(self, optional)
    15271591
    class AmpList(Argument): 
    15341598
    15351599
    15361600    def toStringProto(self, inObject, proto):
    1537         return ''.join([_objectsToStrings(
     1601        return b''.join([_objectsToStrings(
    15381602                    objects, self.subargs, Box(), proto
    15391603                    ).serialize() for objects in inObject])
    15401604
    class Command: 
    16561720            reverseErrors = attrs['reverseErrors'] = {}
    16571721            er = attrs['allErrors'] = {}
    16581722            if 'commandName' not in attrs:
    1659                 attrs['commandName'] = name
     1723                if _PY3:
     1724                    attrs['commandName'] = name.encode("ascii")
     1725                else:
     1726                    attrs['commandName'] = name
    16601727            newtype = type.__new__(cls, name, bases, attrs)
     1728
     1729            if not isinstance(newtype.commandName, bytes):
     1730                raise TypeError(
     1731                    "Command names must be byte strings, got: %r"
     1732                    % (newtype.commandName, ))
     1733            for name, _ in newtype.arguments:
     1734                if not isinstance(name, bytes):
     1735                    raise TypeError(
     1736                        "Argument names must be byte strings, got: %r"
     1737                        % (name, ))
     1738            for name, _ in newtype.response:
     1739                if not isinstance(name, bytes):
     1740                    raise TypeError(
     1741                        "Response names must be byte strings, got: %r"
     1742                        % (name, ))
     1743
    16611744            errors = {}
    16621745            fatalErrors = {}
    16631746            accumulateClassDict(newtype, 'errors', errors)
    16641747            accumulateClassDict(newtype, 'fatalErrors', fatalErrors)
    1665             for v, k in errors.iteritems():
     1748
     1749            if not isinstance(newtype.errors, dict):
     1750                newtype.errors = dict(newtype.errors)
     1751            if not isinstance(newtype.fatalErrors, dict):
     1752                newtype.fatalErrors = dict(newtype.fatalErrors)
     1753
     1754            for v, k in iteritems(errors):
    16661755                reverseErrors[k] = v
    16671756                er[v] = k
    1668             for v, k in fatalErrors.iteritems():
     1757            for v, k in iteritems(fatalErrors):
    16691758                reverseErrors[k] = v
    16701759                er[v] = k
     1760
     1761            for _, name in iteritems(newtype.errors):
     1762                if not isinstance(name, bytes):
     1763                    raise TypeError(
     1764                        "Error names must be byte strings, got: %r"
     1765                        % (name, ))
     1766            for _, name in iteritems(newtype.fatalErrors):
     1767                if not isinstance(name, bytes):
     1768                    raise TypeError(
     1769                        "Fatal error names must be byte strings, got: %r"
     1770                        % (name, ))
     1771
    16711772            return newtype
    16721773
    16731774    arguments = []
    class Command: 
    16931794        @raise InvalidSignature: if you forgot any required arguments.
    16941795        """
    16951796        self.structured = kw
    1696         givenArgs = kw.keys()
    16971797        forgotten = []
    16981798        for name, arg in self.arguments:
    16991799            pythonName = _wireNameToPythonIdentifier(name)
    1700             if pythonName not in givenArgs and not arg.optional:
     1800            if pythonName not in self.structured and not arg.optional:
    17011801                forgotten.append(pythonName)
    17021802        if forgotten:
    17031803            raise InvalidSignature("forgot %s for %s" % (
    1704                     ', '.join(forgotten), self.commandName))
     1804                ', '.join(forgotten), self.commandName))
    17051805        forgotten = []
    17061806
    17071807
    class Command: 
    18501950
    18511951
    18521952
     1953if _PY3:
     1954    # Apply __metaclass__ to Command.
     1955    Command = Command.__metaclass__("Command", (Command, ), {})
     1956
     1957
     1958
    18531959class _NoCertificate:
    18541960    """
    18551961    This is for peers which don't want to use a local certificate.  Used by
    class _TLSBox(AmpBox): 
    19122018
    19132019    def __init__(self):
    19142020        if ssl is None:
    1915             raise RemoteAmpError("TLS_ERROR", "TLS not available")
     2021            raise RemoteAmpError(b"TLS_ERROR", "TLS not available")
    19162022        AmpBox.__init__(self)
    19172023
    19182024
    class _TLSBox(AmpBox): 
    19212027
    19222028
    19232029    # These properties are described in startTLS
    1924     certificate = _keyprop('tls_localCertificate', _NoCertificate(False))
    1925     verify = _keyprop('tls_verifyAuthorities', None)
     2030    certificate = _keyprop(b'tls_localCertificate', _NoCertificate(False))
     2031    verify = _keyprop(b'tls_verifyAuthorities', None)
    19262032
    19272033    def _sendTo(self, proto):
    19282034        """
    19292035        Send my encoded value to the protocol, then initiate TLS.
    19302036        """
    19312037        ab = AmpBox(self)
    1932         for k in ['tls_localCertificate',
    1933                   'tls_verifyAuthorities']:
     2038        for k in [b'tls_localCertificate',
     2039                  b'tls_verifyAuthorities']:
    19342040            ab.pop(k, None)
    19352041        ab._sendTo(proto)
    19362042        proto._startTLS(self.certificate, self.verify)
    class StartTLS(Command): 
    19682074    response dictionary.
    19692075    """
    19702076
    1971     arguments = [("tls_localCertificate", _LocalArgument(optional=True)),
    1972                  ("tls_verifyAuthorities", _LocalArgument(optional=True))]
     2077    arguments = [(b"tls_localCertificate", _LocalArgument(optional=True)),
     2078                 (b"tls_verifyAuthorities", _LocalArgument(optional=True))]
    19732079
    1974     response = [("tls_localCertificate", _LocalArgument(optional=True)),
    1975                 ("tls_verifyAuthorities", _LocalArgument(optional=True))]
     2080    response = [(b"tls_localCertificate", _LocalArgument(optional=True)),
     2081                (b"tls_verifyAuthorities", _LocalArgument(optional=True))]
    19762082
    19772083    responseType = _TLSBox
    19782084
    class ProtocolSwitchCommand(Command): 
    20622168
    20632169
    20642170
     2171@implementer(IFileDescriptorReceiver)
    20652172class _DescriptorExchanger(object):
    20662173    """
    20672174    L{_DescriptorExchanger} is a mixin for L{BinaryBoxProtocol} which adds
    class _DescriptorExchanger(object): 
    20842191        ordinals, starting from 0.  This is used to construct values for
    20852192        C{fileDescriptorReceived}.
    20862193    """
    2087     implements(IFileDescriptorReceiver)
    20882194
    20892195    def __init__(self):
    20902196        self._descriptors = {}
    20912197        self._getDescriptor = self._descriptors.pop
    2092         self._sendingDescriptorCounter = count().next
    2093         self._receivingDescriptorCounter = count().next
     2198        self._sendingDescriptorCounter = partial(next, count())
     2199        self._receivingDescriptorCounter = partial(next, count())
    20942200
    20952201
    20962202    def _sendFileDescriptor(self, descriptor):
    class _DescriptorExchanger(object): 
    21132219
    21142220
    21152221
     2222@implementer(IBoxSender)
    21162223class BinaryBoxProtocol(StatefulStringProtocol, Int16StringReceiver,
    21172224                        _DescriptorExchanger):
    21182225    """
    class BinaryBoxProtocol(StatefulStringProtocol, Int16StringReceiver, 
    21462253    method will be invoked for each L{AmpBox} that is received.
    21472254    """
    21482255
    2149     implements(IBoxSender)
    2150 
    21512256    _justStartedTLS = False
    21522257    _startingTLSBuffer = None
    21532258    _locked = False
    class _ParserHelper: 
    25472652
    25482653        @return: a list of AmpBoxes encoded in the given string.
    25492654        """
    2550         return cls.parse(StringIO(data))
     2655        return cls.parse(BytesIO(data))
    25512656    parseString = classmethod(parseString)
    25522657
    25532658
    class Decimal(Argument): 
    26302735    U{http://speleotrove.com/decimal/} should be considered the authoritative
    26312736    specification for the format.
    26322737    """
    2633     fromString = decimal.Decimal
     2738
     2739    def fromString(self, inString):
     2740        inString = nativeString(inString)
     2741        return decimal.Decimal(inString)
    26342742
    26352743    def toString(self, inObject):
    26362744        """
    class Decimal(Argument): 
    26382746        """
    26392747        if isinstance(inObject, decimal.Decimal):
    26402748            # Hopefully decimal.Decimal.__str__ actually does what we want.
    2641             return str(inObject)
     2749            return str(inObject).encode("ascii")
    26422750        raise ValueError(
    26432751            "amp.Decimal can only encode instances of decimal.Decimal")
    26442752
    class DateTime(Argument): 
    26762784        Parse a string containing a date and time in the wire format into a
    26772785        C{datetime.datetime} instance.
    26782786        """
     2787        s = nativeString(s)
     2788
    26792789        if len(s) != 32:
    26802790            raise ValueError('invalid date format %r' % (s,))
    26812791
    class DateTime(Argument): 
    27072817        # strftime has no way to format the microseconds, or put a ':' in the
    27082818        # timezone. Surprise!
    27092819
    2710         return '%04i-%02i-%02iT%02i:%02i:%02i.%06i%s%02i:%02i' % (
     2820        # Python 3.4 cannot do % interpolation on byte strings so we pack into
     2821        # an explicitly Unicode string then encode as ASCII.
     2822        packed = u'%04i-%02i-%02iT%02i:%02i:%02i.%06i%s%02i:%02i' % (
    27112823            i.year,
    27122824            i.month,
    27132825            i.day,
    class DateTime(Argument): 
    27182830            sign,
    27192831            abs(minutesOffset) // 60,
    27202832            abs(minutesOffset) % 60)
     2833
     2834        return packed.encode("ascii")
  • twisted/python/dist3.py

    diff --git a/twisted/python/dist3.py b/twisted/python/dist3.py
    index c7a8e61..c65092b 100644
    a b modules = [ 
    138138    "twisted.positioning.ipositioning",
    139139    "twisted.positioning.nmea",
    140140    "twisted.protocols",
     141    "twisted.protocols.amp",
    141142    "twisted.protocols.basic",
    142143    "twisted.protocols.policies",
    143144    "twisted.protocols.test",
    testModules = [ 
    311312    "twisted.python.test.test_versions",
    312313    "twisted.python.test.test_zippath",
    313314    "twisted.test.test_abstract",
     315    "twisted.test.test_amp",
    314316    "twisted.test.test_application",
    315317    "twisted.test.test_compat",
    316318    "twisted.test.test_context",
  • twisted/test/test_amp.py

    diff --git a/twisted/test/test_amp.py b/twisted/test/test_amp.py
    index be389ee..3c58dc8 100644
    a b Tests for L{twisted.protocols.amp}. 
    99import datetime
    1010import decimal
    1111
    12 from zope.interface import implements
     12from zope.interface import implementer
    1313from zope.interface.verify import verifyClass, verifyObject
    1414
    1515from twisted.python import filepath
     16from twisted.python.compat import intToBytes
    1617from twisted.python.failure import Failure
    1718from twisted.protocols import amp
    1819from twisted.trial import unittest
    class TestProto(protocol.Protocol): 
    5354    instanceCount = 0
    5455
    5556    def __init__(self, onConnLost, dataToSend):
     57        assert isinstance(dataToSend, bytes), repr(dataToSend)
    5658        self.onConnLost = onConnLost
    5759        self.dataToSend = dataToSend
    5860        self.instanceId = TestProto.instanceCount
    class SimpleSymmetricProtocol(amp.AMP): 
    9092
    9193    def sendHello(self, text):
    9294        return self.callRemoteString(
    93             "hello",
     95            b"hello",
    9496            hello=text)
    9597
    9698    def amp_HELLO(self, box):
    97         return amp.Box(hello=box['hello'])
     99        return amp.Box(hello=box[b'hello'])
    98100
    99101    def amp_HOWDOYOUDO(self, box):
    100         return amp.QuitBox(howdoyoudo='world')
     102        return amp.QuitBox(howdoyoudo=b'world')
    101103
    102104
    103105
    class TransportPeer(amp.Argument): 
    118120    # this serves as some informal documentation for how to get variables from
    119121    # the protocol or your environment and pass them to methods as arguments.
    120122    def retrieve(self, d, name, proto):
    121         return ''
     123        return b''
    122124
    123125    def fromStringProto(self, notAString, proto):
    124126        return proto.transport.getPeer()
    class TransportPeer(amp.Argument): 
    130132
    131133class Hello(amp.Command):
    132134
    133     commandName = 'hello'
     135    commandName = b'hello'
    134136
    135     arguments = [('hello', amp.String()),
    136                  ('optional', amp.Boolean(optional=True)),
    137                  ('print', amp.Unicode(optional=True)),
    138                  ('from', TransportPeer(optional=True)),
    139                  ('mixedCase', amp.String(optional=True)),
    140                  ('dash-arg', amp.String(optional=True)),
    141                  ('underscore_arg', amp.String(optional=True))]
     137    arguments = [(b'hello', amp.String()),
     138                 (b'optional', amp.Boolean(optional=True)),
     139                 (b'print', amp.Unicode(optional=True)),
     140                 (b'from', TransportPeer(optional=True)),
     141                 (b'mixedCase', amp.String(optional=True)),
     142                 (b'dash-arg', amp.String(optional=True)),
     143                 (b'underscore_arg', amp.String(optional=True))]
    142144
    143     response = [('hello', amp.String()),
    144                 ('print', amp.Unicode(optional=True))]
     145    response = [(b'hello', amp.String()),
     146                (b'print', amp.Unicode(optional=True))]
    145147
    146     errors = {UnfriendlyGreeting: 'UNFRIENDLY'}
     148    errors = {UnfriendlyGreeting: b'UNFRIENDLY'}
    147149
    148     fatalErrors = {DeathThreat: 'DEAD'}
     150    fatalErrors = {DeathThreat: b'DEAD'}
    149151
    150152class NoAnswerHello(Hello):
    151153    commandName = Hello.commandName
    152154    requiresAnswer = False
    153155
    154156class FutureHello(amp.Command):
    155     commandName = 'hello'
    156 
    157     arguments = [('hello', amp.String()),
    158                  ('optional', amp.Boolean(optional=True)),
    159                  ('print', amp.Unicode(optional=True)),
    160                  ('from', TransportPeer(optional=True)),
    161                  ('bonus', amp.String(optional=True)), # addt'l arguments
    162                                                        # should generally be
    163                                                        # added at the end, and
    164                                                        # be optional...
     157    commandName = b'hello'
     158
     159    arguments = [(b'hello', amp.String()),
     160                 (b'optional', amp.Boolean(optional=True)),
     161                 (b'print', amp.Unicode(optional=True)),
     162                 (b'from', TransportPeer(optional=True)),
     163                 (b'bonus', amp.String(optional=True)), # addt'l arguments
     164                                                        # should generally be
     165                                                        # added at the end, and
     166                                                        # be optional...
    165167                 ]
    166168
    167     response = [('hello', amp.String()),
    168                 ('print', amp.Unicode(optional=True))]
     169    response = [(b'hello', amp.String()),
     170                (b'print', amp.Unicode(optional=True))]
    169171
    170     errors = {UnfriendlyGreeting: 'UNFRIENDLY'}
     172    errors = {UnfriendlyGreeting: b'UNFRIENDLY'}
    171173
    172174class WTF(amp.Command):
    173175    """
    class BrokenReturn(amp.Command): 
    180182    None...
    181183    """
    182184
    183     commandName = 'broken_return'
     185    commandName = b'broken_return'
    184186
    185187class Goodbye(amp.Command):
    186188    # commandName left blank on purpose: this tests implicit command names.
    187     response = [('goodbye', amp.String())]
     189    response = [(b'goodbye', amp.String())]
    188190    responseType = amp.QuitBox
    189191
    190192class Howdoyoudo(amp.Command):
    191     commandName = 'howdoyoudo'
     193    commandName = b'howdoyoudo'
    192194    # responseType = amp.QuitBox
    193195
    194196class WaitForever(amp.Command):
    195     commandName = 'wait_forever'
     197    commandName = b'wait_forever'
    196198
    197199class GetList(amp.Command):
    198     commandName = 'getlist'
    199     arguments = [('length', amp.Integer())]
    200     response = [('body', amp.AmpList([('x', amp.Integer())]))]
     200    commandName = b'getlist'
     201    arguments = [(b'length', amp.Integer())]
     202    response = [(b'body', amp.AmpList([(b'x', amp.Integer())]))]
    201203
    202204class DontRejectMe(amp.Command):
    203     commandName = 'dontrejectme'
     205    commandName = b'dontrejectme'
    204206    arguments = [
    205             ('magicWord', amp.Unicode()),
    206             ('list', amp.AmpList([('name', amp.Unicode())], optional=True)),
     207            (b'magicWord', amp.Unicode()),
     208            (b'list', amp.AmpList([(b'name', amp.Unicode())], optional=True)),
    207209            ]
    208     response = [('response', amp.Unicode())]
     210    response = [(b'response', amp.Unicode())]
    209211
    210212class SecuredPing(amp.Command):
    211213    # XXX TODO: actually make this refuse to send over an insecure connection
    212     response = [('pinged', amp.Boolean())]
     214    response = [(b'pinged', amp.Boolean())]
    213215
    214216class TestSwitchProto(amp.ProtocolSwitchCommand):
    215     commandName = 'Switch-Proto'
     217    commandName = b'Switch-Proto'
    216218
    217219    arguments = [
    218         ('name', amp.String()),
     220        (b'name', amp.String()),
    219221        ]
    220     errors = {UnknownProtocol: 'UNKNOWN'}
     222    errors = {UnknownProtocol: b'UNKNOWN'}
    221223
    222224class SingleUseFactory(protocol.ClientFactory):
    223225    def __init__(self, proto):
    class SingleUseFactory(protocol.ClientFactory): 
    234236        self.reasonFailed = reason
    235237        return
    236238
    237 THING_I_DONT_UNDERSTAND = 'gwebol nargo'
     239THING_I_DONT_UNDERSTAND = b'gwebol nargo'
    238240class ThingIDontUnderstandError(Exception):
    239241    pass
    240242
    class SimpleSymmetricCommandProtocol(FactoryNotifier): 
    273275        assert From == self.transport.getPeer()
    274276        if hello == THING_I_DONT_UNDERSTAND:
    275277            raise ThingIDontUnderstandError()
    276         if hello.startswith('fuck'):
     278        if hello.startswith(b'fuck'):
    277279            raise UnfriendlyGreeting("Don't be a dick.")
    278         if hello == 'die':
     280        if hello == b'die':
    279281            raise DeathThreat("aieeeeeeeee")
    280282        result = dict(hello=hello)
    281283        if Print is not None:
    class SimpleSymmetricCommandProtocol(FactoryNotifier): 
    302304    WaitForever.responder(waitforit)
    303305
    304306    def howdo(self):
    305         return dict(howdoyoudo='world')
     307        return dict(howdoyoudo=b'world')
    306308    Howdoyoudo.responder(howdo)
    307309
    308310    def saybye(self):
    309         return dict(goodbye="everyone")
     311        return dict(goodbye=b"everyone")
    310312    Goodbye.responder(saybye)
    311313
    312314    def switchToTestProtocol(self, fail=False):
    313315        if fail:
    314             name = 'no-proto'
     316            name = b'no-proto'
    315317        else:
    316             name = 'test-proto'
     318            name = b'test-proto'
    317319        p = TestProto(self.onConnLost, SWITCH_CLIENT_DATA)
    318320        return self.callRemote(
    319321            TestSwitchProto,
    320322            SingleUseFactory(p), name=name).addCallback(lambda ign: p)
    321323
    322324    def switchit(self, name):
    323         if name == 'test-proto':
     325        if name == b'test-proto':
    324326            return TestProto(self.onConnLost, SWITCH_SERVER_DATA)
    325327        raise UnknownProtocol(name)
    326328    TestSwitchProto.responder(switchit)
    class SimpleSymmetricCommandProtocol(FactoryNotifier): 
    332334
    333335class DeferredSymmetricCommandProtocol(SimpleSymmetricCommandProtocol):
    334336    def switchit(self, name):
    335         if name == 'test-proto':
     337        if name == b'test-proto':
    336338            self.maybeLaterProto = TestProto(self.onConnLost, SWITCH_SERVER_DATA)
    337339            self.maybeLater = defer.Deferred()
    338340            return self.maybeLater
    class BadNoAnswerCommandProtocol(SimpleSymmetricCommandProtocol): 
    350352class NoAnswerCommandProtocol(SimpleSymmetricCommandProtocol):
    351353    def goodNoAnswerResponder(self, hello, From, optional=None, Print=None,
    352354                              mixedCase=None, dash_arg=None, underscore_arg=None):
    353         return dict(hello=hello+"-noanswer")
     355        return dict(hello=hello+b"-noanswer")
    354356    NoAnswerHello.responder(goodNoAnswerResponder)
    355357
    356358def connectedServerAndClient(ServerClass=SimpleSymmetricProtocol,
    def connectedServerAndClient(ServerClass=SimpleSymmetricProtocol, 
    363365        *a, **kw)
    364366
    365367class TotallyDumbProtocol(protocol.Protocol):
    366     buf = ''
     368    buf = b''
    367369    def dataReceived(self, data):
    368370        self.buf += data
    369371
    class AmpBoxTests(unittest.TestCase): 
    387389        """
    388390        Make sure that strs serialize to strs.
    389391        """
    390         a = amp.AmpBox(key='value')
    391         self.assertEqual(type(a.serialize()), str)
     392        a = amp.AmpBox(key=b'value')
     393        self.assertEqual(type(a.serialize()), bytes)
    392394
    393395    def test_serializeUnicodeKeyRaises(self):
    394396        """
    class ParsingTests(unittest.TestCase): 
    415417        else.
    416418        """
    417419        b = amp.Boolean()
    418         self.assertEqual(b.fromString("True"), True)
    419         self.assertEqual(b.fromString("False"), False)
    420         self.assertRaises(TypeError, b.fromString, "ninja")
    421         self.assertRaises(TypeError, b.fromString, "true")
    422         self.assertRaises(TypeError, b.fromString, "TRUE")
    423         self.assertEqual(b.toString(True), 'True')
    424         self.assertEqual(b.toString(False), 'False')
     420        self.assertEqual(b.fromString(b"True"), True)
     421        self.assertEqual(b.fromString(b"False"), False)
     422        self.assertRaises(TypeError, b.fromString, b"ninja")
     423        self.assertRaises(TypeError, b.fromString, b"true")
     424        self.assertRaises(TypeError, b.fromString, b"TRUE")
     425        self.assertEqual(b.toString(True), b'True')
     426        self.assertEqual(b.toString(False), b'False')
    425427
    426428    def test_pathValueRoundTrip(self):
    427429        """
    class ParsingTests(unittest.TestCase): 
    452454        c, s, p = connectedServerAndClient(ClientClass=LiteralAmp,
    453455                                           ServerClass=LiteralAmp)
    454456
    455         SIMPLE = ('simple', 'test')
    456         CE = ('ceq', ': ')
    457         CR = ('crtest', 'test\r')
    458         LF = ('lftest', 'hello\n')
    459         NEWLINE = ('newline', 'test\r\none\r\ntwo')
    460         NEWLINE2 = ('newline2', 'test\r\none\r\n two')
    461         BODYTEST = ('body', 'blah\r\n\r\ntesttest')
     457        SIMPLE = (b'simple', b'test')
     458        CE = (b'ceq', b': ')
     459        CR = (b'crtest', b'test\r')
     460        LF = (b'lftest', b'hello\n')
     461        NEWLINE = (b'newline', b'test\r\none\r\ntwo')
     462        NEWLINE2 = (b'newline2', b'test\r\none\r\n two')
     463        BODYTEST = (b'body', b'blah\r\n\r\ntesttest')
    462464
    463465        testData = [
    464466            [SIMPLE],
    class CommandDispatchTests(unittest.TestCase): 
    621623        fired, and the results translated via the given L{Command}'s response
    622624        de-serialization.
    623625        """
    624         D = self.dispatcher.callRemote(Hello, hello='world')
     626        D = self.dispatcher.callRemote(Hello, hello=b'world')
    625627        self.assertEqual(self.sender.sentBoxes,
    626                           [amp.AmpBox(_command="hello",
    627                                       _ask="1",
    628                                       hello="world")])
     628                          [amp.AmpBox(_command=b"hello",
     629                                      _ask=b"1",
     630                                      hello=b"world")])
    629631        answers = []
    630632        D.addCallback(answers.append)
    631633        self.assertEqual(answers, [])
    632         self.dispatcher.ampBoxReceived(amp.AmpBox({'hello': "yay",
    633                                                    'print': "ignored",
    634                                                    '_answer': "1"}))
    635         self.assertEqual(answers, [dict(hello="yay",
    636                                          Print=u"ignored")])
     634        self.dispatcher.ampBoxReceived(amp.AmpBox({b'hello': b"yay",
     635                                                   b'print': b"ignored",
     636                                                   b'_answer': b"1"}))
     637        self.assertEqual(answers, [dict(hello=b"yay",
     638                                         Print="ignored")])
    637639
    638640
    639641    def _localCallbackErrorLoggingTest(self, callResult):
    class CommandDispatchTests(unittest.TestCase): 
    659661        """
    660662        self.sender.expectError()
    661663
    662         callResult = self.dispatcher.callRemote(Hello, hello='world')
     664        callResult = self.dispatcher.callRemote(Hello, hello=b'world')
    663665        callResult.addCallback(lambda result: 1 // 0)
    664666
    665667        self.dispatcher.ampBoxReceived(amp.AmpBox({
    666                     'hello': "yay", 'print': "ignored", '_answer': "1"}))
     668                    b'hello': b"yay", b'print': b"ignored", b'_answer': b"1"}))
    667669
    668670        self._localCallbackErrorLoggingTest(callResult)
    669671
    class CommandDispatchTests(unittest.TestCase): 
    675677        """
    676678        self.sender.expectError()
    677679
    678         callResult = self.dispatcher.callRemote(Hello, hello='world')
     680        callResult = self.dispatcher.callRemote(Hello, hello=b'world')
    679681        callResult.addErrback(lambda result: 1 // 0)
    680682
    681683        self.dispatcher.ampBoxReceived(amp.AmpBox({
    682                     '_error': '1', '_error_code': 'bugs',
    683                     '_error_description': 'stuff'}))
     684                    b'_error': b'1', b'_error_code': b'bugs',
     685                    b'_error_description': b'stuff'}))
    684686
    685687        self._localCallbackErrorLoggingTest(callResult)
    686688
    class SimpleGreeting(amp.Command): 
    690692    """
    691693    A very simple greeting command that uses a few basic argument types.
    692694    """
    693     commandName = 'simple'
    694     arguments = [('greeting', amp.Unicode()),
    695                  ('cookie', amp.Integer())]
    696     response = [('cookieplus', amp.Integer())]
     695    commandName = b'simple'
     696    arguments = [(b'greeting', amp.Unicode()),
     697                 (b'cookie', amp.Integer())]
     698    response = [(b'cookieplus', amp.Integer())]
    697699
    698700
    699701
    class OverrideLocatorAMP(amp.AMP): 
    738740    def __init__(self):
    739741        amp.AMP.__init__(self)
    740742        self.customResponder = object()
    741         self.expectations = {"custom": self.customResponder}
     743        self.expectations = {b"custom": self.customResponder}
    742744        self.greetings = []
    743745
    744746
    class CommandLocatorTests(unittest.TestCase): 
    775777        command.
    776778        """
    777779        locator = locatorClass()
    778         responderCallable = locator.locateResponder("simple")
    779         result = responderCallable(amp.Box(greeting="ni hao", cookie="5"))
     780        responderCallable = locator.locateResponder(b"simple")
     781        result = responderCallable(amp.Box(greeting=b"ni hao", cookie=b"5"))
    780782        def done(values):
    781             self.assertEqual(values, amp.AmpBox(cookieplus=str(expected)))
     783            self.assertEqual(values, amp.AmpBox(cookieplus=intToBytes(expected)))
    782784        return result.addCallback(done)
    783785
    784786
    class CommandLocatorTests(unittest.TestCase): 
    820822        customResponderObject = self.assertWarns(
    821823            PendingDeprecationWarning,
    822824            "Override locateResponder, not lookupFunction.",
    823             __file__, lambda : locator.locateResponder("custom"))
     825            __file__, lambda : locator.locateResponder(b"custom"))
    824826        self.assertEqual(locator.customResponder, customResponderObject)
    825827        # Make sure upcalling works too
    826828        normalResponderObject = self.assertWarns(
    827829            PendingDeprecationWarning,
    828830            "Override locateResponder, not lookupFunction.",
    829             __file__, lambda : locator.locateResponder("simple"))
    830         result = normalResponderObject(amp.Box(greeting="ni hao", cookie="5"))
     831            __file__, lambda : locator.locateResponder(b"simple"))
     832        result = normalResponderObject(amp.Box(greeting=b"ni hao", cookie=b"5"))
    831833        def done(values):
    832             self.assertEqual(values, amp.AmpBox(cookieplus='8'))
     834            self.assertEqual(values, amp.AmpBox(cookieplus=b'8'))
    833835        return result.addCallback(done)
    834836
    835837
    class CommandLocatorTests(unittest.TestCase): 
    842844        responderCallable = self.assertWarns(
    843845            PendingDeprecationWarning,
    844846            "Call locateResponder, not lookupFunction.", __file__,
    845             lambda : locator.lookupFunction("simple"))
    846         result = responderCallable(amp.Box(greeting="ni hao", cookie="5"))
     847            lambda : locator.lookupFunction(b"simple"))
     848        result = responderCallable(amp.Box(greeting=b"ni hao", cookie=b"5"))
    847849        def done(values):
    848             self.assertEqual(values, amp.AmpBox(cookieplus='8'))
     850            self.assertEqual(values, amp.AmpBox(cookieplus=b'8'))
    849851        return result.addCallback(done)
    850852
    851853
    852854
    853 SWITCH_CLIENT_DATA = 'Success!'
    854 SWITCH_SERVER_DATA = 'No, really.  Success.'
     855SWITCH_CLIENT_DATA = b'Success!'
     856SWITCH_SERVER_DATA = b'No, really.  Success.'
    855857
    856858
    857859class BinaryProtocolTests(unittest.TestCase):
    class BinaryProtocolTests(unittest.TestCase): 
    903905
    904906
    905907    def write(self, data):
     908        self.assertIsInstance(data, bytes)
    906909        self.data.append(data)
    907910
    908911
    class BinaryProtocolTests(unittest.TestCase): 
    926929        """
    927930        class SynchronouslySendingReceiver:
    928931            def startReceivingBoxes(self, sender):
    929                 sender.sendBox(amp.Box({'foo': 'bar'}))
     932                sender.sendBox(amp.Box({b'foo': b'bar'}))
    930933
    931934        transport = StringTransport()
    932935        protocol = amp.BinaryBoxProtocol(SynchronouslySendingReceiver())
    933936        protocol.makeConnection(transport)
    934937        self.assertEqual(
    935938            transport.value(),
    936             '\x00\x03foo\x00\x03bar\x00\x00')
     939            b'\x00\x03foo\x00\x03bar\x00\x00')
    937940
    938941
    939942    def test_receiveBoxStateMachine(self):
    class BinaryProtocolTests(unittest.TestCase): 
    945948        it should emit a box and send it to its boxReceiver.
    946949        """
    947950        a = amp.BinaryBoxProtocol(self)
    948         a.stringReceived("hello")
    949         a.stringReceived("world")
    950         a.stringReceived("")
    951         self.assertEqual(self.boxes, [amp.AmpBox(hello="world")])
     951        a.stringReceived(b"hello")
     952        a.stringReceived(b"world")
     953        a.stringReceived(b"")
     954        self.assertEqual(self.boxes, [amp.AmpBox(hello=b"world")])
    952955
    953956
    954957    def test_firstBoxFirstKeyExcessiveLength(self):
    class BinaryProtocolTests(unittest.TestCase): 
    959962        transport = StringTransport()
    960963        protocol = amp.BinaryBoxProtocol(self)
    961964        protocol.makeConnection(transport)
    962         protocol.dataReceived('\x01\x00')
     965        protocol.dataReceived(b'\x01\x00')
    963966        self.assertTrue(transport.disconnecting)
    964967
    965968
    class BinaryProtocolTests(unittest.TestCase): 
    971974        transport = StringTransport()
    972975        protocol = amp.BinaryBoxProtocol(self)
    973976        protocol.makeConnection(transport)
    974         protocol.dataReceived('\x00\x01k\x00\x01v')
     977        protocol.dataReceived(b'\x00\x01k\x00\x01v')
    975978        self.assertFalse(transport.disconnecting)
    976         protocol.dataReceived('\x01\x00')
     979        protocol.dataReceived(b'\x01\x00')
    977980        self.assertTrue(transport.disconnecting)
    978981
    979982
    class BinaryProtocolTests(unittest.TestCase): 
    985988        transport = StringTransport()
    986989        protocol = amp.BinaryBoxProtocol(self)
    987990        protocol.makeConnection(transport)
    988         protocol.dataReceived('\x00\x01k\x00\x01v\x00\x00')
     991        protocol.dataReceived(b'\x00\x01k\x00\x01v\x00\x00')
    989992        self.assertFalse(transport.disconnecting)
    990         protocol.dataReceived('\x01\x00')
     993        protocol.dataReceived(b'\x01\x00')
    991994        self.assertTrue(transport.disconnecting)
    992995
    993996
    class BinaryProtocolTests(unittest.TestCase): 
    9991002        """
    10001003        protocol = amp.BinaryBoxProtocol(self)
    10011004        protocol.makeConnection(StringTransport())
    1002         protocol.dataReceived('\x01\x00')
     1005        protocol.dataReceived(b'\x01\x00')
    10031006        protocol.connectionLost(
    10041007            Failure(error.ConnectionDone("simulated connection done")))
    10051008        self.stopReason.trap(amp.TooLong)
    class BinaryProtocolTests(unittest.TestCase): 
    10401043        it should emit a similar box to its boxReceiver.
    10411044        """
    10421045        a = amp.BinaryBoxProtocol(self)
    1043         a.dataReceived(amp.Box({"testKey": "valueTest",
    1044                                 "anotherKey": "anotherValue"}).serialize())
     1046        a.dataReceived(amp.Box({b"testKey": b"valueTest",
     1047                                b"anotherKey": b"anotherValue"}).serialize())
    10451048        self.assertEqual(self.boxes,
    1046                           [amp.Box({"testKey": "valueTest",
    1047                                     "anotherKey": "anotherValue"})])
     1049                          [amp.Box({b"testKey": b"valueTest",
     1050                                    b"anotherKey": b"anotherValue"})])
    10481051
    10491052
    10501053    def test_receiveLongerBoxData(self):
    class BinaryProtocolTests(unittest.TestCase): 
    10531056        values of up to (2 ** 16 - 1) bytes.
    10541057        """
    10551058        length = (2 ** 16 - 1)
    1056         value = 'x' * length
     1059        value = b'x' * length
    10571060        transport = StringTransport()
    10581061        protocol = amp.BinaryBoxProtocol(self)
    10591062        protocol.makeConnection(transport)
    class BinaryProtocolTests(unittest.TestCase): 
    10691072        """
    10701073        a = amp.BinaryBoxProtocol(self)
    10711074        a.makeConnection(self)
    1072         aBox = amp.Box({"testKey": "valueTest",
    1073                         "someData": "hello"})
     1075        aBox = amp.Box({b"testKey": b"valueTest",
     1076                        b"someData": b"hello"})
    10741077        a.makeConnection(self)
    10751078        a.sendBox(aBox)
    1076         self.assertEqual(''.join(self.data), aBox.serialize())
     1079        self.assertEqual(b''.join(self.data), aBox.serialize())
    10771080
    10781081
    10791082    def test_connectionLostStopSendingBoxes(self):
    class BinaryProtocolTests(unittest.TestCase): 
    10941097        on a box boundary.  When a protocol is in the process of switching, it
    10951098        cannot receive traffic.
    10961099        """
    1097         otherProto = TestProto(None, "outgoing data")
     1100        otherProto = TestProto(None, b"outgoing data")
    10981101        test = self
    10991102        class SwitchyReceiver:
    11001103            switched = False
    class BinaryProtocolTests(unittest.TestCase): 
    11071110                a._lockForSwitch()
    11081111                a._switchTo(otherProto)
    11091112        a = amp.BinaryBoxProtocol(SwitchyReceiver())
    1110         anyOldBox = amp.Box({"include": "lots",
    1111                              "of": "data"})
     1113        anyOldBox = amp.Box({b"include": b"lots",
     1114                             b"of": b"data"})
    11121115        a.makeConnection(self)
    11131116        # Include a 0-length box at the beginning of the next protocol's data,
    11141117        # to make sure that AMP doesn't eat the data or try to deliver extra
    11151118        # boxes either...
    1116         moreThanOneBox = anyOldBox.serialize() + "\x00\x00Hello, world!"
     1119        moreThanOneBox = anyOldBox.serialize() + b"\x00\x00Hello, world!"
    11171120        a.dataReceived(moreThanOneBox)
    11181121        self.assertIdentical(otherProto.transport, self)
    1119         self.assertEqual("".join(otherProto.data), "\x00\x00Hello, world!")
    1120         self.assertEqual(self.data, ["outgoing data"])
    1121         a.dataReceived("more data")
    1122         self.assertEqual("".join(otherProto.data),
    1123                           "\x00\x00Hello, world!more data")
     1122        self.assertEqual(b"".join(otherProto.data), b"\x00\x00Hello, world!")
     1123        self.assertEqual(self.data, [b"outgoing data"])
     1124        a.dataReceived(b"more data")
     1125        self.assertEqual(b"".join(otherProto.data),
     1126                          b"\x00\x00Hello, world!more data")
    11241127        self.assertRaises(amp.ProtocolSwitched, a.sendBox, anyOldBox)
    11251128
    11261129
    class BinaryProtocolTests(unittest.TestCase): 
    11321135        """
    11331136        a = amp.BinaryBoxProtocol(self)
    11341137        a.makeConnection(self)
    1135         otherProto = TestProto(None, "")
     1138        otherProto = TestProto(None, b"")
    11361139        a._switchTo(otherProto)
    11371140        self.assertEqual(otherProto.data, [])
    11381141
    class BinaryProtocolTests(unittest.TestCase): 
    11461149        """
    11471150        a = amp.BinaryBoxProtocol(self)
    11481151        a.makeConnection(self)
    1149         sampleBox = amp.Box({"some": "data"})
     1152        sampleBox = amp.Box({b"some": b"data"})
    11501153        a._lockForSwitch()
    11511154        self.assertRaises(amp.ProtocolSwitched, a.sendBox, sampleBox)
    11521155        a._unlockFromSwitch()
    11531156        a.sendBox(sampleBox)
    1154         self.assertEqual(''.join(self.data), sampleBox.serialize())
     1157        self.assertEqual(b''.join(self.data), sampleBox.serialize())
    11551158        a._lockForSwitch()
    1156         otherProto = TestProto(None, "outgoing data")
     1159        otherProto = TestProto(None, b"outgoing data")
    11571160        a._switchTo(otherProto)
    11581161        self.assertRaises(amp.ProtocolSwitched, a._unlockFromSwitch)
    11591162
    class AMPTests(unittest.TestCase): 
    12231226        """
    12241227        c, s, p = connectedServerAndClient()
    12251228        L = []
    1226         HELLO = 'world'
     1229        HELLO = b'world'
    12271230        c.sendHello(HELLO).addCallback(L.append)
    12281231        p.flush()
    1229         self.assertEqual(L[0]['hello'], HELLO)
     1232        self.assertEqual(L[0][b'hello'], HELLO)
    12301233
    12311234
    12321235    def test_wireFormatRoundTrip(self):
    class AMPTests(unittest.TestCase): 
    12361239        """
    12371240        c, s, p = connectedServerAndClient()
    12381241        L = []
    1239         HELLO = 'world'
     1242        HELLO = b'world'
    12401243        c.sendHello(HELLO).addCallback(L.append)
    12411244        p.flush()
    1242         self.assertEqual(L[0]['hello'], HELLO)
     1245        self.assertEqual(L[0][b'hello'], HELLO)
    12431246
    12441247
    12451248    def test_helloWorldUnicode(self):
    class AMPTests(unittest.TestCase): 
    12501253            ServerClass=SimpleSymmetricCommandProtocol,
    12511254            ClientClass=SimpleSymmetricCommandProtocol)
    12521255        L = []
    1253         HELLO = 'world'
    1254         HELLO_UNICODE = 'wor\u1234ld'
     1256        HELLO = b'world'
     1257        HELLO_UNICODE = u'wor\u1234ld'
    12551258        c.sendUnicodeHello(HELLO, HELLO_UNICODE).addCallback(L.append)
    12561259        p.flush()
    12571260        self.assertEqual(L[0]['hello'], HELLO)
    class AMPTests(unittest.TestCase): 
    12641267        is C{False}.
    12651268        """
    12661269        c, s, p = connectedServerAndClient()
    1267         ret = c.callRemoteString("WTF", requiresAnswer=False)
     1270        ret = c.callRemoteString(b"WTF", requiresAnswer=False)
    12681271        self.assertIdentical(ret, None)
    12691272
    12701273
    class AMPTests(unittest.TestCase): 
    12811284            """
    12821285            e.trap(amp.UnhandledCommand)
    12831286            return "OK"
    1284         c.callRemoteString("WTF").addErrback(clearAndAdd).addCallback(L.append)
     1287        c.callRemoteString(b"WTF").addErrback(clearAndAdd).addCallback(L.append)
    12851288        p.flush()
    12861289        self.assertEqual(L.pop(), "OK")
    1287         HELLO = 'world'
     1290        HELLO = b'world'
    12881291        c.sendHello(HELLO).addCallback(L.append)
    12891292        p.flush()
    1290         self.assertEqual(L[0]['hello'], HELLO)
     1293        self.assertEqual(L[0][b'hello'], HELLO)
    12911294
    12921295
    12931296    def test_unknownCommandHigh(self):
    class AMPTests(unittest.TestCase): 
    13061309        c.callRemote(WTF).addErrback(clearAndAdd).addCallback(L.append)
    13071310        p.flush()
    13081311        self.assertEqual(L.pop(), "OK")
    1309         HELLO = 'world'
     1312        HELLO = b'world'
    13101313        c.sendHello(HELLO).addCallback(L.append)
    13111314        p.flush()
    1312         self.assertEqual(L[0]['hello'], HELLO)
     1315        self.assertEqual(L[0][b'hello'], HELLO)
    13131316
    13141317
    13151318    def test_brokenReturnValue(self):
    class AMPTests(unittest.TestCase): 
    13361339            ServerClass=SimpleSymmetricCommandProtocol,
    13371340            ClientClass=SimpleSymmetricCommandProtocol)
    13381341        L = []
    1339         HELLO = 'world'
     1342        HELLO = b'world'
    13401343        # c.sendHello(HELLO).addCallback(L.append)
    13411344        c.callRemote(FutureHello,
    13421345                     hello=HELLO,
    1343                      bonus="I'm not in the book!").addCallback(
     1346                     bonus=b"I'm not in the book!").addCallback(
    13441347            L.append)
    13451348        p.flush()
    13461349        self.assertEqual(L[0]['hello'], HELLO)
    class AMPTests(unittest.TestCase): 
    13601363        """
    13611364        Verify that L{AMP} objects output their innerProtocol when set.
    13621365        """
    1363         otherProto = TestProto(None, "outgoing data")
     1366        otherProto = TestProto(None, b"outgoing data")
    13641367        a = amp.AMP()
    13651368        a.innerProtocol = otherProto
    13661369
    class AMPTests(unittest.TestCase): 
    13951398        c, s, p = connectedServerAndClient()
    13961399        x = "H" * (0xff+1)
    13971400        tl = self.assertRaises(amp.TooLong,
    1398                                c.callRemoteString, "Hello",
    1399                                **{x: "hi"})
     1401                               c.callRemoteString, b"Hello",
     1402                               **{x: b"hi"})
    14001403        self.assertTrue(tl.isKey)
    14011404        self.assertTrue(tl.isLocal)
    14021405        self.assertIdentical(tl.keyName, None)
    1403         self.assertEqual(tl.value, x)
     1406        self.assertEqual(tl.value, x.encode("ascii"))
    14041407        self.assertIn(str(len(x)), repr(tl))
    14051408        self.assertIn("key", repr(tl))
    14061409
    class AMPTests(unittest.TestCase): 
    14111414        raise an exception.
    14121415        """
    14131416        c, s, p = connectedServerAndClient()
    1414         x = "H" * (0xffff+1)
     1417        x = b"H" * (0xffff+1)
    14151418        tl = self.assertRaises(amp.TooLong, c.sendHello, x)
    14161419        p.flush()
    14171420        self.assertFalse(tl.isKey)
    14181421        self.assertTrue(tl.isLocal)
    1419         self.assertEqual(tl.keyName, 'hello')
     1422        self.assertEqual(tl.keyName, b'hello')
    14201423        self.failUnlessIdentical(tl.value, x)
    14211424        self.assertTrue(str(len(x)) in repr(tl))
    14221425        self.assertTrue("value" in repr(tl))
    class AMPTests(unittest.TestCase): 
    14321435            ServerClass=SimpleSymmetricCommandProtocol,
    14331436            ClientClass=SimpleSymmetricCommandProtocol)
    14341437        L = []
    1435         HELLO = 'world'
     1438        HELLO = b'world'
    14361439        c.sendHello(HELLO).addCallback(L.append)
    14371440        p.flush()
    14381441        self.assertEqual(L[0]['hello'], HELLO)
    class AMPTests(unittest.TestCase): 
    14481451        c, s, p = connectedServerAndClient(
    14491452            ServerClass=SimpleSymmetricCommandProtocol,
    14501453            ClientClass=SimpleSymmetricCommandProtocol)
    1451         HELLO = 'fuck you'
     1454        HELLO = b'fuck you'
    14521455        c.sendHello(HELLO).addErrback(L.append)
    14531456        p.flush()
    14541457        L[0].trap(UnfriendlyGreeting)
    class AMPTests(unittest.TestCase): 
    14661469        c, s, p = connectedServerAndClient(
    14671470            ServerClass=SimpleSymmetricCommandProtocol,
    14681471            ClientClass=SimpleSymmetricCommandProtocol)
    1469         HELLO = 'die'
     1472        HELLO = b'die'
    14701473        c.sendHello(HELLO).addErrback(L.append)
    14711474        p.flush()
    14721475        L.pop().trap(DeathThreat)
    class AMPTests(unittest.TestCase): 
    15261529        c, s, p = connectedServerAndClient(
    15271530            ServerClass=SimpleSymmetricCommandProtocol,
    15281531            ClientClass=SimpleSymmetricCommandProtocol)
    1529         HELLO = 'world'
     1532        HELLO = b'world'
    15301533        c.callRemote(NoAnswerHello, hello=HELLO)
    15311534        p.flush()
    15321535        self.assertTrue(s.greeted)
    class AMPTests(unittest.TestCase): 
    15401543        c, s, p = connectedServerAndClient(
    15411544            ServerClass=SimpleSymmetricCommandProtocol,
    15421545            ClientClass=SimpleSymmetricCommandProtocol)
    1543         HELLO = 'fuck you'
     1546        HELLO = b'fuck you'
    15441547        c.callRemote(NoAnswerHello, hello=HELLO)
    15451548        p.flush()
    15461549        # This should be logged locally.
    15471550        self.assertTrue(self.flushLoggedErrors(amp.RemoteAmpError))
    1548         HELLO = 'world'
     1551        HELLO = b'world'
    15491552        c.callRemote(Hello, hello=HELLO).addErrback(L.append)
    15501553        p.flush()
    15511554        L.pop().trap(error.ConnectionDone)
    class AMPTests(unittest.TestCase): 
    15641567        c, s, p = connectedServerAndClient(
    15651568            ServerClass=BadNoAnswerCommandProtocol,
    15661569            ClientClass=SimpleSymmetricCommandProtocol)
    1567         c.callRemote(NoAnswerHello, hello="hello")
     1570        c.callRemote(NoAnswerHello, hello=b"hello")
    15681571        p.flush()
    15691572        le = self.flushLoggedErrors(amp.BadLocalReturn)
    15701573        self.assertEqual(len(le), 1)
    class AMPTests(unittest.TestCase): 
    15801583            ServerClass=NoAnswerCommandProtocol,
    15811584            ClientClass=SimpleSymmetricCommandProtocol)
    15821585        L = []
    1583         c.callRemote(Hello, hello="Hello!").addCallback(L.append)
     1586        c.callRemote(Hello, hello=b"Hello!").addCallback(L.append)
    15841587        p.flush()
    15851588        self.assertEqual(len(L), 1)
    1586         self.assertEqual(L, [dict(hello="Hello!-noanswer",
     1589        self.assertEqual(L, [dict(hello=b"Hello!-noanswer",
    15871590                                   Print=None)])  # Optional response argument
    15881591
    15891592
    class AMPTests(unittest.TestCase): 
    16251628            ClientClass=SimpleSymmetricCommandProtocol)
    16261629        L = []
    16271630        c.callRemote(DontRejectMe, magicWord=u'please',
    1628                 list=[{'name': 'foo'}]).addCallback(L.append)
     1631                list=[{'name': u'foo'}]).addCallback(L.append)
    16291632        p.flush()
    16301633        response = L.pop().get('response')
    16311634        self.assertEqual(response, 'foo accepted')
    class AMPTests(unittest.TestCase): 
    16801683            c.callRemote(WaitForever).addErrback(wfdr.append)
    16811684        switchDeferred = c.switchToTestProtocol()
    16821685        if spuriousTraffic:
    1683             self.assertRaises(amp.ProtocolSwitched, c.sendHello, 'world')
     1686            self.assertRaises(amp.ProtocolSwitched, c.sendHello, b'world')
    16841687
    1685         def cbConnsLost(((serverSuccess, serverData),
    1686                          (clientSuccess, clientData))):
     1688        def cbConnsLost(info):
     1689            ((serverSuccess, serverData), (clientSuccess, clientData)) = info
    16871690            self.assertTrue(serverSuccess)
    16881691            self.assertTrue(clientSuccess)
    1689             self.assertEqual(''.join(serverData), SWITCH_CLIENT_DATA)
    1690             self.assertEqual(''.join(clientData), SWITCH_SERVER_DATA)
     1692            self.assertEqual(b''.join(serverData), SWITCH_CLIENT_DATA)
     1693            self.assertEqual(b''.join(clientData), SWITCH_SERVER_DATA)
    16911694            self.testSucceeded = True
    16921695
    16931696        def cbSwitch(proto):
    class AMPTests(unittest.TestCase): 
    17421745        self.assertFalse(self.testSucceeded)
    17431746        # It's a known error, so let's send a "hello" on the same connection;
    17441747        # it should work.
    1745         c.sendHello('world').addCallback(L.append)
     1748        c.sendHello(b'world').addCallback(L.append)
    17461749        p.flush()
    1747         self.assertEqual(L.pop()['hello'], 'world')
     1750        self.assertEqual(L.pop()['hello'], b'world')
    17481751
    17491752
    17501753    def test_trafficAfterSwitch(self):
    class AMPTests(unittest.TestCase): 
    17741777            ClientClass=SimpleSymmetricCommandProtocol)
    17751778
    17761779        L = []
    1777         HELLO = 'world'
    1778         GOODBYE = 'everyone'
     1780        HELLO = b'world'
     1781        GOODBYE = b'everyone'
    17791782        c.sendHello(HELLO).addCallback(L.append)
    17801783        p.flush()
    17811784        self.assertEqual(L.pop()['hello'], HELLO)
    class AMPTests(unittest.TestCase): 
    17941797        c, s, p = connectedServerAndClient()
    17951798        L = []
    17961799        s.ampBoxReceived = L.append
    1797         c.callRemote(Hello, hello='hello test', mixedCase='mixed case arg test',
    1798                      dash_arg='x', underscore_arg='y')
     1800        c.callRemote(Hello, hello=b'hello test', mixedCase=b'mixed case arg test',
     1801                     dash_arg=b'x', underscore_arg=b'y')
    17991802        p.flush()
    18001803        self.assertEqual(len(L), 1)
    1801         for k, v in [('_command', Hello.commandName),
    1802                      ('hello', 'hello test'),
    1803                      ('mixedCase', 'mixed case arg test'),
    1804                      ('dash-arg', 'x'),
    1805                      ('underscore_arg', 'y')]:
     1804        for k, v in [(b'_command', Hello.commandName),
     1805                     (b'hello', b'hello test'),
     1806                     (b'mixedCase', b'mixed case arg test'),
     1807                     (b'dash-arg', b'x'),
     1808                     (b'underscore_arg', b'y')]:
    18061809            self.assertEqual(L[-1].pop(k), v)
    1807         L[-1].pop('_ask')
     1810        L[-1].pop(b'_ask')
    18081811        self.assertEqual(L[-1], {})
    18091812
    18101813
    class AMPTests(unittest.TestCase): 
    18181821        class StructuredHello(amp.AMP):
    18191822            def h(self, *a, **k):
    18201823                L.append((a, k))
    1821                 return dict(hello='aaa')
     1824                return dict(hello=b'aaa')
    18221825            Hello.responder(h)
    18231826        c, s, p = connectedServerAndClient(ServerClass=StructuredHello)
    1824         c.callRemote(Hello, hello='hello test', mixedCase='mixed case arg test',
    1825                      dash_arg='x', underscore_arg='y').addCallback(L.append)
     1827        c.callRemote(Hello, hello=b'hello test', mixedCase=b'mixed case arg test',
     1828                     dash_arg=b'x', underscore_arg=b'y').addCallback(L.append)
    18261829        p.flush()
    18271830        self.assertEqual(len(L), 2)
    18281831        self.assertEqual(L[0],
    18291832                          ((), dict(
    1830                     hello='hello test',
    1831                     mixedCase='mixed case arg test',
    1832                     dash_arg='x',
    1833                     underscore_arg='y',
     1833                    hello=b'hello test',
     1834                    mixedCase=b'mixed case arg test',
     1835                    dash_arg=b'x',
     1836                    underscore_arg=b'y',
    18341837                    From=s.transport.getPeer(),
    18351838
    18361839                    # XXX - should optional arguments just not be passed?
    class AMPTests(unittest.TestCase): 
    18391842                    Print=None,
    18401843                    optional=None,
    18411844                    )))
    1842         self.assertEqual(L[1], dict(Print=None, hello='aaa'))
     1845        self.assertEqual(L[1], dict(Print=None, hello=b'aaa'))
    18431846
    18441847class PretendRemoteCertificateAuthority:
    18451848    def checkIsPretendRemote(self):
    class TLSNotAvailableTests(unittest.TestCase): 
    20522055        okc = OKCert()
    20532056        svr.certFactory = lambda : okc
    20542057        box = amp.Box()
    2055         box['_command'] = 'StartTLS'
    2056         box['_ask'] = '1'
     2058        box[b'_command'] = b'StartTLS'
     2059        box[b'_ask'] = b'1'
    20572060        boxes = []
    20582061        svr.sendBox = boxes.append
    20592062        svr.makeConnection(StringTransport())
    20602063        svr.ampBoxReceived(box)
    20612064        self.assertEqual(boxes,
    2062             [{'_error_code': 'TLS_ERROR',
    2063               '_error': '1',
    2064               '_error_description': 'TLS not available'}])
     2065            [{b'_error_code': b'TLS_ERROR',
     2066              b'_error': b'1',
     2067              b'_error_description': b'TLS not available'}])
    20652068
    20662069
    20672070
    class BaseCommand(amp.Command): 
    20832086    """
    20842087    This provides a command that will be subclassed.
    20852088    """
    2086     errors = {InheritedError: 'INHERITED_ERROR'}
     2089    errors = {InheritedError: b'INHERITED_ERROR'}
    20872090
    20882091
    20892092
    class AddErrorsCommand(BaseCommand): 
    21002103    This is a command which subclasses another command but adds errors to the
    21012104    list.
    21022105    """
    2103     arguments = [('other', amp.Boolean())]
    2104     errors = {OtherInheritedError: 'OTHER_INHERITED_ERROR'}
     2106    arguments = [(b'other', amp.Boolean())]
     2107    errors = {OtherInheritedError: b'OTHER_INHERITED_ERROR'}
    21052108
    21062109
    21072110
    class ProtocolIncludingArgument(amp.Argument): 
    23822385        @type obj: L{object}
    23832386        @type protocol: L{amp.AMP}
    23842387        """
    2385         return "%s:%s" % (id(obj), id(protocol))
     2388        ident = u"%d:%d" % (id(obj), id(protocol))
     2389        return ident.encode("ascii")
    23862390
    23872391
    23882392
    class ProtocolIncludingCommand(amp.Command): 
    23912395    A command that has argument and response schemas which use
    23922396    L{ProtocolIncludingArgument}.
    23932397    """
    2394     arguments = [('weird', ProtocolIncludingArgument())]
    2395     response = [('weird', ProtocolIncludingArgument())]
     2398    arguments = [(b'weird', ProtocolIncludingArgument())]
     2399    response = [(b'weird', ProtocolIncludingArgument())]
    23962400
    23972401
    23982402
    class CommandTests(unittest.TestCase): 
    24992503        Command's response schema.
    25002504        """
    25012505        protocol = object()
    2502         result = 'whatever'
    2503         strings = {'weird': result}
     2506        result = b'whatever'
     2507        strings = {b'weird': result}
    25042508        self.assertEqual(
    25052509            ProtocolIncludingCommand.parseResponse(strings, protocol),
    25062510            {'weird': (result, protocol)})
    class CommandTests(unittest.TestCase): 
    25132517        C{parseResponse} method to get the response.
    25142518        """
    25152519        client = NoNetworkProtocol()
    2516         thingy = "weeoo"
     2520        thingy = b"weeoo"
    25172521        response = client.callRemote(MagicSchemaCommand, weird=thingy)
    25182522        def gotResponse(ign):
    25192523            self.assertEqual(client.parseResponseArguments,
    class CommandTests(unittest.TestCase): 
    25302534        command's argument schema.
    25312535        """
    25322536        protocol = object()
    2533         result = 'whatever'
    2534         strings = {'weird': result}
     2537        result = b'whatever'
     2538        strings = {b'weird': result}
    25352539        self.assertEqual(
    25362540            ProtocolIncludingCommand.parseArguments(strings, protocol),
    25372541            {'weird': (result, protocol)})
    class CommandTests(unittest.TestCase): 
    25632567        protocol = object()
    25642568        argument = object()
    25652569        objects = {'weird': argument}
     2570        ident = u"%d:%d" % (id(argument), id(protocol))
    25662571        self.assertEqual(
    25672572            ProtocolIncludingCommand.makeArguments(objects, protocol),
    2568             {'weird': "%d:%d" % (id(argument), id(protocol))})
     2573            {b'weird': ident.encode("ascii")})
    25692574
    25702575
    25712576    def test_makeArgumentsUsesCommandType(self):
    class CommandTests(unittest.TestCase): 
    25742579        of the result of L{amp.Command.commandType}.
    25752580        """
    25762581        protocol = object()
    2577         objects = {"weird": "whatever"}
     2582        objects = {"weird": b"whatever"}
    25782583
    25792584        result = ProtocolIncludingCommandWithDifferentCommandType.makeArguments(
    25802585            objects, protocol)
    class ListOfTestsMixin: 
    26362641        instance.  The tests will make a L{ListOf} using this.
    26372642
    26382643    @ivar strings: Subclasses should set this to a dictionary mapping some
    2639         number of keys to the correct serialized form for some example
    2640         values. These should agree with what L{elementType}
     2644        number of keys -- as BYTE strings -- to the correct serialized form
     2645        for some example values. These should agree with what L{elementType}
    26412646        produces/accepts.
    26422647
    26432648    @ivar objects: Subclasses should set this to a dictionary with the same
    2644         keys as C{strings} and with values which are the lists which should
    2645         serialize to the values in the C{strings} dictionary.
     2649        keys as C{strings} -- as NATIVE strings -- and with values which are
     2650        the lists which should serialize to the values in the C{strings}
     2651        dictionary.
    26462652    """
    26472653    def test_toBox(self):
    26482654        """
    class ListOfTestsMixin: 
    26562662        stringList = amp.ListOf(self.elementType)
    26572663        strings = amp.AmpBox()
    26582664        for key in self.objects:
    2659             stringList.toBox(key, strings, self.objects.copy(), None)
     2665            stringList.toBox(
     2666                key.encode("ascii"), strings, self.objects.copy(), None)
    26602667        self.assertEqual(strings, self.strings)
    26612668
    26622669
    class ListOfStringsTests(unittest.TestCase, ListOfTestsMixin): 
    26792686    elementType = amp.String()
    26802687
    26812688    strings = {
    2682         "empty": "",
    2683         "single": "\x00\x03foo",
    2684         "multiple": "\x00\x03bar\x00\x03baz\x00\x04quux"}
     2689        b"empty": b"",
     2690        b"single": b"\x00\x03foo",
     2691        b"multiple": b"\x00\x03bar\x00\x03baz\x00\x04quux"}
    26852692
    26862693    objects = {
    26872694        "empty": [],
    2688         "single": ["foo"],
    2689         "multiple": ["bar", "baz", "quux"]}
     2695        "single": [b"foo"],
     2696        "multiple": [b"bar", b"baz", b"quux"]}
    26902697
    26912698
    26922699class ListOfIntegersTests(unittest.TestCase, ListOfTestsMixin):
    class ListOfIntegersTests(unittest.TestCase, ListOfTestsMixin): 
    27002707        9999999999999999999999999999999999999999999999999999999999)
    27012708
    27022709    strings = {
    2703         "empty": "",
    2704         "single": "\x00\x0210",
    2705         "multiple": "\x00\x011\x00\x0220\x00\x03500",
    2706         "huge": "\x00\x74%d" % (huge,),
    2707         "negative": "\x00\x02-1"}
     2710        b"empty": b"",
     2711        b"single": b"\x00\x0210",
     2712        b"multiple": b"\x00\x011\x00\x0220\x00\x03500",
     2713        b"huge": b"\x00\x74" + intToBytes(huge),
     2714        b"negative": b"\x00\x02-1"}
    27082715
    27092716    objects = {
    27102717        "empty": [],
    class ListOfUnicodeTests(unittest.TestCase, ListOfTestsMixin): 
    27222729    elementType = amp.Unicode()
    27232730
    27242731    strings = {
    2725         "empty": "",
    2726         "single": "\x00\x03foo",
    2727         "multiple": "\x00\x03\xe2\x98\x83\x00\x05Hello\x00\x05world"}
     2732        b"empty": b"",
     2733        b"single": b"\x00\x03foo",
     2734        b"multiple": b"\x00\x03\xe2\x98\x83\x00\x05Hello\x00\x05world"}
    27282735
    27292736    objects = {
    27302737        "empty": [],
    class ListOfDecimalTests(unittest.TestCase, ListOfTestsMixin): 
    27402747    elementType = amp.Decimal()
    27412748
    27422749    strings = {
    2743         "empty": "",
    2744         "single": "\x00\x031.1",
    2745         "extreme": "\x00\x08Infinity\x00\x09-Infinity",
    2746         "scientist": "\x00\x083.141E+5\x00\x0a0.00003141\x00\x083.141E-7"
    2747                      "\x00\x09-3.141E+5\x00\x0b-0.00003141\x00\x09-3.141E-7",
    2748         "engineer": "\x00\x04%s\x00\x06%s" % (
    2749             decimal.Decimal("0e6").to_eng_string(),
    2750             decimal.Decimal("1.5E-9").to_eng_string()),
     2750        b"empty": b"",
     2751        b"single": b"\x00\x031.1",
     2752        b"extreme": b"\x00\x08Infinity\x00\x09-Infinity",
     2753        b"scientist": b"\x00\x083.141E+5\x00\x0a0.00003141\x00\x083.141E-7"
     2754                      b"\x00\x09-3.141E+5\x00\x0b-0.00003141\x00\x09-3.141E-7",
     2755        b"engineer": (
     2756            b"\x00\x04" +
     2757            decimal.Decimal("0e6").to_eng_string().encode("ascii") +
     2758            b"\x00\x06" +
     2759            decimal.Decimal("1.5E-9").to_eng_string().encode("ascii")),
    27512760    }
    27522761
    27532762    objects = {
    class ListOfDecimalNanTests(unittest.TestCase, ListOfTestsMixin): 
    27842793    elementType = amp.Decimal()
    27852794
    27862795    strings = {
    2787         "nan": "\x00\x03NaN\x00\x04-NaN\x00\x04sNaN\x00\x05-sNaN",
     2796        b"nan": b"\x00\x03NaN\x00\x04-NaN\x00\x04sNaN\x00\x05-sNaN",
    27882797    }
    27892798
    27902799    objects = {
    class ListOfDateTimeTests(unittest.TestCase, ListOfTestsMixin): 
    28492858    elementType = amp.DateTime()
    28502859
    28512860    strings = {
    2852         "christmas": "\x00\x202010-12-25T00:00:00.000000-00:00"
    2853                      "\x00\x202010-12-25T00:00:00.000000-00:00",
    2854         "christmas in eu": "\x00\x202010-12-25T00:00:00.000000+01:00",
    2855         "christmas in iran": "\x00\x202010-12-25T00:00:00.000000+03:30",
    2856         "christmas in nyc": "\x00\x202010-12-25T00:00:00.000000-05:00",
    2857         "previous tests": "\x00\x202010-12-25T00:00:00.000000+03:19"
    2858                           "\x00\x202010-12-25T00:00:00.000000-06:59",
     2861        b"christmas": b"\x00\x202010-12-25T00:00:00.000000-00:00"
     2862                      b"\x00\x202010-12-25T00:00:00.000000-00:00",
     2863        b"christmas in eu": b"\x00\x202010-12-25T00:00:00.000000+01:00",
     2864        b"christmas in iran": b"\x00\x202010-12-25T00:00:00.000000+03:30",
     2865        b"christmas in nyc": b"\x00\x202010-12-25T00:00:00.000000-05:00",
     2866        b"previous tests": b"\x00\x202010-12-25T00:00:00.000000+03:19"
     2867                           b"\x00\x202010-12-25T00:00:00.000000-06:59",
    28592868    }
    28602869
    28612870    objects = {
    class ListOfOptionalTests(unittest.TestCase): 
    28922901        """
    28932902        stringList = amp.ListOf(amp.Integer())
    28942903        self.assertRaises(
    2895             TypeError, stringList.toBox, 'omitted', amp.AmpBox(),
     2904            TypeError, stringList.toBox, b'omitted', amp.AmpBox(),
    28962905            {'omitted': None}, None)
    28972906
    28982907
    class ListOfOptionalTests(unittest.TestCase): 
    29032912        """
    29042913        stringList = amp.ListOf(amp.Integer(), optional=True)
    29052914        strings = amp.AmpBox()
    2906         stringList.toBox('omitted', strings, {'omitted': None}, None)
     2915        stringList.toBox(b'omitted', strings, {b'omitted': None}, None)
    29072916        self.assertEqual(strings, {})
    29082917
    29092918
    class ListOfOptionalTests(unittest.TestCase): 
    29142923        """
    29152924        stringList = amp.ListOf(amp.Integer())
    29162925        self.assertRaises(
    2917             KeyError, stringList.toBox, 'ommited', amp.AmpBox(),
     2926            KeyError, stringList.toBox, b'ommited', amp.AmpBox(),
    29182927            {'someOtherKey': 0}, None)
    29192928
    29202929
    class ListOfOptionalTests(unittest.TestCase): 
    29242933        as optional whose key is not present in the objects dictionary.
    29252934        """
    29262935        stringList = amp.ListOf(amp.Integer(), optional=True)
    2927         stringList.toBox('ommited', amp.AmpBox(), {'someOtherKey': 0}, None)
     2936        stringList.toBox(b'ommited', amp.AmpBox(), {b'someOtherKey': 0}, None)
    29282937
    29292938
    29302939    def test_omittedOptionalArgumentDeserializesAsNone(self):
    class ListOfOptionalTests(unittest.TestCase): 
    29342943        """
    29352944        stringList = amp.ListOf(amp.Integer(), optional=True)
    29362945        objects = {}
    2937         stringList.fromBox('omitted', {}, objects, None)
     2946        stringList.fromBox(b'omitted', {}, objects, None)
    29382947        self.assertEqual(objects, {'omitted': None})
    29392948
    29402949
    29412950
     2951@implementer(interfaces.IUNIXTransport)
    29422952class UNIXStringTransport(object):
    29432953    """
    29442954    An in-memory implementation of L{interfaces.IUNIXTransport} which collects
    class UNIXStringTransport(object): 
    29482958        eg via C{write} or C{sendFileDescriptor}.  Elements are two-tuples of a
    29492959        string (identifying the destination of the data) and the data itself.
    29502960    """
    2951     implements(interfaces.IUNIXTransport)
    29522961
    29532962    def __init__(self, descriptorFuzz):
    29542963        """
    class DescriptorTests(unittest.TestCase): 
    30383047        state inspection and mutation.
    30393048        """
    30403049        argument = amp.Descriptor()
    3041         self.assertEqual("0", argument.toStringProto(2, self.protocol))
     3050        self.assertEqual(b"0", argument.toStringProto(2, self.protocol))
    30423051        self.assertEqual(
    30433052            ("fileDescriptorReceived", 2 + self.fuzz), self.transport._queue.pop(0))
    3044         self.assertEqual("1", argument.toStringProto(4, self.protocol))
     3053        self.assertEqual(b"1", argument.toStringProto(4, self.protocol))
    30453054        self.assertEqual(
    30463055            ("fileDescriptorReceived", 4 + self.fuzz), self.transport._queue.pop(0))
    3047         self.assertEqual("2", argument.toStringProto(6, self.protocol))
     3056        self.assertEqual(b"2", argument.toStringProto(6, self.protocol))
    30483057        self.assertEqual(
    30493058            ("fileDescriptorReceived", 6 + self.fuzz), self.transport._queue.pop(0))
    30503059        self.assertEqual({}, self.protocol._descriptors)
    class DescriptorTests(unittest.TestCase): 
    30563065        L{amp.Descriptor.toBox} to reconstruct a file descriptor value.
    30573066        """
    30583067        name = "alpha"
     3068        name_as_bytes = name.encode("ascii")
    30593069        strings = {}
    30603070        descriptor = 17
    30613071        sendObjects = {name: descriptor}
    30623072
    30633073        argument = amp.Descriptor()
    3064         argument.toBox(name, strings, sendObjects.copy(), self.protocol)
     3074        argument.toBox(name_as_bytes, strings, sendObjects.copy(), self.protocol)
    30653075
    30663076        receiver = amp.BinaryBoxProtocol(
    30673077            amp.BoxDispatcher(amp.CommandLocator()))
    class DescriptorTests(unittest.TestCase): 
    30693079            getattr(receiver, event[0])(*event[1:])
    30703080
    30713081        receiveObjects = {}
    3072         argument.fromBox(name, strings.copy(), receiveObjects, receiver)
     3082        argument.fromBox(
     3083            name_as_bytes, strings.copy(), receiveObjects, receiver)
    30733084
    30743085        # Make sure we got the descriptor.  Adjust by fuzz to be more convincing
    30753086        # of having gone through L{IUNIXTransport.sendFileDescriptor}, not just
    class DateTimeTests(unittest.TestCase): 
    30823093    """
    30833094    Tests for L{amp.DateTime}, L{amp._FixedOffsetTZInfo}, and L{amp.utc}.
    30843095    """
    3085     string = '9876-01-23T12:34:56.054321-01:23'
     3096    string = b'9876-01-23T12:34:56.054321-01:23'
    30863097    tzinfo = tz('-', 1, 23)
    30873098    object = datetime.datetime(9876, 1, 23, 12, 34, 56, 54321, tzinfo)
    30883099
  • new file twisted/topfiles/6833.feature

    diff --git a/twisted/topfiles/6833.feature b/twisted/topfiles/6833.feature
    new file mode 100644
    index 0000000..dd2a030
    - +  
     1twisted.protocols.amp has been ported to Python 3.