Ticket #6070: ticket_6070_2.diff

File ticket_6070_2.diff, 8.1 KB (added by meissenPlate, 2 years ago)

Moved chr_ into compat and improved test. Added topfile.

  • twisted/python/compat.py

    diff --git twisted/python/compat.py twisted/python/compat.py
    index 7a56f86..cf4ffdd 100644
    integer. 
    357357""" 
    358358 
    359359 
     360 
     361if _PY3: 
     362    def chr_(i): 
     363        if isinstance(i, int): 
     364            if i > 255: 
     365                raise ValueError("chr() arg not in range(256)") 
     366            return chr(i).encode("latin1") 
     367        else: 
     368            raise TypeError("an integer is required") 
     369else: 
     370    # We need to emulate 2.x? THIS. IS. 2.X! 
     371    def chr_(i): 
     372        return chr(i) 
     373 
     374chr_.__doc__ = """ 
     375Duplicate the behavior of 2x chr in 3x. 
     376 
     377The Python 2.x built-in chr converted integers in [0, 255] to the 
     378one-character byte strings containing the character with that ASCII encoded 
     379value. 
     380 
     381The Python 3.x chr instead takes integers in the range [0, 1114111], and 
     382converts them to one-character Unicode strings containing the character 
     383with that code-point. 
     384 
     385The chr_ in this function duplicates 2.x behavior on both 2.x and 3.x. 
     386 
     387See these extracts from the Python manual for details. 
     388 
     389Python 2.x 
     390---------- 
     391chr: 
     392"Return a string of one character whose ASCII code is the integer i. For 
     393example, chr(97) returns the string 'a'. This is the inverse of ord(). The 
     394argument must be in the range [0..255], inclusive; ValueError will be raised if 
     395i is outside that range. See also unichr()." 
     396http://docs.python.org/library/functions.html#chr 
     397 
     398Python 3.x 
     399---------- 
     400chr: 
     401"Return the string representing a character whose Unicode codepoint is the 
     402integer i. For example, chr(97) returns the string 'a'. This is the inverse of 
     403ord(). The valid range for the argument is from 0 through 1,114,111 (0x10FFFF 
     404in base 16). ValueError will be raised if i is outside that range." 
     405http://docs.python.org/py3k/library/functions.html#chr 
     406""" 
     407 
     408 
     409 
    360410__all__ = [ 
    361411    "reraise", 
    362412    "execfile", 
    __all__ = [ 
    370420    "unicode", 
    371421    "iterbytes", 
    372422    "intToBytes", 
     423    "chr_" 
    373424    ] 
  • twisted/test/test_compat.py

    diff --git twisted/test/test_compat.py twisted/test/test_compat.py
    index b408153..b41c4ae 100644
    from twisted.python.compat import set, frozenset, reduce, execfile, _PY3 
    1616from twisted.python.compat import comparable, cmp, nativeString 
    1717from twisted.python.compat import unicode as unicodeCompat 
    1818from twisted.python.compat import reraise, NativeStringIO, iterbytes, intToBytes 
     19from twisted.python.compat import chr_ 
    1920from twisted.python.filepath import FilePath 
    2021 
    2122 
    class Python3BytesTests(unittest.SynchronousTestCase): 
    538539        ASCII-encoded string representation of the number. 
    539540        """ 
    540541        self.assertEqual(intToBytes(213), b"213") 
     542 
     543 
     544 
     545class chr_Tests(unittest.SynchronousTestCase): 
     546    """ 
     547    Tests for L{compat.chr_}. 
     548 
     549    L{compat.chr_} should emulate the Python 2.x built-in chr which had 
     550    these key characteristics: 
     551        -Accepted an integer in [0, 255]. 
     552        -Returned a bytestring containing the character encoded to that 
     553         integer under ASCII. 
     554        -Raised a ValueError in response to any integer outside that range. 
     555        -Raised a TypeError in response to any other input. 
     556    """ 
     557    # There are only 256 ASCII-representable characters, so let's just test 
     558    # them all. 
     559    _allASCIICharacters = [b"\x00", b"\x01", b"\x02", b"\x03", b"\x04", b"\x05", b"\x06", b"\x07", b"\x08", b"\t", b"\n", b"\x0b", b"\x0c", b"\r", b"\x0e", b"\x0f", b"\x10", b"\x11", b"\x12", b"\x13", b"\x14", b"\x15", b"\x16", b"\x17", b"\x18", b"\x19", b"\x1a", b"\x1b", b"\x1c", b"\x1d", b"\x1e", b"\x1f", b" ", b"!", b"\"", b"#", b"$", b"%", b"&", b"\'", b"(", b")", b"*", b"+", b",", b"-", b".", b"/", b"0", b"1", b"2", b"3", b"4", b"5", b"6", b"7", b"8", b"9", b":", b";", b"<", b"=", b">", b"?", b"@", b"A", b"B", b"C", b"D", b"E", b"F", b"G", b"H", b"I", b"J", b"K", b"L", b"M", b"N", b"O", b"P", b"Q", b"R", b"S", b"T", b"U", b"V", b"W", b"X", b"Y", b"Z", b"[", b"\\", b"]", b"^", b"_", b"`", b"a", b"b", b"c", b"d", b"e", b"f", b"g", b"h", b"i", b"j", b"k", b"l", b"m", b"n", b"o", b"p", b"q", b"r", b"s", b"t", b"u", b"v", b"w", b"x", b"y", b"z", b"{", b"|", b"}", b"~", b"\x7f", b"\x80", b"\x81", b"\x82", b"\x83", b"\x84", b"\x85", b"\x86", b"\x87", b"\x88", b"\x89", b"\x8a", b"\x8b", b"\x8c", b"\x8d", b"\x8e", b"\x8f", b"\x90", b"\x91", b"\x92", b"\x93", b"\x94", b"\x95", b"\x96", b"\x97", b"\x98", b"\x99", b"\x9a", b"\x9b", b"\x9c", b"\x9d", b"\x9e", b"\x9f", b"\xa0", b"\xa1", b"\xa2", b"\xa3", b"\xa4", b"\xa5", b"\xa6", b"\xa7", b"\xa8", b"\xa9", b"\xaa", b"\xab", b"\xac", b"\xad", b"\xae", b"\xaf", b"\xb0", b"\xb1", b"\xb2", b"\xb3", b"\xb4", b"\xb5", b"\xb6", b"\xb7", b"\xb8", b"\xb9", b"\xba", b"\xbb", b"\xbc", b"\xbd", b"\xbe", b"\xbf", b"\xc0", b"\xc1", b"\xc2", b"\xc3", b"\xc4", b"\xc5", b"\xc6", b"\xc7", b"\xc8", b"\xc9", b"\xca", b"\xcb", b"\xcc", b"\xcd", b"\xce", b"\xcf", b"\xd0", b"\xd1", b"\xd2", b"\xd3", b"\xd4", b"\xd5", b"\xd6", b"\xd7", b"\xd8", b"\xd9", b"\xda", b"\xdb", b"\xdc", b"\xdd", b"\xde", b"\xdf", b"\xe0", b"\xe1", b"\xe2", b"\xe3", b"\xe4", b"\xe5", b"\xe6", b"\xe7", b"\xe8", b"\xe9", b"\xea", b"\xeb", b"\xec", b"\xed", b"\xee", b"\xef", b"\xf0", b"\xf1", b"\xf2", b"\xf3", b"\xf4", b"\xf5", b"\xf6", b"\xf7", b"\xf8", b"\xf9", b"\xfa", b"\xfb", b"\xfc", b"\xfd", b"\xfe", b"\xff"] 
     560    _ASCIIEncodedValues = list(range(256)) 
     561    # And here is a sampling of things that chr_ should NOT accept. 
     562    _negativeIntegers = [-10, -1] 
     563    _integersOver255 = [256, 257, 500, 1000, 10000, 60000, 65534, 65535] 
     564    _integersOver65535 = [65536, 65537, 100000] 
     565    _bytestringASCIICharacters = [b"a", b"\x15"] 
     566    _UnicodeCharacters = [u"b", u"\xeff", u"\xfffe", u"\xffff"] 
     567    _UnicodeCharactersOver65535 = [u"\x10000", u"\x10001"] 
     568    _nonIntegersNotCharacters = [2.3, dict()] 
     569 
     570    def test_chr_Accepts(self): 
     571        """ 
     572        L{compat.chr_} accepts integers in [0, 255] and returns the 
     573        corresponding character in an ASCII-encoded bytestring. 
     574        """ 
     575        validIntegers = self._ASCIIEncodedValues 
     576        for i in validIntegers: 
     577            # Deliberately leak any exceptions; failing the test with ERROR. 
     578            ret = chr_(i) 
     579            self.assertIsInstance(ret, bytes) 
     580            self.assertEqual(ret, self._allASCIICharacters[i]) 
     581 
     582    def _assert_chr_Rejects(self, invalidInput, exceptionToRejectWith): 
     583        """Convenience function. map assertRaises across invalidInput.""" 
     584        for x in invalidInput: 
     585            self.assertRaises(exceptionToRejectWith, chr_, x) 
     586 
     587    def test_chr_RejectsNegativeIntegers(self): 
     588        """ 
     589        L{compat.chr_} rejects negative integers with ValueError. 
     590        """ 
     591        self._assert_chr_Rejects(self._negativeIntegers, ValueError) 
     592 
     593    def test_chr_RejectsIntegersOver255(self): 
     594        """ 
     595        L{compat.chr_} rejects integers over 255 with ValueError. 
     596        """ 
     597        self._assert_chr_Rejects(self._integersOver255, ValueError) 
     598 
     599    def test_chr_RejectsIntegersOver65535(self): 
     600        """ 
     601        L{compat.chr_} rejects integers over 65535 with ValueError. 
     602        """ 
     603        self._assert_chr_Rejects(self._integersOver65535, ValueError) 
     604 
     605    def test_chr_RejectsBytestringASCIICharacters(self): 
     606        """ 
     607        L{compat.chr_} rejects ASCII-encoded bytestrings with TypeError. 
     608        """ 
     609        self._assert_chr_Rejects(self._bytestringASCIICharacters, TypeError) 
     610 
     611    def test_chr_RejectsUnicodeCharacters(self): 
     612        """ 
     613        L{compat.chr_} rejects Unicode strings with TypeError. 
     614        """ 
     615        self._assert_chr_Rejects(self._UnicodeCharacters, TypeError) 
     616 
     617    def test_chr_RejectsUnicodeCharactersOver65535(self): 
     618        """ 
     619        L{compat.chr_} rejects Unicode strings with codepoints over 65535 with 
     620        TypeError. 
     621        """ 
     622        self._assert_chr_Rejects(self._UnicodeCharactersOver65535, TypeError) 
     623 
     624    def test_chr_RejectsNonIntegersNonCharacters(self): 
     625        """ 
     626        L{compat.chr_} rejects any other odd thing you give it, like a dict, 
     627        with TypeError. 
     628        """ 
     629        self._assert_chr_Rejects(self._nonIntegersNotCharacters, TypeError)