Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move metadata, versions and specifiers API documentation to sphinx.ext.autodoc #572

Merged
merged 5 commits into from Jul 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Empty file removed docs/_static/.empty
Empty file.
109 changes: 33 additions & 76 deletions docs/conf.py
Expand Up @@ -3,14 +3,16 @@
# for complete details.

import os
import sys

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath("."))
# -- Project information loading ----------------------------------------------

ABOUT = {}
_BASE_DIR = os.path.join(os.path.dirname(__file__), os.pardir)
with open(os.path.join(_BASE_DIR, "packaging", "__about__.py")) as f:
exec(f.read(), ABOUT)

# -- General configuration ----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
Expand All @@ -19,93 +21,48 @@
"sphinx.ext.doctest",
"sphinx.ext.extlinks",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# The suffix of source filenames.
source_suffix = ".rst"

# The master toctree document.
master_doc = "index"

# General information about the project.
project = "Packaging"
version = ABOUT["__version__"]
release = ABOUT["__version__"]
copyright = ABOUT["__copyright__"]

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#

base_dir = os.path.join(os.path.dirname(__file__), os.pardir)
about = {}
with open(os.path.join(base_dir, "packaging", "__about__.py")) as f:
exec(f.read(), about)

version = release = about["__version__"]
copyright = about["__copyright__"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["_build"]

extlinks = {
"issue": ("https://github.com/pypa/packaging/issues/%s", "#%s"),
"pull": ("https://github.com/pypa/packaging/pull/%s", "PR #%s"),
}
# -- Options for HTML output --------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.

html_theme = "furo"
html_title = "packaging"
html_title = project

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# -- Options for autodoc ----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration

# Output file base name for HTML help builder.
htmlhelp_basename = "packagingdoc"
autodoc_member_order = "bysource"
autodoc_preserve_defaults = True

# Automatically extract typehints when specified and place them in
# descriptions of the relevant function/method.
autodoc_typehints = "description"

# -- Options for LaTeX output -------------------------------------------------
# Don't show class signature with the class' name.
autodoc_class_signature = "separated"

latex_elements = {}
# -- Options for extlinks -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html#configuration

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual])
latex_documents = [
("index", "packaging.tex", "Packaging Documentation", "Donald Stufft", "manual")
]

# -- Options for manual page output -------------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [("index", "packaging", "Packaging Documentation", ["Donald Stufft"], 1)]

# -- Options for Texinfo output -----------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
"index",
"packaging",
"Packaging Documentation",
"Donald Stufft",
"packaging",
"Core utilities for Python packages",
"Miscellaneous",
)
]
extlinks = {
"issue": ("https://github.com/pypa/packaging/issues/%s", "#%s"),
"pull": ("https://github.com/pypa/packaging/pull/%s", "PR #%s"),
}

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"https://docs.python.org/": None}
# -- Options for intersphinx ----------------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration

epub_theme = "epub"
intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"pypug": ("https://packaging.python.org/", None),
}
82 changes: 5 additions & 77 deletions docs/metadata.rst
@@ -1,86 +1,14 @@
Metadata
==========

.. currentmodule:: packaging.metadata

A data representation for `core metadata`_.

.. _`core metadata`: https://packaging.python.org/en/latest/specifications/core-metadata/


Reference
---------

.. class:: DynamicField

An :class:`enum.Enum` representing fields which can be listed in
the ``Dynamic`` field of `core metadata`_. Every valid field is
a name on this enum, upper-cased with any ``-`` replaced with ``_``.
Each value is the field name lower-cased (``-`` are kept). For
example, the ``Home-page`` field has a name of ``HOME_PAGE`` and a
value of ``home-page``.


.. class:: Metadata(name, version, *, platforms=None, summary=None, description=None, keywords=None, home_page=None, author=None, author_emails=None, license=None, supported_platforms=None, download_url=None, classifiers=None, maintainer=None, maintainer_emails=None, requires_dists=None, requires_python=None, requires_externals=None, project_urls=None, provides_dists= None, obsoletes_dists= None, description_content_type=None, provides_extras=None, dynamic_fields=None)

