diff -r 2f0716009132 Lib/test/test_os.py --- a/Lib/test/test_os.py Tue Jul 12 18:24:25 2016 -0400 +++ b/Lib/test/test_os.py Thu Jul 14 21:10:08 2016 +0800 @@ -3132,21 +3132,18 @@ for s in 'hello', 'goodbye', 'some/path/and/file': self.assertEqual(s, self.fspath(s)) - def test_fsencode_fsdecode(self): - for p in "path/like/object", b"path/like/object": - pathlike = self.PathLike(p) - - self.assertEqual(p, self.fspath(pathlike)) - self.assertEqual(b"path/like/object", os.fsencode(pathlike)) - self.assertEqual("path/like/object", os.fsdecode(pathlike)) - def test_pathlike(self): self.assertEqual('#feelthegil', self.fspath(self.PathLike('#feelthegil'))) self.assertTrue(issubclass(self.PathLike, os.PathLike)) self.assertTrue(isinstance(self.PathLike(), os.PathLike)) - with self.assertRaises(TypeError): - self.fspath(self.PathLike(42)) + def test_fsencode_fsdecode(self): + for p in "path/like/object", b"path/like/object": + pathlike = self.PathLike(p) + + self.assertEqual(p, self.fspath(pathlike)) + self.assertEqual(b"path/like/object", os.fsencode(pathlike)) + self.assertEqual("path/like/object", os.fsdecode(pathlike)) def test_garbage_in_exception_out(self): vapor = type('blah', (), {}) @@ -3154,9 +3151,18 @@ self.assertRaises(TypeError, self.fspath, o) def test_argument_required(self): - with self.assertRaises(TypeError): - self.fspath() - + self.assertRaises(TypeError, self.fspath) + + def test_bad_pathlike(self): + # bad __fspath__ return value, not str or bytes object + self.assertRaises(TypeError, self.fspath, self.PathLike(42)) + # __fspath__ attribute that is not callable + c = type('foo', (), {}) + c.__fspath__ = 1 + self.assertRaises(TypeError, self.fspath, c()) + # __fspath__ method raises exceptions + c.__fspath__ = lambda self: self.__not_exist + self.assertRaises(AttributeError, self.fspath, c()) # Only test if the C version is provided, otherwise TestPEP519 already tested # the pure Python implementation. diff -r 2f0716009132 Modules/posixmodule.c --- a/Modules/posixmodule.c Tue Jul 12 18:24:25 2016 -0400 +++ b/Modules/posixmodule.c Thu Jul 14 21:10:08 2016 +0800 @@ -12319,6 +12319,8 @@ path_repr = PyObject_CallFunctionObjArgs(func, NULL); Py_DECREF(func); + if (NULL == path_repr) + return NULL; if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { PyErr_Format(PyExc_TypeError, "expected %.200s.__fspath__() to return str or bytes, "