mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			107 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import io
 | |
| import itertools
 | |
| import math
 | |
| import re
 | |
| import string
 | |
| import unittest
 | |
| import zipfile
 | |
| 
 | |
| from ._functools import compose
 | |
| from ._itertools import consume
 | |
| 
 | |
| from ._support import import_or_skip
 | |
| 
 | |
| 
 | |
| big_o = import_or_skip('big_o')
 | |
| pytest = import_or_skip('pytest')
 | |
| 
 | |
| 
 | |
| class TestComplexity(unittest.TestCase):
 | |
|     @pytest.mark.flaky
 | |
|     def test_implied_dirs_performance(self):
 | |
|         best, others = big_o.big_o(
 | |
|             compose(consume, zipfile._path.CompleteDirs._implied_dirs),
 | |
|             lambda size: [
 | |
|                 '/'.join(string.ascii_lowercase + str(n)) for n in range(size)
 | |
|             ],
 | |
|             max_n=1000,
 | |
|             min_n=1,
 | |
|         )
 | |
|         assert best <= big_o.complexities.Linear
 | |
| 
 | |
|     def make_zip_path(self, depth=1, width=1) -> zipfile.Path:
 | |
|         """
 | |
|         Construct a Path with width files at every level of depth.
 | |
|         """
 | |
|         zf = zipfile.ZipFile(io.BytesIO(), mode='w')
 | |
|         pairs = itertools.product(self.make_deep_paths(depth), self.make_names(width))
 | |
|         for path, name in pairs:
 | |
|             zf.writestr(f"{path}{name}.txt", b'')
 | |
|         zf.filename = "big un.zip"
 | |
|         return zipfile.Path(zf)
 | |
| 
 | |
|     @classmethod
 | |
|     def make_names(cls, width, letters=string.ascii_lowercase):
 | |
|         """
 | |
|         >>> list(TestComplexity.make_names(1))
 | |
|         ['a']
 | |
|         >>> list(TestComplexity.make_names(2))
 | |
|         ['a', 'b']
 | |
|         >>> list(TestComplexity.make_names(30))
 | |
|         ['aa', 'ab', ..., 'bd']
 | |
|         >>> list(TestComplexity.make_names(17124))
 | |
|         ['aaa', 'aab', ..., 'zip']
 | |
|         """
 | |
|         # determine how many products are needed to produce width
 | |
|         n_products = max(1, math.ceil(math.log(width, len(letters))))
 | |
|         inputs = (letters,) * n_products
 | |
|         combinations = itertools.product(*inputs)
 | |
|         names = map(''.join, combinations)
 | |
|         return itertools.islice(names, width)
 | |
| 
 | |
|     @classmethod
 | |
|     def make_deep_paths(cls, depth):
 | |
|         return map(cls.make_deep_path, range(depth))
 | |
| 
 | |
|     @classmethod
 | |
|     def make_deep_path(cls, depth):
 | |
|         return ''.join(('d/',) * depth)
 | |
| 
 | |
|     def test_baseline_regex_complexity(self):
 | |
|         best, others = big_o.big_o(
 | |
|             lambda path: re.fullmatch(r'[^/]*\\.txt', path),
 | |
|             self.make_deep_path,
 | |
|             max_n=100,
 | |
|             min_n=1,
 | |
|         )
 | |
|         assert best <= big_o.complexities.Constant
 | |
| 
 | |
|     @pytest.mark.flaky
 | |
|     def test_glob_depth(self):
 | |
|         best, others = big_o.big_o(
 | |
|             lambda path: consume(path.glob('*.txt')),
 | |
|             self.make_zip_path,
 | |
|             max_n=100,
 | |
|             min_n=1,
 | |
|         )
 | |
|         assert best <= big_o.complexities.Linear
 | |
| 
 | |
|     @pytest.mark.flaky
 | |
|     def test_glob_width(self):
 | |
|         best, others = big_o.big_o(
 | |
|             lambda path: consume(path.glob('*.txt')),
 | |
|             lambda size: self.make_zip_path(width=size),
 | |
|             max_n=100,
 | |
|             min_n=1,
 | |
|         )
 | |
|         assert best <= big_o.complexities.Linear
 | |
| 
 | |
|     @pytest.mark.flaky
 | |
|     def test_glob_width_and_depth(self):
 | |
|         best, others = big_o.big_o(
 | |
|             lambda path: consume(path.glob('*.txt')),
 | |
|             lambda size: self.make_zip_path(depth=size, width=size),
 | |
|             max_n=10,
 | |
|             min_n=1,
 | |
|         )
 | |
|         assert best <= big_o.complexities.Linear
 | 
