Index: Objects/unicodectype.c =================================================================== --- Objects/unicodectype.c (revision 71863) +++ Objects/unicodectype.c (working copy) @@ -87,7 +87,7 @@ delta = ctype->upper; if (ctype->flags & NODELTA_MASK) - return delta; + return delta ? delta : ch; if (delta >= 32768) delta -= 65536; @@ -772,7 +772,7 @@ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->upper; if (ctype->flags & NODELTA_MASK) - return delta; + return delta ? delta : ch; if (delta >= 32768) delta -= 65536; return ch + delta; @@ -786,7 +786,7 @@ const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); int delta = ctype->lower; if (ctype->flags & NODELTA_MASK) - return delta; + return delta ? delta : ch; if (delta >= 32768) delta -= 65536; return ch + delta; Index: Lib/test/test_unicodedata.py =================================================================== --- Lib/test/test_unicodedata.py (revision 71863) +++ Lib/test/test_unicodedata.py (working copy) @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'aef99984a58c8e1e5363a3175f2ff9608599a93e' + expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' def test_method_checksum(self): h = hashlib.sha1() @@ -258,7 +258,19 @@ # the upper-case mapping: as delta, or as absolute value self.assert_("a".upper()=='A') self.assert_("\u1d79".upper()=='\ua77d') + self.assert_(".".upper()=='.') + def test_bug_5828(self): + self.assertEqual("\u1d79".lower(), "\u1d79") + # Only U+0000 should have U+0000 as its upper/lower/titlecase variant + self.assertEqual( + [ + c for c in range(sys.maxunicode+1) + if chr(c).lower() == "\x00" or chr(c).upper() == "\x00" or chr(c).title() == "\x00" + ], + [0] + ) + def test_main(): test.support.run_unittest( UnicodeMiscTest,