Specifiers ========== 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. Usage ----- .. doctest:: >>> from inversion.python import PythonVersion, PythonSpecifierSet >>> spec1 = PythonSpecifierSet("~=1.0") >>> spec1 >>> spec2 = PythonSpecifierSet(">=1.0") >>> spec2 =1.0')> >>> # We can combine specifiers: >>> combined_spec = spec1 & spec2 >>> combined_spec =1.0,~=1.0')> >>> # We can also implicitly combine a string specifier: >>> combined_spec &= "!=1.1" >>> combined_spec =1.0,~=1.0')> >>> # Create a few versions to check for contains: >>> v1 = PythonVersion("1.0a5") >>> v2 = PythonVersion("1.0") >>> # We can check a version object to see if it falls within a specifier: >>> v1 in combined_spec False >>> v2 in combined_spec True >>> # We can even do the same with a string based version: >>> "1.4" in combined_spec True >>> # Finally we can filter a list of versions to get only those which are >>> # contained within our specifier: >>> list(combined_spec.filter([v1, v2, "1.4"])) [, '1.4'] Reference --------- Python Specifiers ^^^^^^^^^^^^^^^^^ .. currentmodule:: inversion.python .. class:: PythonSpecifierSet(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. This will attempt to parse each individual specifier be as a `PEP 440`_ specifier (:class:`PythonSpecifier`). You may combine :class:`PythonSpecifierSet` instances using the ``&`` operator (``PythonSpecifierSet(">2") & PythonSpecifierSet("<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:`PythonSpecifierSet` 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 or a :class:`PythonVersion`, 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 ``PythonSpecifier().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:`PythonSpecifier` instances in this specifier set. .. method:: filter(iterable, prereleases=None) Takes an iterable that can contain version strings and :class:`.PythonVersion` instances and will then filter it, 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 ``PythonSpecifier().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:: PythonSpecifier(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:`PythonSpecifierSet`. :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:`PythonSpecifierSet.prereleases`. .. method:: __contains__(version) See :meth:`PythonSpecifierSet.__contains__()`. .. method:: contains(version, prereleases=None) See :meth:`PythonSpecifierSet.contains()`. .. method:: filter(iterable, prereleases=None) See :meth:`PythonSpecifierSet.filter()`. .. class:: SpecifierSet(specifiers, prereleases=None) An alias for :class:`PythonSpecifierSet`. .. class:: Specifier(specifier, prereleases=None) An alias for :class:`PythonSpecifier`. Loose Specifiers ^^^^^^^^^^^^^^^^ .. currentmodule:: inversion.loose .. class:: LooseSpecifierSet(specifiers) This class abstracts handling specifying the dependencies of a project that doesn't use `PEP 440`_-compatible versions. Like :class:`PythonSpecifierSet`, it can be passed a single specifier (``>=3.0``), a comma-separated list of specifiers (``>=3.0,!=3.1``), or no specifier at all. This will attempt to parse each individual specifier as a :class:`LooseSpecifier`. You may combine :class:`LooseSpecifierSet` instances using the ``&`` operator (``LooseSpecifierSet(">2") & LooseSpecifierSet("<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. :raises InvalidSpecifier: If the given ``specifiers`` are not parseable than this exception will be raised. .. attribute:: prereleases This will always be ``None`` since without `PEP 440`_ we do not have the concept of a prerelease. It exists primarily for compatibility with :class:`~.PythonSpecifierSet`'s interface. .. 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 or a :class:`LooseVersion`, is contained within this set of specifiers. The ``prereleases`` parameter is ignored and exists primarily for compatibility with :class:`~.PythonSpecifierSet`'s interface. .. method:: __len__() Returns the number of specifiers in this specifier set. .. method:: __iter__() Returns an iterator over all the underlying :class:`LooseSpecifier` (or :class:`LegacySpecifier`) instances in this specifier set. .. method:: filter(iterable, prereleases=None) Takes an iterable that can contain version strings and :class:`LooseVersion` instances and will then filter it, 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 is ignored and exists primarily for compatibility with :class:`~.PythonSpecifierSet`'s interface. .. class:: LooseSpecifier(specifier) This class abstracts the handling of a single "loose" version specifier. It is generally not required to instantiate this manually, preferring instead to work with :class:`LooseSpecifierSet`. :param str specifier: The string representation of a specifier which will be parsed and normalized before use. :raises InvalidSpecifier: If the ``specifier`` is not parseable then this 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:`LooseSpecifierSet.prereleases`. .. method:: __contains__(version) See :meth:`LooseSpecifierSet.__contains__()`. .. method:: contains(version, prereleases=None) See :meth:`LooseSpecifierSet.contains()`. .. method:: filter(iterable, prereleases=None) See :meth:`LooseSpecifierSet.filter()`. .. class:: SpecifierSet(specifiers) An alias for :class:`LooseSpecifierSet`. .. class:: Specifier(specifier) An alias for :class:`LooseSpecifier`. Exceptions ^^^^^^^^^^ .. currentmodule:: inversion.basespecifier .. exception:: InvalidSpecifier Raised when attempting to create a :class:`~.PythonSpecifier` or :class:`~.LooseSpecifier` with a specifier string that does not conform to `PEP 440`_. .. _`PEP 440`: https://www.python.org/dev/peps/pep-0440/