bpo-38453: Ensure ntpath.realpath correctly resolves relative paths (GH-16967)

Ensure isabs() is always True for \\?\ prefixed paths
Avoid unnecessary usage of readlink() to avoid resolving broken links incorrectly
Ensure shutil tests run in test directory
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py
index e0ec441..a84b94c 100644
--- a/Lib/test/test_ntpath.py
+++ b/Lib/test/test_ntpath.py
@@ -286,14 +286,16 @@
                                  ABSTFN + r"\missing")
             self.assertPathEqual(ntpath.realpath(r"broken\foo"),
                                  ABSTFN + r"\missing\foo")
+            # bpo-38453: We no longer recursively resolve segments of relative
+            # symlinks that the OS cannot resolve.
             self.assertPathEqual(ntpath.realpath(r"broken1"),
-                                 ABSTFN + r"\missing\bar")
+                                 ABSTFN + r"\broken\bar")
             self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
-                                 ABSTFN + r"\missing\bar\baz")
+                                 ABSTFN + r"\broken\bar\baz")
             self.assertPathEqual(ntpath.realpath("broken2"),
-                                 ABSTFN + r"\missing")
+                                 ABSTFN + r"\self\self\missing")
             self.assertPathEqual(ntpath.realpath("broken3"),
-                                 ABSTFN + r"\missing")
+                                 ABSTFN + r"\subdir\parent\subdir\parent\missing")
             self.assertPathEqual(ntpath.realpath("broken4"),
                                  ABSTFN + r"\missing")
             self.assertPathEqual(ntpath.realpath("broken5"),
@@ -304,13 +306,13 @@
             self.assertPathEqual(ntpath.realpath(rb"broken\foo"),
                                  os.fsencode(ABSTFN + r"\missing\foo"))
             self.assertPathEqual(ntpath.realpath(rb"broken1"),
-                                 os.fsencode(ABSTFN + r"\missing\bar"))
+                                 os.fsencode(ABSTFN + r"\broken\bar"))
             self.assertPathEqual(ntpath.realpath(rb"broken1\baz"),
-                                 os.fsencode(ABSTFN + r"\missing\bar\baz"))
+                                 os.fsencode(ABSTFN + r"\broken\bar\baz"))
             self.assertPathEqual(ntpath.realpath(b"broken2"),
-                                 os.fsencode(ABSTFN + r"\missing"))
+                                 os.fsencode(ABSTFN + r"\self\self\missing"))
             self.assertPathEqual(ntpath.realpath(rb"broken3"),
-                                 os.fsencode(ABSTFN + r"\missing"))
+                                 os.fsencode(ABSTFN + r"\subdir\parent\subdir\parent\missing"))
             self.assertPathEqual(ntpath.realpath(b"broken4"),
                                  os.fsencode(ABSTFN + r"\missing"))
             self.assertPathEqual(ntpath.realpath(b"broken5"),
@@ -319,8 +321,8 @@
     @support.skip_unless_symlink
     @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
     def test_realpath_symlink_loops(self):
-        # Bug #930024, return the path unchanged if we get into an infinite
-        # symlink loop.
+        # Symlink loops are non-deterministic as to which path is returned, but
+        # it will always be the fully resolved path of one member of the cycle
         ABSTFN = ntpath.abspath(support.TESTFN)
         self.addCleanup(support.unlink, ABSTFN)
         self.addCleanup(support.unlink, ABSTFN + "1")
@@ -332,8 +334,6 @@
         os.symlink(ABSTFN, ABSTFN)
         self.assertPathEqual(ntpath.realpath(ABSTFN), ABSTFN)
 
-        # cycles are non-deterministic as to which path is returned, but
-        # it will always be the fully resolved path of one member of the cycle
         os.symlink(ABSTFN + "1", ABSTFN + "2")
         os.symlink(ABSTFN + "2", ABSTFN + "1")
         expected = (ABSTFN + "1", ABSTFN + "2")
@@ -402,6 +402,34 @@
     def test_realpath_nul(self):
         tester("ntpath.realpath('NUL')", r'\\.\NUL')
 
+    @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
+    def test_realpath_cwd(self):
+        ABSTFN = ntpath.abspath(support.TESTFN)
+
+        support.unlink(ABSTFN)
+        support.rmtree(ABSTFN)
+        os.mkdir(ABSTFN)
+        self.addCleanup(support.rmtree, ABSTFN)
+
+        test_dir_long = ntpath.join(ABSTFN, "MyVeryLongDirectoryName")
+        test_dir_short = ntpath.join(ABSTFN, "MYVERY~1")
+        test_file_long = ntpath.join(test_dir_long, "file.txt")
+        test_file_short = ntpath.join(test_dir_short, "file.txt")
+
+        os.mkdir(test_dir_long)
+
+        with open(test_file_long, "wb") as f:
+            f.write(b"content")
+
+        self.assertPathEqual(test_file_long, ntpath.realpath(test_file_short))
+
+        with support.change_cwd(test_dir_long):
+            self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
+        with support.change_cwd(test_dir_long.lower()):
+            self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
+        with support.change_cwd(test_dir_short):
+            self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
+
     def test_expandvars(self):
         with support.EnvironmentVarGuard() as env:
             env.clear()
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 636e3bd..b98e7dc 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -177,7 +177,10 @@
 
         Returns the path of the directory.
         """
-        d = tempfile.mkdtemp()
+        basedir = None
+        if sys.platform == "win32":
+            basedir = os.path.realpath(os.getcwd())
+        d = tempfile.mkdtemp(dir=basedir)
         self.tempdirs.append(d)
         return d
 
@@ -1788,8 +1791,11 @@
 
     def setUp(self):
         filename = "foo"
-        self.src_dir = tempfile.mkdtemp()
-        self.dst_dir = tempfile.mkdtemp()
+        basedir = None
+        if sys.platform == "win32":
+            basedir = os.path.realpath(os.getcwd())
+        self.src_dir = tempfile.mkdtemp(dir=basedir)
+        self.dst_dir = tempfile.mkdtemp(dir=basedir)
         self.src_file = os.path.join(self.src_dir, filename)
         self.dst_file = os.path.join(self.dst_dir, filename)
         with open(self.src_file, "wb") as f: