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.
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index ee7ac67..eae3cf3 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -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)
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index 86e3eda..9f39aba 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -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