A class representing the `core metadata`_ for a project.

Every potential metadata field except for ``Metadata-Version`` is
represented by a parameter to the class' constructor. The required
metadata can be passed in positionally or via keyword, while all
optional metadata can only be passed in via keyword.

Every parameter has a matching attribute on instances,
except for *name* (see :attr:`display_name` and
:attr:`canonical_name`). Any parameter that accepts an
:class:`~collections.abc.Iterable` is represented as a
:class:`list` on the corresponding attribute.

:param str name: ``Name``.
:param packaging.version.Version version: ``Version`` (note
that this is different than ``Metadata-Version``).
:param Iterable[str] platforms: ``Platform``.
:param str summary: ``Summary``.
:param str description: ``Description``.
:param Iterable[str] keywords: ``Keywords``.
:param str home_page: ``Home-Page``.
:param str author: ``Author``.
:param Iterable[tuple[str | None, str]] author_emails: ``Author-Email``
where the two-item tuple represents the name and email of the author,
respectively.
:param str license: ``License``.
:param Iterable[str] supported_platforms: ``Supported-Platform``.
:param str download_url: ``Download-URL``.
:param Iterable[str] classifiers: ``Classifier``.
:param str maintainer: ``Maintainer``.
:param Iterable[tuple[str | None, str]] maintainer_emails: ``Maintainer-Email``,
where the two-item tuple represents the name and email of the maintainer,
respectively.
:param Iterable[packaging.requirements.Requirement] requires_dists: ``Requires-Dist``.
:param packaging.specifiers.SpecifierSet requires_python: ``Requires-Python``.
:param Iterable[str] requires_externals: ``Requires-External``.
:param tuple[str, str] project_urls: ``Project-URL``.
:param Iterable[str] provides_dists: ``Provides-Dist``.
:param Iterable[str] obsoletes_dists: ``Obsoletes-Dist``.
:param str description_content_type: ``Description-Content-Type``.
:param Iterable[packaging.utils.NormalizedName] provides_extras: ``Provides-Extra``.
:param Iterable[DynamicField] dynamic_fields: ``Dynamic``.

Attributes not directly corresponding to a parameter are:

.. attribute:: display_name

The project name to be displayed to users (i.e. not normalized).
Initially set based on the *name* parameter.
Setting this attribute will also update :attr:`canonical_name`.

.. attribute:: canonical_name

The normalized project name as per
:func:`packaging.utils.canonicalize_name`. The attribute is
read-only and automatically calculated based on the value of
:attr:`display_name`.


.. _`core metadata`: https://packaging.python.org/en/latest/specifications/core-metadata/
.. _`project metadata`: https://packaging.python.org/en/latest/specifications/declaring-project-metadata/
.. _`source distribution`: https://packaging.python.org/en/latest/specifications/source-distribution-format/
.. _`binary distrubtion`: https://packaging.python.org/en/latest/specifications/binary-distribution-format/
.. automodule:: packaging.metadata
:members:
:undoc-members:
137 changes: 9 additions & 128 deletions docs/specifiers.rst
@@ -1,11 +1,13 @@
Specifiers
==========

.. currentmodule:: packaging.specifiers
A core requirement of dealing with dependencies is the ability to
specify what versions of a dependency are acceptable for you.

A core requirement of dealing with dependencies is the ability to specify what
versions of a dependency are acceptable for you. `PEP 440`_ defines the
standard specifier scheme which has been implemented by this module.
See `Version Specifiers Specification`_ for more details on the exact
format implemented in this module, for use in Python Packaging tooling.

.. _Version Specifiers Specification: https://packaging.python.org/en/latest/specifications/version-specifiers/

Usage
-----
Expand Down Expand Up @@ -48,127 +50,6 @@ Usage
Reference
---------

.. class:: SpecifierSet(specifiers="", prereleases=None)

