diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-06-28 16:01:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-28 16:01:59 (GMT) |
commit | ec3e20a2d1edddb0558f9d32e2b367904ccdde88 (patch) | |
tree | 4cb63b0ccbaf0d9cbdb0d6257b03b6337ae2823c /Lib | |
parent | 3029035ef34c9bae0c8d965290cd9b273c8de1ea (diff) | |
download | cpython-ec3e20a2d1edddb0558f9d32e2b367904ccdde88.zip cpython-ec3e20a2d1edddb0558f9d32e2b367904ccdde88.tar.gz cpython-ec3e20a2d1edddb0558f9d32e2b367904ccdde88.tar.bz2 |
bpo-37412: Fix os.getcwd() for long path on Windows (GH-14424)
* Fix test for integer overflow.
* Add an unit test.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_os.py | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 18cd78b..2e73906 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -22,6 +22,7 @@ import stat import subprocess import sys import sysconfig +import tempfile import threading import time import unittest @@ -87,6 +88,60 @@ class MiscTests(unittest.TestCase): cwd = os.getcwd() self.assertIsInstance(cwd, str) + def test_getcwd_long_path(self): + # bpo-37412: On Linux, PATH_MAX is usually around 4096 bytes. On + # Windows, MAX_PATH is defined as 260 characters, but Windows supports + # longer path if longer paths support is enabled. Internally, the os + # module uses MAXPATHLEN which is at least 1024. + # + # Use a directory name of 200 characters to fit into Windows MAX_PATH + # limit. + # + # On Windows, the test can stop when trying to create a path longer + # than MAX_PATH if long paths support is disabled: + # see RtlAreLongPathsEnabled(). + min_len = 2000 # characters + dirlen = 200 # characters + dirname = 'python_test_dir_' + dirname = dirname + ('a' * (dirlen - len(dirname))) + + with tempfile.TemporaryDirectory() as tmpdir: + with support.change_cwd(tmpdir): + path = tmpdir + expected = path + + while True: + cwd = os.getcwd() + self.assertEqual(cwd, expected) + + need = min_len - (len(cwd) + len(os.path.sep)) + if need <= 0: + break + if len(dirname) > need and need > 0: + dirname = dirname[:need] + + path = os.path.join(path, dirname) + try: + os.mkdir(path) + # On Windows, chdir() can fail + # even if mkdir() succeeded + os.chdir(path) + except FileNotFoundError: + # On Windows, catch ERROR_PATH_NOT_FOUND (3) and + # ERROR_FILENAME_EXCED_RANGE (206) errors + # ("The filename or extension is too long") + break + except OSError as exc: + if exc.errno == errno.ENAMETOOLONG: + break + else: + raise + + expected = path + + if support.verbose: + print(f"Tested current directory length: {len(cwd)}") + def test_getcwdb(self): cwd = os.getcwdb() self.assertIsInstance(cwd, bytes) |