Index: Doc/library/os.path.rst =================================================================== --- Doc/library/os.path.rst (revision 82145) +++ Doc/library/os.path.rst (working copy) @@ -201,6 +201,7 @@ Normalize the case of a pathname. On Unix and Mac OS X, this returns the path unchanged; on case-insensitive filesystems, it converts the path to lowercase. On Windows, it also converts forward slashes to backward slashes. + Raise a TypeError if the type of the path is not ``str`` or ``bytes``. .. function:: normpath(path) Index: Lib/os2emxpath.py =================================================================== --- Lib/os2emxpath.py (revision 82145) +++ Lib/os2emxpath.py (working copy) @@ -36,6 +36,9 @@ """Normalize case of pathname. Makes all characters lowercase and all altseps into seps.""" + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not '{}'".format(s.__class__.__name__)) return s.replace('\\', '/').lower() Index: Lib/posixpath.py =================================================================== --- Lib/posixpath.py (revision 82145) +++ Lib/posixpath.py (working copy) @@ -49,6 +49,9 @@ def normcase(s): """Normalize case of pathname. Has no effect under Posix""" # TODO: on Mac OS X, this should really return s.lower(). + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not '{}'".format(s.__class__.__name__)) return s Index: Lib/ntpath.py =================================================================== --- Lib/ntpath.py (revision 82145) +++ Lib/ntpath.py (working copy) @@ -78,6 +78,9 @@ """Normalize case of pathname. Makes all characters lowercase and all slashes into backslashes.""" + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not '{}'".format(s.__class__.__name__)) return s.replace(_get_altsep(s), _get_sep(s)).lower() Index: Lib/macpath.py =================================================================== --- Lib/macpath.py (revision 82145) +++ Lib/macpath.py (working copy) @@ -32,6 +32,9 @@ # Normalize the case of a pathname. Dummy in Posix, but .lower() here. def normcase(path): + if not isinstance(path, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not '{}'".format(path.__class__.__name__)) return path.lower() Index: Lib/test/test_genericpath.py =================================================================== --- Lib/test/test_genericpath.py (revision 82145) +++ Lib/test/test_genericpath.py (working copy) @@ -194,15 +194,23 @@ ] def test_normcase(self): - # Check that normcase() is idempotent + normcase = self.pathmodule.normcase + # check that normcase() is idempotent p = "FoO/./BaR" - p = self.pathmodule.normcase(p) + p = normcase(p) self.assertEqual(p, self.pathmodule.normcase(p)) p = b"FoO/./BaR" - p = self.pathmodule.normcase(p) - self.assertEqual(p, self.pathmodule.normcase(p)) + p = normcase(p) + self.assertEqual(p, normcase(p)) + self.assertEqual(normcase(''), '') + self.assertEqual(normcase(b''), b'') + + # check that normcase raises a TypeError for invalid types + for path in (None, True, 0, 2.5, [], bytearray(b''), {'o','o'}): + self.assertRaises(TypeError, normcase, path) + def test_splitdrive(self): # splitdrive for non-NT paths splitdrive = self.pathmodule.splitdrive