summaryrefslogtreecommitdiff
path: root/devdocs/python~3.12/library%2Fimportlib.metadata.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/python~3.12/library%2Fimportlib.metadata.html
new repository
Diffstat (limited to 'devdocs/python~3.12/library%2Fimportlib.metadata.html')
-rw-r--r--devdocs/python~3.12/library%2Fimportlib.metadata.html83
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
+&gt;&gt;&gt; from importlib.metadata import version
+&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 'wheel' in scripts.names
+True
+&gt;&gt;&gt; wheel = scripts['wheel']
+</pre> <p>Equivalently, query for that entry point during selection:</p> <pre data-language="python">&gt;&gt;&gt; (wheel,) = entry_points(group='console_scripts', name='wheel')
+&gt;&gt;&gt; (wheel,) = entry_points().select(group='console_scripts', name='wheel')
+</pre> <p>Inspect the resolved entry point:</p> <pre data-language="python">&gt;&gt;&gt; wheel
+EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')
+&gt;&gt;&gt; wheel.module
+'wheel.cli'
+&gt;&gt;&gt; wheel.attr
+'main'
+&gt;&gt;&gt; wheel.extras
+[]
+&gt;&gt;&gt; main = wheel.load()
+&gt;&gt;&gt; main
+&lt;function main at 0x103528488&gt;
+</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">&gt;&gt;&gt; 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">&gt;&gt;&gt; wheel_metadata['Requires-Python']
+'&gt;=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">&gt;&gt;&gt; wheel_metadata.json['requires_python']
+'&gt;=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">&gt;&gt;&gt; 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">&gt;&gt;&gt; util = [p for p in files('wheel') if 'util.py' in str(p)][0]
+&gt;&gt;&gt; util
+PackagePath('wheel/util.py')
+&gt;&gt;&gt; util.size
+859
+&gt;&gt;&gt; util.dist
+&lt;importlib.metadata._hooks.PathDistribution object at 0x101e0cef0&gt;
+&gt;&gt;&gt; util.hash
+&lt;FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI&gt;
+</pre> <p>Once you have the file, you can also read its contents:</p> <pre data-language="python">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; requires('wheel')
+["pytest (&gt;=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">&gt;&gt;&gt; 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">&gt;&gt;&gt; from importlib.metadata import distribution
+&gt;&gt;&gt; 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; dist.metadata['Requires-Python']
+'&gt;=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
+&gt;&gt;&gt; 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">
+ &copy; 2001&ndash;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>