mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
bpo-38112: compileall: Skip long path path on Windows if the path can't be created (GH-16414)
This avoids the buildbot failure on Windows: ``` FileNotFoundError: [WinError 206] The filename or extension is too long: 'd:\\temp\\tmp5r3z438t\\long\\1\\2\\3\\4\\5\\6\\7\\8\\9\\10\\11\\12\\13\\14\\15\\16\\17\\18\\19\\20\\21\\22\\23\\24\\25\\26\\27\\28\\29\\30\\31\\32\\33\\34\\35\\36\\37\\38\\39\\40\\41\\42\\43\\44\\45\\46\\47\\48\\49\\50\\51\\52\\53\\54\\55\\56\\57\\58\\59\\60\\61\\62\\63\\64\\65\\66\\67\\68\\69\\70\\71\\72\\73\\74\\75\\76\\77\\78' ``` Creates a path that's long but avoids OS restrictions. https://bugs.python.org/issue38112
This commit is contained in:
parent
a7414571a1
commit
4267c989e7
1 changed files with 51 additions and 12 deletions
|
|
@ -11,6 +11,7 @@ import tempfile
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import io
|
import io
|
||||||
|
import errno
|
||||||
|
|
||||||
from unittest import mock, skipUnless
|
from unittest import mock, skipUnless
|
||||||
try:
|
try:
|
||||||
|
|
@ -41,20 +42,57 @@ class CompileallTestsBase:
|
||||||
os.mkdir(self.subdirectory)
|
os.mkdir(self.subdirectory)
|
||||||
self.source_path3 = os.path.join(self.subdirectory, '_test3.py')
|
self.source_path3 = os.path.join(self.subdirectory, '_test3.py')
|
||||||
shutil.copyfile(self.source_path, self.source_path3)
|
shutil.copyfile(self.source_path, self.source_path3)
|
||||||
many_directories = [str(number) for number in range(1, 100)]
|
|
||||||
self.long_path = os.path.join(self.directory,
|
|
||||||
"long",
|
|
||||||
*many_directories)
|
|
||||||
os.makedirs(self.long_path)
|
|
||||||
self.source_path_long = os.path.join(self.long_path, '_test4.py')
|
|
||||||
shutil.copyfile(self.source_path, self.source_path_long)
|
|
||||||
self.bc_path_long = importlib.util.cache_from_source(
|
|
||||||
self.source_path_long
|
|
||||||
)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
shutil.rmtree(self.directory)
|
shutil.rmtree(self.directory)
|
||||||
|
|
||||||
|
def create_long_path(self):
|
||||||
|
long_path = os.path.join(self.directory, "long")
|
||||||
|
|
||||||
|
# Create a long path, 10 directories at a time.
|
||||||
|
# It will be 100 directories deep, or shorter if the OS limits it.
|
||||||
|
for i in range(10):
|
||||||
|
longer_path = os.path.join(
|
||||||
|
long_path, *(f"long_directory_{i}_{j}" for j in range(10))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if we can open __pycache__/*.pyc.
|
||||||
|
# Also, put in the source file that we want to compile
|
||||||
|
longer_source = os.path.join(longer_path, '_test_long.py')
|
||||||
|
longer_cache = importlib.util.cache_from_source(longer_source)
|
||||||
|
try:
|
||||||
|
os.makedirs(longer_path)
|
||||||
|
shutil.copyfile(self.source_path, longer_source)
|
||||||
|
os.makedirs(os.path.dirname(longer_cache))
|
||||||
|
# Make sure we can write to the cache
|
||||||
|
with open(longer_cache, 'w'):
|
||||||
|
pass
|
||||||
|
except FileNotFoundError:
|
||||||
|
# On Windows, a FileNotFoundError("The filename or extension
|
||||||
|
# is too long") is raised for long paths
|
||||||
|
if sys.platform == "win32":
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
except OSError as exc:
|
||||||
|
if exc.errno == errno.ENAMETOOLONG:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
# Remove the __pycache__
|
||||||
|
shutil.rmtree(os.path.dirname(longer_cache))
|
||||||
|
|
||||||
|
long_path = longer_path
|
||||||
|
long_source = longer_source
|
||||||
|
long_cache = longer_cache
|
||||||
|
|
||||||
|
if i < 2:
|
||||||
|
raise ValueError('Path limit is too short')
|
||||||
|
|
||||||
|
self.source_path_long = long_source
|
||||||
|
self.bc_path_long = long_cache
|
||||||
|
|
||||||
def add_bad_source_file(self):
|
def add_bad_source_file(self):
|
||||||
self.bad_source_path = os.path.join(self.directory, '_test_bad.py')
|
self.bad_source_path = os.path.join(self.directory, '_test_bad.py')
|
||||||
with open(self.bad_source_path, 'w') as file:
|
with open(self.bad_source_path, 'w') as file:
|
||||||
|
|
@ -204,13 +242,14 @@ class CompileallTestsBase:
|
||||||
compileall.compile_dir(self.directory, quiet=True, workers=5)
|
compileall.compile_dir(self.directory, quiet=True, workers=5)
|
||||||
self.assertTrue(compile_file_mock.called)
|
self.assertTrue(compile_file_mock.called)
|
||||||
|
|
||||||
def text_compile_dir_maxlevels(self):
|
def test_compile_dir_maxlevels(self):
|
||||||
# Test the actual impact of maxlevels attr
|
# Test the actual impact of maxlevels attr
|
||||||
|
self.create_long_path()
|
||||||
compileall.compile_dir(os.path.join(self.directory, "long"),
|
compileall.compile_dir(os.path.join(self.directory, "long"),
|
||||||
maxlevels=10, quiet=True)
|
maxlevels=10, quiet=True)
|
||||||
self.assertFalse(os.path.isfile(self.bc_path_long))
|
self.assertFalse(os.path.isfile(self.bc_path_long))
|
||||||
compileall.compile_dir(os.path.join(self.directory, "long"),
|
compileall.compile_dir(os.path.join(self.directory, "long"),
|
||||||
maxlevels=110, quiet=True)
|
quiet=True)
|
||||||
self.assertTrue(os.path.isfile(self.bc_path_long))
|
self.assertTrue(os.path.isfile(self.bc_path_long))
|
||||||
|
|
||||||
def test_strip_only(self):
|
def test_strip_only(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue