diff --git twisted/python/chr_.py twisted/python/chr_.py
new file mode 100644
index 0000000..f1be195
--- /dev/null
+++ twisted/python/chr_.py
@@ -0,0 +1,53 @@
+# -*- test-case-name: twisted.python.test.test_chr_ -*-
+# Copyright (c) Twisted Matrix Laboratories.
+# See LICENSE for details.
+"""
+The Python 2.x built-in converted integers in [0, 255] to the one-character
+byte strings containing the character with that ASCII encoded value.
+
+In Python 3.x, the built-in chr instead takes integers in the range 
+[0, 1114111], and converts them to one-character Unicode strings containing the
+character with that code-point.
+
+The chr_ in this function duplicates 2.x behavior on both 2.x and 3.x.
+
+See these extracts from the Python manual for details.
+
+Python 2.x
+----------
+chr:
+"Return a string of one character whose ASCII code is the integer i. For
+example, chr(97) returns the string 'a'. This is the inverse of ord(). The
+argument must be in the range [0..255], inclusive; ValueError will be raised if
+i is outside that range. See also unichr()."
+http://docs.python.org/library/functions.html#chr
+
+Python 3.x
+----------
+chr:
+"Return the string representing a character whose Unicode codepoint is the
+integer i. For example, chr(97) returns the string 'a'. This is the inverse of
+ord(). The valid range for the argument is from 0 through 1,114,111 (0x10FFFF
+in base 16). ValueError will be raised if i is outside that range."
+http://docs.python.org/py3k/library/functions.html#chr
+"""
+
+from twisted.python import compat 
+
+def _2x_era_chr(i):
+    """Duplicate the behavior of 2x chr in 3x."""
+    if isinstance(i, int):
+        if i > 255:
+            raise ValueError("chr() arg not in range(256)")
+        return chr(i).encode("latin1")
+    else:
+        raise TypeError("an integer is required")
+
+chr_ = None
+if compat._PY3:
+    chr_ = _2x_era_chr
+else:
+    # We need to emulate 2.x? THIS. IS. 2.X!
+    chr_ = chr
+
+all = [chr_] 
diff --git twisted/python/test/test_chr_.py twisted/python/test/test_chr_.py
new file mode 100644
index 0000000..6bc6ad0
--- /dev/null
+++ twisted/python/test/test_chr_.py
@@ -0,0 +1,60 @@
+# Copyright (c) Twisted Matrix Laboratories.
+# See LICENSE for details.
+
+"""
+Tests for L{twisted.python.chr_}.
+"""
+
+from __future__ import division, absolute_import
+
+from twisted.trial.unittest import SynchronousTestCase as TestCase
+
+from twisted.python import compat
+
+from twisted.python import chr_
+
+
+class chr_Tests(TestCase):
+    """
+    Tests for L{chr_.chr_}.
+    """
+    # There are only 256 ASCII-representable characters, so let's just test
+    # them all.
+    _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"]
+    _ASCII_encoded_values = list(range(256))
+    # And here is a sampling of things that chr should NOT accept.
+    _negative_integers = [-10, -1]
+    _integers_over_255 = [256, 257, 500, 1000, 10000, 60000, 65534, 65535]
+    _integers_over_65535 = [65536, 65537, 100000]
+    _bytestring_ASCII_characters = [b"a", b"\x15"]
+    _Unicode_characters = [u"b", u"\xeff", u"\xfffe", u"\xffff"]
+    _Unicode_characters_over_65535 = [u"\x10000", u"\x10001"]
+    _non_integers_non_characters = [2.3, dict()]
+
+    def test_chr_(self):
+        """
+        L{chr_.chr_} should emulate the Python 2.x built-in chr which had these key 
+        characteristics:
+            -Accepted an integer in [0, 255].
+            -Returned a bytestring containing the character encoded to that 
+             integer under ASCII.
+            -Raised a ValueError in response to any integer outside that range.
+            -Raised a TypeError in response to any other input.
+        """
+        valid_integers = self._ASCII_encoded_values
+        for i in valid_integers:
+            try:
+                ret = chr_.chr_(i)
+            except Exception as e:
+                self.fail(e)
+            self.assertIsInstance(ret, bytes)
+            self.assertEqual(ret, self._all_ASCII_characters[i])
+        invalid_integers = (self._negative_integers + self._integers_over_255 +
+            self._integers_over_65535)
+        for x in invalid_integers:
+            self.assertRaises(ValueError, chr_.chr_, x)
+        invalid_input = (self._bytestring_ASCII_characters + 
+            self._Unicode_characters + self._Unicode_characters_over_65535 +
+            self._non_integers_non_characters)
+        for x in invalid_input:
+            self.assertRaises(TypeError, chr_.chr_, x)
