| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5fe1df1 commit 161541a
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -77,7 +77,9 @@ Entry points | |||
| 77 | 77 | The ``entry_points()`` function returns a dictionary of all entry points, | |
| 78 | 78 | keyed by group. Entry points are represented by ``EntryPoint`` instances; | |
| 79 | 79 | each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and | |
| 80 | - a ``.load()`` method to resolve the value. | ||
| 80 | + a ``.load()`` method to resolve the value. There are also ``.module``, | ||
| 81 | + ``.attr``, and ``.extras`` attributes for getting the components of the | ||
| 82 | + ``.value`` attribute:: | ||
| 81 | 83 | ||
| 82 | 84 | >>> eps = entry_points() # doctest: +SKIP | |
| 83 | 85 | >>> list(eps) # doctest: +SKIP | |
@@ -86,6 +88,12 @@ a ``.load()`` method to resolve the value. | |||
| 86 | 88 | >>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0] # doctest: +SKIP | |
| 87 | 89 | >>> wheel # doctest: +SKIP | |
| 88 | 90 | EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts') | |
| 91 | + >>> wheel.module # doctest: +SKIP | ||
| 92 | + 'wheel.cli' | ||
| 93 | + >>> wheel.attr # doctest: +SKIP | ||
| 94 | + 'main' | ||
| 95 | + >>> wheel.extras # doctest: +SKIP | ||
| 96 | + [] | ||
| 89 | 97 | >>> main = wheel.load() # doctest: +SKIP | |
| 90 | 98 | >>> main # doctest: +SKIP | |
| 91 | 99 | <function main at 0x103528488> | |
@@ -94,7 +102,7 @@ The ``group`` and ``name`` are arbitrary values defined by the package author | |||
| 94 | 102 | and usually a client will wish to resolve all entry points for a particular | |
| 95 | 103 | group. Read `the setuptools docs | |
| 96 | 104 | <https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins>`_ | |
| 97 | - for more information on entrypoints, their definition, and usage. | ||
| 105 | + for more information on entry points, their definition, and usage. | ||
| 98 | 106 | ||
| 99 | 107 | ||
| 100 | 108 | .. _metadata: | |
@@ -235,7 +243,7 @@ method:: | |||
| 235 | 243 | """ | |
| 236 | 244 | ||
| 237 | 245 | The ``DistributionFinder.Context`` object provides ``.path`` and ``.name`` | |
| 238 | - properties indicating the path to search and names to match and may | ||
| 246 | + properties indicating the path to search and name to match and may | ||
| 239 | 247 | supply other relevant context. | |
| 240 | 248 | ||
| 241 | 249 | What this means in practice is that to support finding distribution package | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -78,6 +78,16 @@ def load(self): | |||
| 78 | 78 | attrs = filter(None, (match.group('attr') or '').split('.')) | |
| 79 | 79 | return functools.reduce(getattr, attrs, module) | |
| 80 | 80 | ||
| 81 | + @property | ||
| 82 | + def module(self): | ||
| 83 | + match = self.pattern.match(self.value) | ||
| 84 | + return match.group('module') | ||
| 85 | + | ||
| 86 | + @property | ||
| 87 | + def attr(self): | ||
| 88 | + match = self.pattern.match(self.value) | ||
| 89 | + return match.group('attr') | ||
| 90 | + | ||
| 81 | 91 | @property | |
| 82 | 92 | def extras(self): | |
| 83 | 93 | match = self.pattern.match(self.value) | |
@@ -170,7 +180,7 @@ def from_name(cls, name): | |||
| 170 | 180 | """ | |
| 171 | 181 | for resolver in cls._discover_resolvers(): | |
| 172 | 182 | dists = resolver(DistributionFinder.Context(name=name)) | |
| 173 | - dist = next(dists, None) | ||
| 183 | + dist = next(iter(dists), None) | ||
| 174 | 184 | if dist is not None: | |
| 175 | 185 | return dist | |
| 176 | 186 | else: | |
@@ -213,6 +223,17 @@ def _discover_resolvers(): | |||
| 213 | 223 | ) | |
| 214 | 224 | return filter(None, declared) | |
| 215 | 225 | ||
| 226 | + @classmethod | ||
| 227 | + def _local(cls, root='.'): | ||
| 228 | + from pep517 import build, meta | ||
| 229 | + system = build.compat_system(root) | ||
| 230 | + builder = functools.partial( | ||
| 231 | + meta.build, | ||
| 232 | + source_dir=root, | ||
| 233 | + system=system, | ||
| 234 | + ) | ||
| 235 | + return PathDistribution(zipfile.Path(meta.build_as_zip(builder))) | ||
| 236 | + | ||
| 216 | 237 | @property | |
| 217 | 238 | def metadata(self): | |
| 218 | 239 | """Return the parsed metadata for this Distribution. | |
@@ -391,7 +412,7 @@ class FastPath: | |||
| 391 | 412 | ||
| 392 | 413 | def __init__(self, root): | |
| 393 | 414 | self.root = root | |
| 394 | - self.base = os.path.basename(root).lower() | ||
| 415 | + self.base = os.path.basename(self.root).lower() | ||
| 395 | 416 | ||
| 396 | 417 | def joinpath(self, child): | |
| 397 | 418 | return pathlib.Path(self.root, child) | |
@@ -408,8 +429,8 @@ def zip_children(self): | |||
| 408 | 429 | names = zip_path.root.namelist() | |
| 409 | 430 | self.joinpath = zip_path.joinpath | |
| 410 | 431 | ||
| 411 | - return ( | ||
| 412 | - posixpath.split(child)[0] | ||
| 432 | + return dict.fromkeys( | ||
| 433 | + child.split(posixpath.sep, 1)[0] | ||
| 413 | 434 | for child in names | |
| 414 | 435 | ) | |
| 415 | 436 | ||
@@ -475,7 +496,6 @@ def _search_paths(cls, name, paths): | |||
| 475 | 496 | ) | |
| 476 | 497 | ||
| 477 | 498 | ||
| 478 | - | ||
| 479 | 499 | class PathDistribution(Distribution): | |
| 480 | 500 | def __init__(self, path): | |
| 481 | 501 | """Construct a distribution from a path to the metadata directory. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -161,6 +161,21 @@ def setUp(self): | |||
| 161 | 161 | build_files(EggInfoFile.files, prefix=self.site_dir) | |
| 162 | 162 | ||
| 163 | 163 | ||
| 164 | + class LocalPackage: | ||
| 165 | + files = { | ||
| 166 | + "setup.py": """ | ||
| 167 | + import setuptools | ||
| 168 | + setuptools.setup(name="local-pkg", version="2.0.1") | ||
| 169 | + """, | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + def setUp(self): | ||
| 173 | + self.fixtures = contextlib.ExitStack() | ||
| 174 | + self.addCleanup(self.fixtures.close) | ||
| 175 | + self.fixtures.enter_context(tempdir_as_cwd()) | ||
| 176 | + build_files(self.files) | ||
| 177 | + | ||
| 178 | + | ||
| 164 | 179 | def build_files(file_defs, prefix=pathlib.Path()): | |
| 165 | 180 | """Build a set of files/directories, as described by the | |
| 166 | 181 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -246,3 +246,19 @@ def test_json_dump(self): | |||
| 246 | 246 | """ | |
| 247 | 247 | with self.assertRaises(Exception): | |
| 248 | 248 | json.dumps(self.ep) | |
| 249 | + | ||
| 250 | + def test_module(self): | ||
| 251 | + assert self.ep.module == 'value' | ||
| 252 | + | ||
| 253 | + def test_attr(self): | ||
| 254 | + assert self.ep.attr is None | ||
| 255 | + | ||
| 256 | + | ||
| 257 | + class FileSystem(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): | ||
| 258 | + def test_unicode_dir_on_sys_path(self): | ||
| 259 | + """ | ||
| 260 | + Ensure a Unicode subdirectory of a directory on sys.path | ||
| 261 | + does not crash. | ||
| 262 | + """ | ||
| 263 | + fixtures.build_files({'☃': {}}, prefix=self.site_dir) | ||
| 264 | + list(distributions()) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,9 +3,10 @@ | |||
| 3 | 3 | ||
| 4 | 4 | from contextlib import ExitStack | |
| 5 | 5 | from importlib.metadata import ( | |
| 6 | - distribution, entry_points, files, PackageNotFoundError, version, | ||
| 6 | + distribution, entry_points, files, PackageNotFoundError, | ||
| 7 | + version, distributions, | ||
| 7 | 8 | ) | |
| 8 | - from importlib.resources import path | ||
| 9 | + from importlib import resources | ||
| 9 | 10 | ||
| 10 | 11 | from test.support import requires_zlib | |
| 11 | 12 | ||
@@ -14,15 +15,19 @@ | |||
| 14 | 15 | class TestZip(unittest.TestCase): | |
| 15 | 16 | root = 'test.test_importlib.data' | |
| 16 | 17 | ||
| 18 | + def _fixture_on_path(self, filename): | ||
| 19 | + pkg_file = resources.files(self.root).joinpath(filename) | ||
| 20 | + file = self.resources.enter_context(resources.as_file(pkg_file)) | ||
| 21 | + assert file.name.startswith('example-'), file.name | ||
| 22 | + sys.path.insert(0, str(file)) | ||
| 23 | + self.resources.callback(sys.path.pop, 0) | ||
| 24 | + | ||
| 17 | 25 | def setUp(self): | |
| 18 | 26 | # Find the path to the example-*.whl so we can add it to the front of | |
| 19 | 27 | # sys.path, where we'll then try to find the metadata thereof. | |
| 20 | 28 | self.resources = ExitStack() | |
| 21 | 29 | self.addCleanup(self.resources.close) | |
| 22 | - wheel = self.resources.enter_context( | ||
| 23 | - path(self.root, 'example-21.12-py3-none-any.whl')) | ||
| 24 | - sys.path.insert(0, str(wheel)) | ||
| 25 | - self.resources.callback(sys.path.pop, 0) | ||
| 30 | + self._fixture_on_path('example-21.12-py3-none-any.whl') | ||
| 26 | 31 | ||
| 27 | 32 | def test_zip_version(self): | |
| 28 | 33 | self.assertEqual(version('example'), '21.12') | |
@@ -49,6 +54,10 @@ def test_files(self): | |||
| 49 | 54 | path = str(file.dist.locate_file(file)) | |
| 50 | 55 | assert '.whl/' in path, path | |
| 51 | 56 | ||
| 57 | + def test_one_distribution(self): | ||
| 58 | + dists = list(distributions(path=sys.path[:1])) | ||
| 59 | + assert len(dists) == 1 | ||
| 60 | + | ||
| 52 | 61 | ||
| 53 | 62 | @requires_zlib() | |
| 54 | 63 | class TestEgg(TestZip): | |
@@ -57,10 +66,7 @@ def setUp(self): | |||
| 57 | 66 | # sys.path, where we'll then try to find the metadata thereof. | |
| 58 | 67 | self.resources = ExitStack() | |
| 59 | 68 | self.addCleanup(self.resources.close) | |
| 60 | - egg = self.resources.enter_context( | ||
| 61 | - path(self.root, 'example-21.12-py3.6.egg')) | ||
| 62 | - sys.path.insert(0, str(egg)) | ||
| 63 | - self.resources.callback(sys.path.pop, 0) | ||
| 69 | + self._fixture_on_path('example-21.12-py3.6.egg') | ||
| 64 | 70 | ||
| 65 | 71 | def test_files(self): | |
| 66 | 72 | for file in files('example'): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Refresh importlib.metadata from importlib_metadata 1.6.1. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments