diff -r d444496e714a Lib/test/test_posix.py --- a/Lib/test/test_posix.py Wed Apr 01 16:53:53 2015 +0300 +++ b/Lib/test/test_posix.py Wed Apr 01 23:02:27 2015 +0300 @@ -261,6 +261,40 @@ class PosixTester(unittest.TestCase): def test_stat(self): self.assertTrue(posix.stat(test_support.TESTFN)) + @unittest.skipUnless(hasattr(posix, 'stat'), 'test needs posix.stat()') + @unittest.skipUnless(hasattr(posix, 'makedev'), 'test needs posix.makedev()') + def test_makedev(self): + st = posix.stat(test_support.TESTFN) + dev = st.st_dev + self.assertIsInstance(dev, (int, long)) + self.assertGreaterEqual(dev, 0) + + major = posix.major(dev) + self.assertIsInstance(major, (int, long)) + self.assertGreaterEqual(major, 0) + self.assertEqual(posix.major(int(dev)), major) + self.assertEqual(posix.major(long(dev)), major) + self.assertRaises(TypeError, posix.major, float(dev)) + self.assertRaises(TypeError, posix.major) + self.assertRaises((ValueError, OverflowError), posix.major, -1) + + minor = posix.minor(dev) + self.assertIsInstance(minor, (int, long)) + self.assertGreaterEqual(minor, 0) + self.assertEqual(posix.minor(int(dev)), minor) + self.assertEqual(posix.minor(long(dev)), minor) + self.assertRaises(TypeError, posix.minor, float(dev)) + self.assertRaises(TypeError, posix.minor) + self.assertRaises((ValueError, OverflowError), posix.minor, -1) + + self.assertEqual(posix.makedev(major, minor), dev) + self.assertEqual(posix.makedev(int(major), int(minor)), dev) + self.assertEqual(posix.makedev(long(major), long(minor)), dev) + self.assertRaises(TypeError, posix.makedev, float(major), minor) + self.assertRaises(TypeError, posix.makedev, major, float(minor)) + self.assertRaises(TypeError, posix.makedev, major) + self.assertRaises(TypeError, posix.makedev) + def _test_all_chown_common(self, chown_func, first_param, stat_func): """Common code for chown, fchown and lchown tests.""" def check_stat(uid, gid): diff -r d444496e714a Modules/posixmodule.c --- a/Modules/posixmodule.c Wed Apr 01 16:53:53 2015 +0300 +++ b/Modules/posixmodule.c Wed Apr 01 23:02:27 2015 +0300 @@ -478,13 +478,38 @@ OverflowUp: static int _Py_Dev_Converter(PyObject *obj, void *p) { + PyObject *index = PyNumber_Index(obj); + if (index == NULL) + return 0; + if (PyInt_Check(index)) { + long x = PyInt_AS_LONG(index); + Py_DECREF(index); + if (x == -1 && PyErr_Occurred()) + return 0; + if (x < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative number to unsigned long"); + return 0; + } + *((dev_t *)p) = (unsigned long)x; + } + else if (PyLong_Check(index)) { #ifdef HAVE_LONG_LONG - *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); + *((dev_t *)p) = PyLong_AsUnsignedLongLong(index); #else - *((dev_t *)p) = PyLong_AsUnsignedLong(obj); -#endif - if (PyErr_Occurred()) + *((dev_t *)p) = PyLong_AsUnsignedLong(index); +#endif + Py_DECREF(index); + if (PyErr_Occurred()) + return 0; + } + else { + Py_DECREF(index); + PyErr_Format(PyExc_TypeError, + "expected int/long, %s found", + Py_TYPE(obj)->tp_name); return 0; + } return 1; }