filter method

Iterator<Object?> filter({
  1. required Iterable<Object?> iterable,
  2. Object? prereleases,
})

filter

python docstring

Filter items in the given iterable, that match the specifier.

:param iterable: An iterable that can contain version strings and :class:Version instances. The items in the iterable will be filtered according to the specifier. :param prereleases: Whether or not to allow prereleases in the returned iterator. If set to None (the default), it will be intelligently decide whether to allow prereleases or not (based on the :attr:prereleases attribute, and whether the only versions matching are prereleases).

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

list(Specifier(">=1.2.3").filter("1.2", "1.3", "1.5a1"))

'1.3'

list(Specifier(">=1.2.3").filter("1.2", "1.2.3", "1.3", Version("1.4")))

'1.2.3', '1.3', <Version('1.4')>

list(Specifier(">=1.2.3").filter("1.2", "1.5a1"))

'1.5a1'

list(Specifier(">=1.2.3").filter("1.3", "1.5a1", prereleases=True))

'1.3', '1.5a1'

list(Specifier(">=1.2.3", prereleases=True).filter("1.3", "1.5a1"))

'1.3', '1.5a1'

python source

def filter(
        self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None
    ) -> Iterator[UnparsedVersionVar]:
        """Filter items in the given iterable, that match the specifier.

        :param iterable:
            An iterable that can contain version strings and :class:`Version` instances.
            The items in the iterable will be filtered according to the specifier.
        :param prereleases:
            Whether or not to allow prereleases in the returned iterator. If set to
            ``None`` (the default), it will be intelligently decide whether to allow
            prereleases or not (based on the :attr:`prereleases` attribute, and
            whether the only versions matching are prereleases).

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

        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
        ['1.3']
        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")]))
        ['1.2.3', '1.3', <Version('1.4')>]
        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"]))
        ['1.5a1']
        >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']
        """

        yielded = False
        found_prereleases = []

        kw = {"prereleases": prereleases if prereleases is not None else True}

        # Attempt to iterate over all the values in the iterable and if any of
        # them match, yield them.
        for version in iterable:
            parsed_version = _coerce_version(version)

            if self.contains(parsed_version, **kw):
                # If our version is a prerelease, and we were not set to allow
                # prereleases, then we'll store it for later in case nothing
                # else matches this specifier.
                if parsed_version.is_prerelease and not (
                    prereleases or self.prereleases
                ):
                    found_prereleases.append(version)
                # Either this is not a prerelease, or we should have been
                # accepting prereleases from the beginning.
                else:
                    yielded = True
                    yield version

        # Now that we've iterated over everything, determine if we've yielded
        # any values, and if we have not and we have any prereleases stored up
        # then we will go ahead and yield the prereleases.
        if not yielded and found_prereleases:
            for version in found_prereleases:
                yield version

Implementation

Iterator<Object?> filter({
  required Iterable<Object?> iterable,
  Object? prereleases,
}) =>
    TypedIterator.from(
      PythonIterator.from<Object?, PythonFfiDelegate<Object?>, Object?>(
        getFunction("filter").call(
          <Object?>[
            iterable,
            prereleases,
          ],
          kwargs: <String, Object?>{},
        ),
      ),
    ).transform((e) => e).cast<Object?>();