[Python-checkins] r84561 - in python/branches/py3k: Doc/library/os.path.rst Lib/ntpath.py Lib/test/test_ntpath.py Misc/NEWS Modules/posixmodule.c

brian.curtin python-checkins at python.org
Mon Sep 6 19:07:31 CEST 2010


Author: brian.curtin
Date: Mon Sep  6 19:07:27 2010
New Revision: 84561

Log:
Implement #7566 - os.path.sameopenfile for Windows.

This uses the GetFileInformationByHandle function to return a tuple of values
to identify a file, then ntpath.sameopenfile compares file tuples, which
is exposed as os.path.sameopenfile.



Modified:
   python/branches/py3k/Doc/library/os.path.rst
   python/branches/py3k/Lib/ntpath.py
   python/branches/py3k/Lib/test/test_ntpath.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/posixmodule.c

Modified: python/branches/py3k/Doc/library/os.path.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.path.rst	(original)
+++ python/branches/py3k/Doc/library/os.path.rst	Mon Sep  6 19:07:27 2010
@@ -251,7 +251,9 @@
 
    Return ``True`` if the file descriptors *fp1* and *fp2* refer to the same file.
 
-   Availability: Unix.
+   Availability: Unix, Windows.
+
+   .. versionchanged:: 3.2 Added Windows support.
 
 
 .. function:: samestat(stat1, stat2)

Modified: python/branches/py3k/Lib/ntpath.py
==============================================================================
--- python/branches/py3k/Lib/ntpath.py	(original)
+++ python/branches/py3k/Lib/ntpath.py	Mon Sep  6 19:07:27 2010
@@ -10,6 +10,7 @@
 import stat
 import genericpath
 from genericpath import *
+from nt import _getfileinformation
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
            "basename","dirname","commonprefix","getsize","getmtime",
@@ -17,7 +18,7 @@
            "ismount", "expanduser","expandvars","normpath","abspath",
            "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
            "extsep","devnull","realpath","supports_unicode_filenames","relpath",
-           "samefile",]
+           "samefile", "sameopenfile",]
 
 # strings representing various path-related bits and pieces
 # These are primarily for export; internally, they are hardcoded.
@@ -652,3 +653,7 @@
         # Also, on other operating systems, fake this method with a
         #  Windows-XP approximation.
         return abspath(f1) == abspath(f2)
+
+def sameopenfile(f1, f2):
+    """Test whether two file objects reference the same file"""
+    return _getfileinformation(f1) == _getfileinformation(f2)

Modified: python/branches/py3k/Lib/test/test_ntpath.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ntpath.py	(original)
+++ python/branches/py3k/Lib/test/test_ntpath.py	Mon Sep  6 19:07:27 2010
@@ -2,6 +2,7 @@
 import os
 from test.support import TestFailed
 from test import support, test_genericpath
+from tempfile import TemporaryFile
 import unittest
 
 
@@ -237,6 +238,18 @@
         tester('ntpath.relpath("/a", "/a")', '.')
         tester('ntpath.relpath("/a/b", "/a/b")', '.')
 
+    def test_sameopenfile(self):
+        with TemporaryFile() as tf1, TemporaryFile() as tf2:
+            # Make sure the same file is really the same
+            self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
+            # Make sure different files are really different
+            self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
+            # Make sure invalid values don't cause issues
+            with self.assertRaises(ValueError):
+                # Invalid file descriptors shouldn't display assert
+                # dialogs (#4804)
+                ntpath.sameopenfile(-1, -1)
+
 
 class NtCommonTest(test_genericpath.CommonTest):
     pathmodule = ntpath

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Sep  6 19:07:27 2010
@@ -13,6 +13,8 @@
 Library
 -------
 
+- Issue #7566: Implement os.path.sameopenfile for Windows.
+
 - Issue #9293: I/O streams now raise ``io.UnsupportedOperation`` when an
   unsupported operation is attempted (for example, writing to a file open
   only for reading).

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Mon Sep  6 19:07:27 2010
@@ -2758,6 +2758,33 @@
     return result;
 
 } /* end of posix__getfinalpathname */
+
+static PyObject *
+posix__getfileinformation(PyObject *self, PyObject *args)
+{
+    HANDLE hFile;
+    BY_HANDLE_FILE_INFORMATION info;
+    int fd;
+
+    if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
+        return NULL;
+
+    if (!_PyVerify_fd(fd)) {
+        PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
+        return NULL;
+    }
+
+    hFile = (HANDLE)_get_osfhandle(fd);
+    if (hFile == INVALID_HANDLE_VALUE)
+        return win32_error("_getfileinformation", NULL);
+
+    if (!GetFileInformationByHandle(hFile, &info))
+        return win32_error("_getfileinformation", NULL);
+
+    return Py_BuildValue("iii", info.dwVolumeSerialNumber,
+                                info.nFileIndexHigh,
+                                info.nFileIndexLow);
+}
 #endif /* MS_WINDOWS */
 
 PyDoc_STRVAR(posix_mkdir__doc__,
@@ -7908,6 +7935,7 @@
 #ifdef MS_WINDOWS
     {"_getfullpathname",        posix__getfullpathname, METH_VARARGS, NULL},
     {"_getfinalpathname",       posix__getfinalpathname, METH_VARARGS, NULL},
+    {"_getfileinformation",     posix__getfileinformation, METH_VARARGS, NULL},
 #endif
 #ifdef HAVE_GETLOADAVG
     {"getloadavg",      posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},


More information about the Python-checkins mailing list