|
22 | 22 | import subprocess
|
23 | 23 | import sys
|
24 | 24 | import sysconfig
|
| 25 | +import tempfile |
25 | 26 | import threading
|
26 | 27 | import time
|
27 | 28 | import unittest
|
@@ -87,6 +88,60 @@ def test_getcwd(self):
|
87 | 88 | cwd = os.getcwd()
|
88 | 89 | self.assertIsInstance(cwd, str)
|
89 | 90 |
|
| 91 | + def test_getcwd_long_path(self): |
| 92 | + # bpo-37412: On Linux, PATH_MAX is usually around 4096 bytes. On |
| 93 | + # Windows, MAX_PATH is defined as 260 characters, but Windows supports |
| 94 | + # longer path if longer paths support is enabled. Internally, the os |
| 95 | + # module uses MAXPATHLEN which is at least 1024. |
| 96 | + # |
| 97 | + # Use a directory name of 200 characters to fit into Windows MAX_PATH |
| 98 | + # limit. |
| 99 | + # |
| 100 | + # On Windows, the test can stop when trying to create a path longer |
| 101 | + # than MAX_PATH if long paths support is disabled: |
| 102 | + # see RtlAreLongPathsEnabled(). |
| 103 | + min_len = 2000 # characters |
| 104 | + dirlen = 200 # characters |
| 105 | + dirname = 'python_test_dir_' |
| 106 | + dirname = dirname + ('a' * (dirlen - len(dirname))) |
| 107 | + |
| 108 | + with tempfile.TemporaryDirectory() as tmpdir: |
| 109 | + with support.change_cwd(tmpdir): |
| 110 | + path = tmpdir |
| 111 | + expected = path |
| 112 | + |
| 113 | + while True: |
| 114 | + cwd = os.getcwd() |
| 115 | + self.assertEqual(cwd, expected) |
| 116 | + |
| 117 | + need = min_len - (len(cwd) + len(os.path.sep)) |
| 118 | + if need <= 0: |
| 119 | + break |
| 120 | + if len(dirname) > need and need > 0: |
| 121 | + dirname = dirname[:need] |
| 122 | + |
| 123 | + path = os.path.join(path, dirname) |
| 124 | + try: |
| 125 | + os.mkdir(path) |
| 126 | + # On Windows, chdir() can fail |
| 127 | + # even if mkdir() succeeded |
| 128 | + os.chdir(path) |
| 129 | + except FileNotFoundError: |
| 130 | + # On Windows, catch ERROR_PATH_NOT_FOUND (3) and |
| 131 | + # ERROR_FILENAME_EXCED_RANGE (206) errors |
| 132 | + # ("The filename or extension is too long") |
| 133 | + break |
| 134 | + except OSError as exc: |
| 135 | + if exc.errno == errno.ENAMETOOLONG: |
| 136 | + break |
| 137 | + else: |
| 138 | + raise |
| 139 | + |
| 140 | + expected = path |
| 141 | + |
| 142 | + if support.verbose: |
| 143 | + print(f"Tested current directory length: {len(cwd)}") |
| 144 | + |
90 | 145 | def test_getcwdb(self):
|
91 | 146 | cwd = os.getcwdb()
|
92 | 147 | self.assertIsInstance(cwd, bytes)
|
|
0 commit comments