mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +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 None | ||||||
|         return spec.loader |         return spec.loader | ||||||
| 
 | 
 | ||||||
|     search_template = r'(?:{pattern}(-.*)?\.(dist|egg)-info|EGG-INFO)' |  | ||||||
| 
 |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def find_distributions(cls, name=None, path=None): |     def find_distributions(cls, name=None, path=None): | ||||||
|         """ |         """ | ||||||
|  | @ -1400,24 +1398,35 @@ def _search_paths(cls, pattern, paths): | ||||||
|     def _switch_path(path): |     def _switch_path(path): | ||||||
|         from contextlib import suppress |         from contextlib import suppress | ||||||
|         import zipfile |         import zipfile | ||||||
|         from pathlib import Path |         import pathlib | ||||||
|  |         PYPY_OPEN_BUG = False | ||||||
|  |         if not PYPY_OPEN_BUG or os.path.isfile(path):  # pragma: no branch | ||||||
|             with suppress(Exception): |             with suppress(Exception): | ||||||
|                 return zipfile.Path(path) |                 return zipfile.Path(path) | ||||||
|         return Path(path) |         return pathlib.Path(path) | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def _predicate(cls, pattern, root, item): |     def _matches_info(cls, normalized, item): | ||||||
|         import re |         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 |     @classmethod | ||||||
|     def _search_path(cls, root, pattern): |     def _search_path(cls, root, pattern): | ||||||
|         if not root.is_dir(): |         if not root.is_dir(): | ||||||
|             return () |             return () | ||||||
|         normalized = pattern.replace('-', '_') |         normalized = pattern.replace('-', '_') | ||||||
|         matcher = cls.search_template.format(pattern=normalized) |  | ||||||
|         return (item for item in root.iterdir() |         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: | class FileFinder: | ||||||
|  |  | ||||||
|  | @ -88,7 +88,7 @@ def _from_config(cls, config): | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def _from_text(cls, text): |     def _from_text(cls, text): | ||||||
|         config = ConfigParser() |         config = ConfigParser(delimiters='=') | ||||||
|         # case sensitive: https://stackoverflow.com/q/1611799/812183 |         # case sensitive: https://stackoverflow.com/q/1611799/812183 | ||||||
|         config.optionxform = str |         config.optionxform = str | ||||||
|         try: |         try: | ||||||
|  |  | ||||||
|  | @ -83,6 +83,7 @@ class DistInfoPkg(OnSysPath, SiteDir): | ||||||
|             "entry_points.txt": """ |             "entry_points.txt": """ | ||||||
|                 [entries] |                 [entries] | ||||||
|                 main = mod:main |                 main = mod:main | ||||||
|  |                 ns:sub = mod:main | ||||||
|             """ |             """ | ||||||
|             }, |             }, | ||||||
|         "mod.py": """ |         "mod.py": """ | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ def test_new_style_classes(self): | ||||||
| class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): | class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): | ||||||
|     def test_import_nonexistent_module(self): |     def test_import_nonexistent_module(self): | ||||||
|         # Ensure that the MetadataPathFinder does not crash an import of a |         # Ensure that the MetadataPathFinder does not crash an import of a | ||||||
|         # nonexistent module. |         # non-existant module. | ||||||
|         with self.assertRaises(ImportError): |         with self.assertRaises(ImportError): | ||||||
|             importlib.import_module('does_not_exist') |             importlib.import_module('does_not_exist') | ||||||
| 
 | 
 | ||||||
|  | @ -41,6 +41,11 @@ def test_resolve(self): | ||||||
|         ep = entries['main'] |         ep = entries['main'] | ||||||
|         self.assertEqual(ep.load().__name__, "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): |     def test_resolve_without_attr(self): | ||||||
|         ep = EntryPoint( |         ep = EntryPoint( | ||||||
|             name='ep', |             name='ep', | ||||||
|  | @ -159,8 +164,16 @@ def test_package_discovery(self): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): | class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): | ||||||
|     def test(self): |     def test_egg_info(self): | ||||||
|         # make an `EGG-INFO` directory that's unrelated |         # make an `EGG-INFO` directory that's unrelated | ||||||
|         self.site_dir.joinpath('EGG-INFO').mkdir() |         self.site_dir.joinpath('EGG-INFO').mkdir() | ||||||
|         # used to crash with `IsADirectoryError` |         # 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 | import unittest | ||||||
| 
 | 
 | ||||||
| from contextlib import ExitStack | 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 | from importlib.resources import path | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -22,6 +24,10 @@ def setUp(self): | ||||||
|     def test_zip_version(self): |     def test_zip_version(self): | ||||||
|         self.assertEqual(version('example'), '21.12') |         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): |     def test_zip_entry_points(self): | ||||||
|         scripts = dict(entry_points()['console_scripts']) |         scripts = dict(entry_points()['console_scripts']) | ||||||
|         entry_point = scripts['example'] |         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