Skip to content

Commit

Permalink
bpo-37697: Sync with importlib_metadata 0.19 (python#14993)
Browse files Browse the repository at this point in the history
* bpo-37697: Sync with importlib_metadata 0.19

* Run make regen-importlib

* πŸ“œπŸ€– Added by blurb_it.
  • Loading branch information
jaraco authored Jul 28, 2019
1 parent b222955 commit 049460d
Show file tree
Hide file tree
Showing 7 changed files with 841 additions and 794 deletions.
29 changes: 19 additions & 10 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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 _matches_info(cls, normalized, item):
import re
template = r'{pattern}(-.*)?\.(dist|egg)-info'
manifest = template.format(pattern=normalized)
return re.match(manifest, item.name, flags=re.IGNORECASE)

@classmethod
def _predicate(cls, pattern, root, item):
def _matches_legacy(cls, normalized, item):
import re
return re.match(pattern, str(item.name), flags=re.IGNORECASE)
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:
Expand Down
2 changes: 1 addition & 1 deletion Lib/importlib/metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_importlib/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class DistInfoPkg(OnSysPath, SiteDir):
"entry_points.txt": """
[entries]
main = mod:main
ns:sub = mod:main
"""
},
"mod.py": """
Expand Down
19 changes: 16 additions & 3 deletions Lib/test/test_importlib/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand All @@ -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',
Expand Down Expand Up @@ -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')
8 changes: 7 additions & 1 deletion Lib/test/test_importlib/test_zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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']
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Loading

0 comments on commit 049460d

Please sign in to comment.