Ticket #6070: ticket_6070_4.diff

File ticket_6070_4.diff, 6.3 KB (added by meissenPlate, 3 years ago)

This version only tests 9 ASCII characters. See the discussion below.

  • 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..3121b3c 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    # A sampling of ASCII characters, which chr_ should accept.
     558    _ASCIIEncodedValues = [0, 1, 103, 104, 126, 127, 128, 254, 255]
     559    _ASCIICharacters = [b"\x00", b"\x01", b"g", b"h", b"~", b"\x7f", b"\x80", b"\xfe", b"\xff"]
     560    # And here is a sampling of things that chr_ should NOT accept.
     561    _negativeIntegers = [-10, -1]
     562    _integersOver255 = [256, 257, 500, 1000, 10000, 60000, 65534, 65535]
     563    _integersOver65535 = [65536, 65537, 100000]
     564    _bytestringASCIICharacters = [b"a", b"\x15"]
     565    _UnicodeCharacters = [u"b", u"\xeff", u"\xfffe", u"\xffff"]
     566    _UnicodeCharactersOver65535 = [u"\x10000", u"\x10001"]
     567    _nonIntegersNotCharacters = [2.3, dict()]
     568
     569    def test_chr_Accepts(self):
     570        """
     571        L{compat.chr_} accepts integers in [0, 255] and returns the
     572        corresponding character in an ASCII-encoded bytestring.
     573        """
     574        for (encodedValue, bytestringCharacter) in zip(
     575                self._ASCIIEncodedValues, self._ASCIICharacters):
     576            # Deliberately leak any exceptions; failing the test with ERROR.
     577            ret = chr_(encodedValue)
     578            self.assertIsInstance(ret, bytes)
     579            self.assertEqual(ret, bytestringCharacter)
     580
     581    def _assert_chr_Rejects(self, invalidInput, exceptionToRejectWith):
     582        """Convenience function. map assertRaises across invalidInput."""
     583        for x in invalidInput:
     584            self.assertRaises(exceptionToRejectWith, chr_, x)
     585
     586    def test_chr_RejectsNegativeIntegers(self):
     587        """
     588        L{compat.chr_} rejects negative integers with ValueError.
     589        """
     590        self._assert_chr_Rejects(self._negativeIntegers, ValueError)
     591
     592    def test_chr_RejectsIntegersOver255(self):
     593        """
     594        L{compat.chr_} rejects integers over 255 with ValueError.
     595        """
     596        self._assert_chr_Rejects(self._integersOver255, ValueError)
     597
     598    def test_chr_RejectsIntegersOver65535(self):
     599        """
     600        L{compat.chr_} rejects integers over 65535 with ValueError.
     601        """
     602        self._assert_chr_Rejects(self._integersOver65535, ValueError)
     603
     604    def test_chr_RejectsBytestringASCIICharacters(self):
     605        """
     606        L{compat.chr_} rejects ASCII-encoded bytestrings with TypeError.
     607        """
     608        self._assert_chr_Rejects(self._bytestringASCIICharacters, TypeError)
     609
     610    def test_chr_RejectsUnicodeCharacters(self):
     611        """
     612        L{compat.chr_} rejects Unicode strings with TypeError.
     613        """
     614        self._assert_chr_Rejects(self._UnicodeCharacters, TypeError)
     615
     616    def test_chr_RejectsUnicodeCharactersOver65535(self):
     617        """
     618        L{compat.chr_} rejects Unicode strings with codepoints over 65535 with
     619        TypeError.
     620        """
     621        self._assert_chr_Rejects(self._UnicodeCharactersOver65535, TypeError)
     622
     623    def test_chr_RejectsNonIntegersNonCharacters(self):
     624        """
     625        L{compat.chr_} rejects any other odd thing you give it, like a dict,
     626        with TypeError.
     627        """
     628        self._assert_chr_Rejects(self._nonIntegersNotCharacters, TypeError)