Requirements
============

.. currentmodule:: packaging.requirements

Parse a given requirements line for specifying dependencies of a Python
project, using the :ref:`specification of dependency specifiers
<pypug:dependency-specifiers>`, which defines the scheme that has been
implemented by this module.

Usage
-----

.. doctest::

    >>> from packaging.requirements import Requirement
    >>> simple_req = Requirement("name")
    >>> simple_req
    <Requirement('name')>
    >>> simple_req.name
    'name'
    >>> simple_req.url is None
    True
    >>> simple_req.extras
    set()
    >>> simple_req.specifier
    <SpecifierSet('')>
    >>> simple_req.marker is None
    True
    >>> # Requirements can be specified with extras, specifiers and markers
    >>> req = Requirement('name[foo]>=2,<3; python_version>"2.0"')
    >>> req.name
    'name'
    >>> req.extras
    {'foo'}
    >>> req.specifier
    <SpecifierSet('<3,>=2')>
    >>> req.marker
    <Marker('python_version > "2.0"')>
    >>> # Requirements can also be specified with a URL, but may not specify
    >>> # a version.
    >>> url_req = Requirement('name @ https://github.com/pypa ;os_name=="a"')
    >>> url_req.name
    'name'
    >>> url_req.url
    'https://github.com/pypa'
    >>> url_req.extras
    set()
    >>> url_req.marker
    <Marker('os_name == "a"')>
    >>> # You can do simple comparisons between requirement objects:
    >>> Requirement("packaging") == Requirement("packaging")
    True
    >>> Requirement("my_pkg[foo_bar] == 1.0") == Requirement("my-pkg[foo-bar] == 1.0.0")
    True
    >>> str(Requirement("my_pkg[foo_bar] == 1.0"))
    'my_pkg[foo_bar]==1.0'
    >>> # You can also perform simple comparisons between sets of requirements:
    >>> requirements1 = {Requirement("packaging"), Requirement("pip")}
    >>> requirements2 = {Requirement("pip"), Requirement("packaging")}
    >>> requirements1 == requirements2
    True

.. versionchanged:: 23.2

    When a requirement is specified with a URL, the :class:`Requirement` class
    used to check the URL and reject values containing invalid scheme and
    netloc combinations. This is no longer performed since the specification does
    not have such rules, and the check incorrectly disallows valid requirement
    strings from being parsed.

Reference
---------

.. class:: Requirement(requirement_string)

    This class abstracts handling the details of a requirement for a project.
    Each requirement will be parsed according to the specification.

    .. versionadded:: 16.1

    .. versionchanged:: 22.0
        Added equality (``__eq__``) and hashing (``__hash__``) so requirements
        can be compared and stored in sets / dicts.

    .. versionchanged:: 23.2
        Equality and hashing began canonicalizing requirement names, so
        requirements whose names differ only by normalization (e.g.
        ``Requirement("Foo")`` vs ``Requirement("foo")``) now compare and hash
        equal.

    Instances are safe to serialize with :mod:`pickle`. They use a stable
    format so the same pickle can be loaded in future packaging releases.

    .. versionchanged:: 26.2

        Added a stable pickle format. Pickles created with packaging 26.2+ can
        be unpickled with future releases.  Backward compatibility with pickles
        from packaging < 26.2 is supported but may be removed in a future
        release.

    .. versionchanged:: 26.3

        The dedicated pickle support introduced in 26.2 did not preserve the
        specifier's explicit :attr:`~packaging.specifiers.SpecifierSet.prereleases`
        override; it is now included again.

        Equality and hashing normalize extras and equivalent specifiers. The
        string representation still preserves the parsed name and extras
        spelling.

    :param str requirement_string: The string representation of a requirement.
    :raises InvalidRequirement: If the given ``requirement_string`` is not parseable,
                                then this exception will be raised.

    .. attribute:: name

       The name of the requirement.

    .. attribute:: url

      The URL, if any, where to download the requirement from. Can be None.

    .. attribute:: extras

      A set of extras that the requirement specifies.

    .. attribute:: specifier

      A :class:`~.SpecifierSet` of the version specified by the requirement.

    .. attribute:: marker

      A :class:`~.Marker` of the marker for the requirement. Can be None.

.. exception:: InvalidRequirement

    Raised when attempting to create a :class:`Requirement` with a string that
    does not conform to the specification.

    .. versionadded:: 16.1
