diff -r da2c96cf2ce6 Lib/test/test_os.py --- a/Lib/test/test_os.py Sun Sep 25 20:39:29 2016 +0300 +++ b/Lib/test/test_os.py Sun Sep 25 14:31:53 2016 -0400 @@ -2095,9 +2095,13 @@ self.assertTrue(os.path.exists(self.junction)) self.assertTrue(os.path.isdir(self.junction)) - # Junctions are not recognized as links. - self.assertFalse(os.path.islink(self.junction)) - + # Junctions are recognized as links. + self.assertTrue(os.path.islink(self.junction)) + + # os.readlink supports junctions. + real_junction_target = os.readlink(self.junction) + self.assertTrue(os.path.samefile(real_junction_target, self.junction_target)) + def test_unlink_removes_junction(self): _winapi.CreateJunction(self.junction_target, self.junction) self.assertTrue(os.path.exists(self.junction)) diff -r da2c96cf2ce6 Modules/posixmodule.c --- a/Modules/posixmodule.c Sun Sep 25 20:39:29 2016 +0300 +++ b/Modules/posixmodule.c Sun Sep 25 14:31:53 2016 -0400 @@ -6997,6 +6997,7 @@ char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; const wchar_t *print_name; + USHORT print_name_length; static char *keywords[] = {"path", "dir_fd", NULL}; @@ -7041,17 +7042,27 @@ if (io_result==0) return win32_error_object("readlink", po); - if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) - { - PyErr_SetString(PyExc_ValueError, - "not a symbolic link"); - return NULL; - } - print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset; + if(rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) + { + print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + + (rdb->SymbolicLinkReparseBuffer.PrintNameOffset / 2); + print_name_length = rdb->SymbolicLinkReparseBuffer.PrintNameLength / 2; + } + else if(rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) + { + print_name = rdb->MountPointReparseBuffer.PathBuffer + + (rdb->MountPointReparseBuffer.PrintNameOffset / 2); + print_name_length = rdb->MountPointReparseBuffer.PrintNameLength / 2; + } + else + { + PyErr_SetString(PyExc_ValueError, + "not a symbolic link"); + return NULL; + } result = PyUnicode_FromWideChar(print_name, - rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); + print_name_length); return result; } diff -r da2c96cf2ce6 Python/fileutils.c --- a/Python/fileutils.c Sun Sep 25 20:39:29 2016 +0300 +++ b/Python/fileutils.c Sun Sep 25 14:31:53 2016 -0400 @@ -584,7 +584,7 @@ FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); result->st_nlink = info->nNumberOfLinks; result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; - if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { + if (reparse_tag == IO_REPARSE_TAG_SYMLINK || reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) { /* first clear the S_IFMT bits */ result->st_mode ^= (result->st_mode & S_IFMT); /* now set the bits that make this a symlink */