diff options
Diffstat (limited to 'devdocs/python~3.12/library%2Fimportlib.metadata.html')
| -rw-r--r-- | devdocs/python~3.12/library%2Fimportlib.metadata.html | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/devdocs/python~3.12/library%2Fimportlib.metadata.html b/devdocs/python~3.12/library%2Fimportlib.metadata.html new file mode 100644 index 00000000..53280d81 --- /dev/null +++ b/devdocs/python~3.12/library%2Fimportlib.metadata.html @@ -0,0 +1,83 @@ + <span id="importlib-metadata-accessing-package-metadata"></span><span id="using"></span><h1>importlib.metadata – Accessing package metadata</h1> <div class="versionadded"> <p><span class="versionmodified added">New in version 3.8.</span></p> </div> <div class="versionchanged"> <p><span class="versionmodified changed">Changed in version 3.10: </span><code>importlib.metadata</code> is no longer provisional.</p> </div> <p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Lib/importlib/metadata/__init__.py">Lib/importlib/metadata/__init__.py</a></p> <p><code>importlib.metadata</code> is a library that provides access to the metadata of an installed <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a>, such as its entry points or its top-level names (<a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Import-Package">Import Package</a>s, modules, if any). Built in part on Python’s import system, this library intends to replace similar functionality in the <a class="reference external" href="https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points">entry point API</a> and <a class="reference external" href="https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api">metadata API</a> of <code>pkg_resources</code>. Along with <a class="reference internal" href="importlib.resources#module-importlib.resources" title="importlib.resources: Package resource reading, opening, and access"><code>importlib.resources</code></a>, this package can eliminate the need to use the older and less efficient <code>pkg_resources</code> package.</p> <p><code>importlib.metadata</code> operates on third-party <em>distribution packages</em> installed into Python’s <code>site-packages</code> directory via tools such as <a class="reference external" href="https://pypi.org/project/pip/">pip</a>. Specifically, it works with distributions with discoverable <code>dist-info</code> or <code>egg-info</code> directories, and metadata defined by the <a class="reference external" href="https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata">Core metadata specifications</a>.</p> <div class="admonition important"> <p class="admonition-title">Important</p> <p>These are <em>not</em> necessarily equivalent to or correspond 1:1 with the top-level <em>import package</em> names that can be imported inside Python code. One <em>distribution package</em> can contain multiple <em>import packages</em> (and single modules), and one top-level <em>import package</em> may map to multiple <em>distribution packages</em> if it is a namespace package. You can use <a class="reference internal" href="#package-distributions"><span class="std std-ref">package_distributions()</span></a> to get a mapping between them.</p> </div> <p>By default, distribution metadata can live on the file system or in zip archives on <a class="reference internal" href="sys#sys.path" title="sys.path"><code>sys.path</code></a>. Through an extension mechanism, the metadata can live almost anywhere.</p> <div class="admonition seealso"> <p class="admonition-title">See also</p> <dl class="simple"> <dt><a class="reference external" href="https://importlib-metadata.readthedocs.io/">https://importlib-metadata.readthedocs.io/</a></dt> +<dd> +<p>The documentation for <code>importlib_metadata</code>, which supplies a backport of <code>importlib.metadata</code>. This includes an <a class="reference external" href="https://importlib-metadata.readthedocs.io/en/latest/api.html">API reference</a> for this module’s classes and functions, as well as a <a class="reference external" href="https://importlib-metadata.readthedocs.io/en/latest/migration.html">migration guide</a> for existing users of <code>pkg_resources</code>.</p> </dd> </dl> </div> <section id="overview"> <h2>Overview</h2> <p>Let’s say you wanted to get the version string for a <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a> you’ve installed using <code>pip</code>. We start by creating a virtual environment and installing something into it:</p> <pre data-language="shell">$ python -m venv example +$ source example/bin/activate +(example) $ python -m pip install wheel +</pre> <p>You can get the version string for <code>wheel</code> by running the following:</p> <pre data-language="pycon">(example) $ python +>>> from importlib.metadata import version +>>> version('wheel') +'0.32.3' +</pre> <p>You can also get a collection of entry points selectable by properties of the EntryPoint (typically ‘group’ or ‘name’), such as <code>console_scripts</code>, <code>distutils.commands</code> and others. Each group contains a collection of <a class="reference internal" href="#entry-points"><span class="std std-ref">EntryPoint</span></a> objects.</p> <p>You can get the <a class="reference internal" href="#metadata"><span class="std std-ref">metadata for a distribution</span></a>:</p> <pre data-language="python">>>> list(metadata('wheel')) +['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist'] +</pre> <p>You can also get a <a class="reference internal" href="#version"><span class="std std-ref">distribution’s version number</span></a>, list its <a class="reference internal" href="#files"><span class="std std-ref">constituent files</span></a>, and get a list of the distribution’s <a class="reference internal" href="#requirements"><span class="std std-ref">Distribution requirements</span></a>.</p> </section> <section id="functional-api"> <h2>Functional API</h2> <p>This package provides the following functionality via its public API.</p> <section id="entry-points"> <span id="id2"></span><h3>Entry points</h3> <p>The <code>entry_points()</code> function returns a collection of entry points. Entry points are represented by <code>EntryPoint</code> instances; each <code>EntryPoint</code> has a <code>.name</code>, <code>.group</code>, and <code>.value</code> attributes and a <code>.load()</code> method to resolve the value. There are also <code>.module</code>, <code>.attr</code>, and <code>.extras</code> attributes for getting the components of the <code>.value</code> attribute.</p> <p>Query all entry points:</p> <pre data-language="python">>>> eps = entry_points() +</pre> <p>The <code>entry_points()</code> function returns an <code>EntryPoints</code> object, a collection of all <code>EntryPoint</code> objects with <code>names</code> and <code>groups</code> attributes for convenience:</p> <pre data-language="python">>>> sorted(eps.groups) +['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation'] +</pre> <p><code>EntryPoints</code> has a <code>select</code> method to select entry points matching specific properties. Select entry points in the <code>console_scripts</code> group:</p> <pre data-language="python">>>> scripts = eps.select(group='console_scripts') +</pre> <p>Equivalently, since <code>entry_points</code> passes keyword arguments through to select:</p> <pre data-language="python">>>> scripts = entry_points(group='console_scripts') +</pre> <p>Pick out a specific script named “wheel” (found in the wheel project):</p> <pre data-language="python">>>> 'wheel' in scripts.names +True +>>> wheel = scripts['wheel'] +</pre> <p>Equivalently, query for that entry point during selection:</p> <pre data-language="python">>>> (wheel,) = entry_points(group='console_scripts', name='wheel') +>>> (wheel,) = entry_points().select(group='console_scripts', name='wheel') +</pre> <p>Inspect the resolved entry point:</p> <pre data-language="python">>>> wheel +EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts') +>>> wheel.module +'wheel.cli' +>>> wheel.attr +'main' +>>> wheel.extras +[] +>>> main = wheel.load() +>>> main +<function main at 0x103528488> +</pre> <p>The <code>group</code> and <code>name</code> are arbitrary values defined by the package author and usually a client will wish to resolve all entry points for a particular group. Read <a class="reference external" href="https://setuptools.pypa.io/en/latest/userguide/entry_point.html">the setuptools docs</a> for more information on entry points, their definition, and usage.</p> <p><em>Compatibility Note</em></p> <p>The “selectable” entry points were introduced in <code>importlib_metadata</code> 3.6 and Python 3.10. Prior to those changes, <code>entry_points</code> accepted no parameters and always returned a dictionary of entry points, keyed by group. With <code>importlib_metadata</code> 5.0 and Python 3.12, <code>entry_points</code> always returns an <code>EntryPoints</code> object. See <a class="reference external" href="https://pypi.org/project/backports.entry-points-selectable">backports.entry_points_selectable</a> for compatibility options.</p> </section> <section id="distribution-metadata"> <span id="metadata"></span><h3>Distribution metadata</h3> <p>Every <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a> includes some metadata, which you can extract using the <code>metadata()</code> function:</p> <pre data-language="python">>>> wheel_metadata = metadata('wheel') +</pre> <p>The keys of the returned data structure, a <code>PackageMetadata</code>, name the metadata keywords, and the values are returned unparsed from the distribution metadata:</p> <pre data-language="python">>>> wheel_metadata['Requires-Python'] +'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' +</pre> <p><code>PackageMetadata</code> also presents a <code>json</code> attribute that returns all the metadata in a JSON-compatible form per <span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0566/"><strong>PEP 566</strong></a>:</p> <pre data-language="python">>>> wheel_metadata.json['requires_python'] +'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' +</pre> <div class="admonition note"> <p class="admonition-title">Note</p> <p>The actual type of the object returned by <code>metadata()</code> is an implementation detail and should be accessed only through the interface described by the <a class="reference external" href="https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata">PackageMetadata protocol</a>.</p> </div> <div class="versionchanged"> <p><span class="versionmodified changed">Changed in version 3.10: </span>The <code>Description</code> is now included in the metadata when presented through the payload. Line continuation characters have been removed.</p> </div> <div class="versionadded"> <p><span class="versionmodified added">New in version 3.10: </span>The <code>json</code> attribute was added.</p> </div> </section> <section id="distribution-versions"> <span id="version"></span><h3>Distribution versions</h3> <p>The <code>version()</code> function is the quickest way to get a <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a>’s version number, as a string:</p> <pre data-language="python">>>> version('wheel') +'0.32.3' +</pre> </section> <section id="distribution-files"> <span id="files"></span><h3>Distribution files</h3> <p>You can also get the full set of files contained within a distribution. The <code>files()</code> function takes a <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a> name and returns all of the files installed by this distribution. Each file object returned is a <code>PackagePath</code>, a <a class="reference internal" href="pathlib#pathlib.PurePath" title="pathlib.PurePath"><code>pathlib.PurePath</code></a> derived object with additional <code>dist</code>, <code>size</code>, and <code>hash</code> properties as indicated by the metadata. For example:</p> <pre data-language="python">>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] +>>> util +PackagePath('wheel/util.py') +>>> util.size +859 +>>> util.dist +<importlib.metadata._hooks.PathDistribution object at 0x101e0cef0> +>>> util.hash +<FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI> +</pre> <p>Once you have the file, you can also read its contents:</p> <pre data-language="python">>>> print(util.read_text()) +import base64 +import sys +... +def as_bytes(s): + if isinstance(s, text_type): + return s.encode('utf-8') + return s +</pre> <p>You can also use the <code>locate</code> method to get a the absolute path to the file:</p> <pre data-language="python">>>> util.locate() +PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py') +</pre> <p>In the case where the metadata file listing files (RECORD or SOURCES.txt) is missing, <code>files()</code> will return <code>None</code>. The caller may wish to wrap calls to <code>files()</code> in <a class="reference external" href="https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable">always_iterable</a> or otherwise guard against this condition if the target distribution is not known to have the metadata present.</p> </section> <section id="distribution-requirements"> <span id="requirements"></span><h3>Distribution requirements</h3> <p>To get the full set of requirements for a <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a>, use the <code>requires()</code> function:</p> <pre data-language="python">>>> requires('wheel') +["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"] +</pre> </section> <section id="mapping-import-to-distribution-packages"> <span id="import-distribution-package-mapping"></span><span id="package-distributions"></span><h3>Mapping import to distribution packages</h3> <p>A convenience method to resolve the <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a> name (or names, in the case of a namespace package) that provide each importable top-level Python module or <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Import-Package">Import Package</a>:</p> <pre data-language="python">>>> packages_distributions() +{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...} +</pre> <p>Some editable installs, <a class="reference external" href="https://github.com/pypa/packaging-problems/issues/609">do not supply top-level names</a>, and thus this function is not reliable with such installs.</p> <div class="versionadded"> <p><span class="versionmodified added">New in version 3.10.</span></p> </div> </section> </section> <section id="distributions"> <span id="id9"></span><h2>Distributions</h2> <p>While the above API is the most common and convenient usage, you can get all of that information from the <code>Distribution</code> class. A <code>Distribution</code> is an abstract object that represents the metadata for a Python <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a>. You can get the <code>Distribution</code> instance:</p> <pre data-language="python">>>> from importlib.metadata import distribution +>>> dist = distribution('wheel') +</pre> <p>Thus, an alternative way to get the version number is through the <code>Distribution</code> instance:</p> <pre data-language="python">>>> dist.version +'0.32.3' +</pre> <p>There are all kinds of additional metadata available on the <code>Distribution</code> instance:</p> <pre data-language="python">>>> dist.metadata['Requires-Python'] +'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' +>>> dist.metadata['License'] +'MIT' +</pre> <p>The full set of available metadata is not described here. See the <a class="reference external" href="https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata">Core metadata specifications</a> for additional details.</p> </section> <section id="distribution-discovery"> <h2>Distribution Discovery</h2> <p>By default, this package provides built-in support for discovery of metadata for file system and zip file <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a>s. This metadata finder search defaults to <code>sys.path</code>, but varies slightly in how it interprets those values from how other import machinery does. In particular:</p> <ul class="simple"> <li> +<code>importlib.metadata</code> does not honor <a class="reference internal" href="stdtypes#bytes" title="bytes"><code>bytes</code></a> objects on <code>sys.path</code>.</li> <li> +<code>importlib.metadata</code> will incidentally honor <a class="reference internal" href="pathlib#pathlib.Path" title="pathlib.Path"><code>pathlib.Path</code></a> objects on <code>sys.path</code> even though such values will be ignored for imports.</li> </ul> </section> <section id="extending-the-search-algorithm"> <h2>Extending the search algorithm</h2> <p>Because <a class="reference external" href="https://packaging.python.org/en/latest/glossary/#term-Distribution-Package">Distribution Package</a> metadata is not available through <a class="reference internal" href="sys#sys.path" title="sys.path"><code>sys.path</code></a> searches, or package loaders directly, the metadata for a distribution is found through import system <a class="reference internal" href="../reference/import#finders-and-loaders"><span class="std std-ref">finders</span></a>. To find a distribution package’s metadata, <code>importlib.metadata</code> queries the list of <a class="reference internal" href="../glossary#term-meta-path-finder"><span class="xref std std-term">meta path finders</span></a> on <a class="reference internal" href="sys#sys.meta_path" title="sys.meta_path"><code>sys.meta_path</code></a>.</p> <p>By default <code>importlib.metadata</code> installs a finder for distribution packages found on the file system. This finder doesn’t actually find any <em>distributions</em>, but it can find their metadata.</p> <p>The abstract class <a class="reference internal" href="importlib#importlib.abc.MetaPathFinder" title="importlib.abc.MetaPathFinder"><code>importlib.abc.MetaPathFinder</code></a> defines the interface expected of finders by Python’s import system. <code>importlib.metadata</code> extends this protocol by looking for an optional <code>find_distributions</code> callable on the finders from <a class="reference internal" href="sys#sys.meta_path" title="sys.meta_path"><code>sys.meta_path</code></a> and presents this extended interface as the <code>DistributionFinder</code> abstract base class, which defines this abstract method:</p> <pre data-language="python">@abc.abstractmethod +def find_distributions(context=DistributionFinder.Context()): + """Return an iterable of all Distribution instances capable of + loading the metadata for packages for the indicated ``context``. + """ +</pre> <p>The <code>DistributionFinder.Context</code> object provides <code>.path</code> and <code>.name</code> properties indicating the path to search and name to match and may supply other relevant context.</p> <p>What this means in practice is that to support finding distribution package metadata in locations other than the file system, subclass <code>Distribution</code> and implement the abstract methods. Then from a custom finder, return instances of this derived <code>Distribution</code> in the <code>find_distributions()</code> method.</p> </section> <div class="_attribution"> + <p class="_attribution-p"> + © 2001–2023 Python Software Foundation<br>Licensed under the PSF License.<br> + <a href="https://docs.python.org/3.12/library/importlib.metadata.html" class="_attribution-link">https://docs.python.org/3.12/library/importlib.metadata.html</a> + </p> +</div> |
