@@ -103,16 +103,6 @@ def setUp(self):
103103 os .mkdir (self .subdirectory )
104104 self .source_path3 = os .path .join (self .subdirectory , '_test3.py' )
105105 shutil .copyfile (self .source_path , self .source_path3 )
106- many_directories = [str (number ) for number in range (1 , 100 )]
107- self .long_path = os .path .join (self .directory ,
108- "long" ,
109- * many_directories )
110- os .makedirs (self .long_path )
111- self .source_path_long = os .path .join (self .long_path , '_test4.py' )
112- shutil .copyfile (self .source_path , self .source_path_long )
113- self .bc_path_long = importlib .util .cache_from_source (
114- self .source_path_long
115- )
116106
117107 def tearDown (self ):
118108 shutil .rmtree (self .directory )
@@ -266,14 +256,22 @@ def test_compile_missing_multiprocessing(self, compile_file_mock):
266256 compileall .compile_dir (self .directory , quiet = True , workers = 5 )
267257 self .assertTrue (compile_file_mock .called )
268258
269- def text_compile_dir_maxlevels (self ):
270- # Test the actual impact of maxlevels attr
271- compileall .compile_dir (os .path .join (self .directory , "long" ),
272- maxlevels = 10 , quiet = True )
273- self .assertFalse (os .path .isfile (self .bc_path_long ))
274- compileall .compile_dir (os .path .join (self .directory , "long" ),
275- maxlevels = 110 , quiet = True )
276- self .assertTrue (os .path .isfile (self .bc_path_long ))
259+ def test_compile_dir_maxlevels (self ):
260+ # Test the actual impact of maxlevels parameter
261+ depth = 3
262+ path = self .directory
263+ for i in range (1 , depth + 1 ):
264+ path = os .path .join (path , "dir_{}" .format (i ))
265+ source = os .path .join (path , 'script.py' )
266+ os .mkdir (path )
267+ shutil .copyfile (self .source_path , source )
268+ pyc_filename = importlib .util .cache_from_source (source )
269+
270+ compileall .compile_dir (self .directory , quiet = True , maxlevels = depth - 1 )
271+ self .assertFalse (os .path .isfile (pyc_filename ))
272+
273+ compileall .compile_dir (self .directory , quiet = True , maxlevels = depth )
274+ self .assertTrue (os .path .isfile (pyc_filename ))
277275
278276 def test_strip_only (self ):
279277 fullpath = ["test" , "build" , "real" , "path" ]
@@ -330,6 +328,15 @@ def test_strip_and_prepend(self):
330328 str (err , encoding = sys .getdefaultencoding ())
331329 )
332330
331+ def test_strip_prepend_and_ddir (self ):
332+ fullpath = ["test" , "build" , "real" , "path" , "ddir" ]
333+ path = os .path .join (self .directory , * fullpath )
334+ os .makedirs (path )
335+ script_helper .make_script (path , "test" , "1 / 0" )
336+ with self .assertRaises (ValueError ):
337+ compileall .compile_dir (path , quiet = True , ddir = "/bar" ,
338+ stripdir = "/foo" , prependdir = "/bar" )
339+
333340 def test_multiple_optimization_levels (self ):
334341 script = script_helper .make_script (self .directory ,
335342 "test_optimization" ,
@@ -341,7 +348,7 @@ def test_multiple_optimization_levels(self):
341348 test_combinations = [[0 , 1 ], [1 , 2 ], [0 , 2 ], [0 , 1 , 2 ]]
342349
343350 for opt_combination in test_combinations :
344- compileall .compile_file (script ,
351+ compileall .compile_file (script , quiet = True ,
345352 optimize = opt_combination )
346353 for opt_level in opt_combination :
347354 self .assertTrue (os .path .isfile (bc [opt_level ]))
@@ -372,7 +379,7 @@ def test_ignore_symlink_destination(self):
372379 allowed_bc = importlib .util .cache_from_source (allowed_symlink )
373380 prohibited_bc = importlib .util .cache_from_source (prohibited_symlink )
374381
375- compileall .compile_dir (symlinks_path , quiet = False , limit_sl_dest = allowed_path )
382+ compileall .compile_dir (symlinks_path , quiet = True , limit_sl_dest = allowed_path )
376383
377384 self .assertTrue (os .path .isfile (allowed_bc ))
378385 self .assertFalse (os .path .isfile (prohibited_bc ))
@@ -642,21 +649,19 @@ def test_recursion_limit(self):
642649 self .assertCompiled (spamfn )
643650 self .assertCompiled (eggfn )
644651
645- def test_default_recursion_limit (self ):
646- many_directories = [str (number ) for number in range (1 , 100 )]
647- self .long_path = os .path .join (self .directory ,
648- "long" ,
649- * many_directories )
650- os .makedirs (self .long_path )
651- self .source_path_long = script_helper .make_script (
652- self .long_path , "deepscript" , ""
653- )
654- self .bc_path_long = importlib .util .cache_from_source (
655- self .source_path_long
656- )
657- self .assertFalse (os .path .isfile (self .bc_path_long ))
658- self .assertRunOK ('-q' , os .path .join (self .directory , "long" ))
659- self .assertTrue (os .path .isfile (self .bc_path_long ))
652+ @support .skip_unless_symlink
653+ def test_symlink_loop (self ):
654+ # Currently, compileall ignores symlinks to directories.
655+ # If that limitation is ever lifted, it should protect against
656+ # recursion in symlink loops.
657+ pkg = os .path .join (self .pkgdir , 'spam' )
658+ script_helper .make_pkg (pkg )
659+ os .symlink ('.' , os .path .join (pkg , 'evil' ))
660+ os .symlink ('.' , os .path .join (pkg , 'evil2' ))
661+ self .assertRunOK ('-q' , self .pkgdir )
662+ self .assertCompiled (os .path .join (
663+ self .pkgdir , 'spam' , 'evil' , 'evil2' , '__init__.py'
664+ ))
660665
661666 def test_quiet (self ):
662667 noisy = self .assertRunOK (self .pkgdir )
0 commit comments