mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	bpo-37697: Sync with importlib_metadata 0.19 (#14993)
* bpo-37697: Sync with importlib_metadata 0.19 * Run make regen-importlib * 📜🤖 Added by blurb_it.
This commit is contained in:
		
							parent
							
								
									b222955355
								
							
						
					
					
						commit
						049460da9c
					
				
					 7 changed files with 841 additions and 794 deletions
				
			
		|  | @ -1367,8 +1367,6 @@ def find_module(cls, fullname, path=None): | |||
|             return None | ||||
|         return spec.loader | ||||
| 
 | ||||
|     search_template = r'(?:{pattern}(-.*)?\.(dist|egg)-info|EGG-INFO)' | ||||
| 
 | ||||
|     @classmethod | ||||
|     def find_distributions(cls, name=None, path=None): | ||||
|         """ | ||||
|  | @ -1400,24 +1398,35 @@ def _search_paths(cls, pattern, paths): | |||
|     def _switch_path(path): | ||||
|         from contextlib import suppress | ||||
|         import zipfile | ||||
|         from pathlib import Path | ||||
|         with suppress(Exception): | ||||
|             return zipfile.Path(path) | ||||
|         return Path(path) | ||||
|         import pathlib | ||||
|         PYPY_OPEN_BUG = False | ||||
|         if not PYPY_OPEN_BUG or os.path.isfile(path):  # pragma: no branch | ||||
|             with suppress(Exception): | ||||
|                 return zipfile.Path(path) | ||||
|         return pathlib.Path(path) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _predicate(cls, pattern, root, item): | ||||
|     def _matches_info(cls, normalized, item): | ||||
|         import re | ||||
|         return re.match(pattern, str(item.name), flags=re.IGNORECASE) | ||||
|         template = r'{pattern}(-.*)?\.(dist|egg)-info' | ||||
|         manifest = template.format(pattern=normalized) | ||||
|         return re.match(manifest, item.name, flags=re.IGNORECASE) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _matches_legacy(cls, normalized, item): | ||||
|         import re | ||||
|         template = r'{pattern}-.*\.egg[\\/]EGG-INFO' | ||||
|         manifest = template.format(pattern=normalized) | ||||
|         return re.search(manifest, str(item), flags=re.IGNORECASE) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def _search_path(cls, root, pattern): | ||||
|         if not root.is_dir(): | ||||
|             return () | ||||
|         normalized = pattern.replace('-', '_') | ||||
|         matcher = cls.search_template.format(pattern=normalized) | ||||
|         return (item for item in root.iterdir() | ||||
|                 if cls._predicate(matcher, root, item)) | ||||
|                 if cls._matches_info(normalized, item) | ||||
|                 or cls._matches_legacy(normalized, item)) | ||||
| 
 | ||||
| 
 | ||||
| class FileFinder: | ||||
|  |  | |||
|  | @ -88,7 +88,7 @@ def _from_config(cls, config): | |||
| 
 | ||||
|     @classmethod | ||||
|     def _from_text(cls, text): | ||||
|         config = ConfigParser() | ||||
|         config = ConfigParser(delimiters='=') | ||||
|         # case sensitive: https://stackoverflow.com/q/1611799/812183 | ||||
|         config.optionxform = str | ||||
|         try: | ||||
|  |  | |||
|  | @ -83,6 +83,7 @@ class DistInfoPkg(OnSysPath, SiteDir): | |||
|             "entry_points.txt": """ | ||||
|                 [entries] | ||||
|                 main = mod:main | ||||
|                 ns:sub = mod:main | ||||
|             """ | ||||
|             }, | ||||
|         "mod.py": """ | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ def test_new_style_classes(self): | |||
| class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): | ||||
|     def test_import_nonexistent_module(self): | ||||
|         # Ensure that the MetadataPathFinder does not crash an import of a | ||||
|         # nonexistent module. | ||||
|         # non-existant module. | ||||
|         with self.assertRaises(ImportError): | ||||
|             importlib.import_module('does_not_exist') | ||||
| 
 | ||||
|  | @ -41,6 +41,11 @@ def test_resolve(self): | |||
|         ep = entries['main'] | ||||
|         self.assertEqual(ep.load().__name__, "main") | ||||
| 
 | ||||
|     def test_entrypoint_with_colon_in_name(self): | ||||
|         entries = dict(entry_points()['entries']) | ||||
|         ep = entries['ns:sub'] | ||||
|         self.assertEqual(ep.value, 'mod:main') | ||||
| 
 | ||||
|     def test_resolve_without_attr(self): | ||||
|         ep = EntryPoint( | ||||
|             name='ep', | ||||
|  | @ -159,8 +164,16 @@ def test_package_discovery(self): | |||
| 
 | ||||
| 
 | ||||
| class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): | ||||
|     def test(self): | ||||
|     def test_egg_info(self): | ||||
|         # make an `EGG-INFO` directory that's unrelated | ||||
|         self.site_dir.joinpath('EGG-INFO').mkdir() | ||||
|         # used to crash with `IsADirectoryError` | ||||
|         self.assertIsNone(version('unknown-package')) | ||||
|         with self.assertRaises(PackageNotFoundError): | ||||
|             version('unknown-package') | ||||
| 
 | ||||
|     def test_egg(self): | ||||
|         egg = self.site_dir.joinpath('foo-3.6.egg') | ||||
|         egg.mkdir() | ||||
|         with self.add_sys_path(egg): | ||||
|             with self.assertRaises(PackageNotFoundError): | ||||
|                 version('foo') | ||||
|  |  | |||
|  | @ -2,7 +2,9 @@ | |||
| import unittest | ||||
| 
 | ||||
| from contextlib import ExitStack | ||||
| from importlib.metadata import distribution, entry_points, files, version | ||||
| from importlib.metadata import ( | ||||
|     distribution, entry_points, files, PackageNotFoundError, version, | ||||
| ) | ||||
| from importlib.resources import path | ||||
| 
 | ||||
| 
 | ||||
|  | @ -22,6 +24,10 @@ def setUp(self): | |||
|     def test_zip_version(self): | ||||
|         self.assertEqual(version('example'), '21.12') | ||||
| 
 | ||||
|     def test_zip_version_does_not_match(self): | ||||
|         with self.assertRaises(PackageNotFoundError): | ||||
|             version('definitely-not-installed') | ||||
| 
 | ||||
|     def test_zip_entry_points(self): | ||||
|         scripts = dict(entry_points()['console_scripts']) | ||||
|         entry_point = scripts['example'] | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Syncronize ``importlib.metadata`` with `importlib_metadata 0.19 <https://gitlab.com/python-devs/importlib_metadata/-/milestones/20>`_, improving handling of EGG-INFO files and fixing a crash when entry point names contained colons. | ||||
							
								
								
									
										1575
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1575
									
								
								Python/importlib_external.h
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jason R. Coombs
						Jason R. Coombs