This class abstracts handling specifying the dependencies of a project. It
can be passed a single specifier (``>=3.0``), a comma-separated list of
specifiers (``>=3.0,!=3.1``), or no specifier at all. Each individual
specifier will be attempted to be parsed as a PEP 440 specifier
(:class:`Specifier`). You may combine :class:`SpecifierSet` instances using
the ``&`` operator (``SpecifierSet(">2") & SpecifierSet("<4")``).

Both the membership tests and the combination support using raw strings
in place of already instantiated objects.

:param str specifiers: The string representation of a specifier or a
comma-separated list of specifiers which will
be parsed and normalized before use.
:param bool prereleases: This tells the SpecifierSet if it should accept
prerelease versions if applicable or not. The
default of ``None`` will autodetect it from the
given specifiers.
:raises InvalidSpecifier: If the given ``specifiers`` are not parseable
than this exception will be raised.

.. attribute:: prereleases

A boolean value indicating whether this :class:`SpecifierSet`
represents a specifier that includes a pre-release versions. This can be
set to either ``True`` or ``False`` to explicitly enable or disable
prereleases or it can be set to ``None`` (the default) to enable
autodetection.

.. method:: __contains__(version)

This is the more Pythonic version of :meth:`contains()`, but does
not allow you to override the ``prereleases`` argument. If you
need that, use :meth:`contains()`.

See :meth:`contains()`.

.. method:: contains(version, prereleases=None)

Determines if ``version``, which can be either a version string, a
:class:`Version` is contained within this set of specifiers.

This will either match or not match prereleases based on the
``prereleases`` parameter. When ``prereleases`` is set to ``None``
(the default) it will use the ``Specifier().prereleases`` attribute to
determine if to allow them. Otherwise it will use the boolean value of
the passed in value to determine if to allow them or not.

.. method:: __len__()

Returns the number of specifiers in this specifier set.

.. method:: __iter__()

Returns an iterator over all the underlying :class:`Specifier` instances
in this specifier set.

.. method:: filter(iterable, prereleases=None)

Takes an iterable that can contain version strings, :class:`~.Version`,
instances and will then filter them, returning an iterable that contains
only items which match the rules of this specifier object.

This method is smarter than just
``filter(Specifier().contains, [...])`` because it implements the rule
from PEP 440 where a prerelease item SHOULD be accepted if no other
versions match the given specifier.

The ``prereleases`` parameter functions similarly to that of the same
parameter in ``contains``. If the value is ``None`` (the default) then
it will intelligently decide if to allow prereleases based on the
specifier, the ``Specifier().prereleases`` value, and the PEP 440
rules. Otherwise it will act as a boolean which will enable or disable
all prerelease versions from being included.


.. class:: Specifier(specifier, prereleases=None)

This class abstracts the handling of a single `PEP 440`_ compatible
specifier. It is generally not required to instantiate this manually,
preferring instead to work with :class:`SpecifierSet`.

:param str specifier: The string representation of a specifier which will
be parsed and normalized before use.
:param bool prereleases: This tells the specifier if it should accept
prerelease versions if applicable or not. The
default of ``None`` will autodetect it from the
given specifiers.
:raises InvalidSpecifier: If the ``specifier`` does not conform to PEP 440
in any way then this exception will be raised.

.. attribute:: operator

The string value of the operator part of this specifier.

.. attribute:: version

The string version of the version part of this specifier.

.. attribute:: prereleases

See :attr:`SpecifierSet.prereleases`.

.. method:: __contains__(version)

See :meth:`SpecifierSet.__contains__()`.

.. method:: contains(version, prereleases=None)

See :meth:`SpecifierSet.contains()`.

.. method:: filter(iterable, prereleases=None)

See :meth:`SpecifierSet.filter()`.


.. exception:: InvalidSpecifier

Raised when attempting to create a :class:`Specifier` with a specifier
string that does not conform to `PEP 440`_.


.. _`PEP 440`: https://www.python.org/dev/peps/pep-0440/
.. automodule:: packaging.specifiers
:members:
:special-members: