Ticket #6070: ticket_6070_patch_1.diff

File ticket_6070_patch_1.diff, 6.3 KB (added by Peter Stringfield, 5 years ago)

Patch that adds a chr function and unittest.

  • new file twisted/python/chr_.py

    diff --git twisted/python/chr_.py twisted/python/chr_.py
    new file mode 100644
    index 0000000..f1be195
    - +  
     1# -*- test-case-name: twisted.python.test.test_chr_ -*-
     2# Copyright (c) Twisted Matrix Laboratories.
     3# See LICENSE for details.
     5The Python 2.x built-in converted integers in [0, 255] to the one-character
     6byte strings containing the character with that ASCII encoded value.
     8In Python 3.x, the built-in chr instead takes integers in the range
     9[0, 1114111], and converts them to one-character Unicode strings containing the
     10character with that code-point.
     12The chr_ in this function duplicates 2.x behavior on both 2.x and 3.x.
     14See these extracts from the Python manual for details.
     16Python 2.x
     19"Return a string of one character whose ASCII code is the integer i. For
     20example, chr(97) returns the string 'a'. This is the inverse of ord(). The
     21argument must be in the range [0..255], inclusive; ValueError will be raised if
     22i is outside that range. See also unichr()."
     25Python 3.x
     28"Return the string representing a character whose Unicode codepoint is the
     29integer i. For example, chr(97) returns the string 'a'. This is the inverse of
     30ord(). The valid range for the argument is from 0 through 1,114,111 (0x10FFFF
     31in base 16). ValueError will be raised if i is outside that range."
     35from twisted.python import compat
     37def _2x_era_chr(i):
     38    """Duplicate the behavior of 2x chr in 3x."""
     39    if isinstance(i, int):
     40        if i > 255:
     41            raise ValueError("chr() arg not in range(256)")
     42        return chr(i).encode("latin1")
     43    else:
     44        raise TypeError("an integer is required")
     46chr_ = None
     47if compat._PY3:
     48    chr_ = _2x_era_chr
     50    # We need to emulate 2.x? THIS. IS. 2.X!
     51    chr_ = chr
     53all = [chr_]
  • new file twisted/python/test/test_chr_.py

    diff --git twisted/python/test/test_chr_.py twisted/python/test/test_chr_.py
    new file mode 100644
    index 0000000..6bc6ad0
    - +  
     1# Copyright (c) Twisted Matrix Laboratories.
     2# See LICENSE for details.
     5Tests for L{twisted.python.chr_}.
     8from __future__ import division, absolute_import
     10from twisted.trial.unittest import SynchronousTestCase as TestCase
     12from twisted.python import compat
     14from twisted.python import chr_
     17class chr_Tests(TestCase):
     18    """
     19    Tests for L{chr_.chr_}.
     20    """
     21    # There are only 256 ASCII-representable characters, so let's just test
     22    # them all.
     23    _all_ASCII_characters = [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"]
     24    _ASCII_encoded_values = list(range(256))
     25    # And here is a sampling of things that chr should NOT accept.
     26    _negative_integers = [-10, -1]
     27    _integers_over_255 = [256, 257, 500, 1000, 10000, 60000, 65534, 65535]
     28    _integers_over_65535 = [65536, 65537, 100000]
     29    _bytestring_ASCII_characters = [b"a", b"\x15"]
     30    _Unicode_characters = [u"b", u"\xeff", u"\xfffe", u"\xffff"]
     31    _Unicode_characters_over_65535 = [u"\x10000", u"\x10001"]
     32    _non_integers_non_characters = [2.3, dict()]
     34    def test_chr_(self):
     35        """
     36        L{chr_.chr_} should emulate the Python 2.x built-in chr which had these key
     37        characteristics:
     38            -Accepted an integer in [0, 255].
     39            -Returned a bytestring containing the character encoded to that
     40             integer under ASCII.
     41            -Raised a ValueError in response to any integer outside that range.
     42            -Raised a TypeError in response to any other input.
     43        """
     44        valid_integers = self._ASCII_encoded_values
     45        for i in valid_integers:
     46            try:
     47                ret = chr_.chr_(i)
     48            except Exception as e:
     49                self.fail(e)
     50            self.assertIsInstance(ret, bytes)
     51            self.assertEqual(ret, self._all_ASCII_characters[i])
     52        invalid_integers = (self._negative_integers + self._integers_over_255 +
     53            self._integers_over_65535)
     54        for x in invalid_integers:
     55            self.assertRaises(ValueError, chr_.chr_, x)
     56        invalid_input = (self._bytestring_ASCII_characters +
     57            self._Unicode_characters + self._Unicode_characters_over_65535 +
     58            self._non_integers_non_characters)
     59        for x in invalid_input:
     60            self.assertRaises(TypeError, chr_.chr_, x)