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 specifiers in this set.

: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(SpecifierSet(...).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(SpecifierSet(">=1.2.3").filter("1.2", "1.3", "1.5a1"))

'1.3'

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

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

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

[]

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

'1.3', '1.5a1'

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

'1.3', '1.5a1'

An "empty" SpecifierSet will filter items based on the presence of prerelease versions in the set.

list(SpecifierSet("").filter("1.3", "1.5a1"))

'1.3'

list(SpecifierSet("").filter("1.5a1"))

'1.5a1'

list(SpecifierSet("", prereleases=True).filter("1.3", "1.5a1"))

'1.3', '1.5a1'

list(SpecifierSet("").filter("1.3", "1.5a1", prereleases=True))

'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 specifiers in this set.

        :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(SpecifierSet(...).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(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
        ['1.3']
        >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")]))
        ['1.3', <Version('1.4')>]
        >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"]))
        []
        >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']

        An "empty" SpecifierSet will filter items based on the presence of prerelease
        versions in the set.

        >>> list(SpecifierSet("").filter(["1.3", "1.5a1"]))
        ['1.3']
        >>> list(SpecifierSet("").filter(["1.5a1"]))
        ['1.5a1']
        >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']
        >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        """
        # Determine if we're forcing a prerelease or not, if we're not forcing
        # one for this particular filter call, then we'll use whatever the
        # SpecifierSet thinks for whether or not we should support prereleases.
        if prereleases is None:
            prereleases = self.prereleases

        # If we have any specifiers, then we want to wrap our iterable in the
        # filter method for each one, this will act as a logical AND amongst
        # each specifier.
        if self._specs:
            for spec in self._specs:
                iterable = spec.filter(iterable, prereleases=bool(prereleases))
            return iter(iterable)
        # If we do not have any specifiers, then we need to have a rough filter
        # which will filter out any pre-releases, unless there are no final
        # releases.
        else:
            filtered: List[UnparsedVersionVar] = []
            found_prereleases: List[UnparsedVersionVar] = []

            for item in iterable:
                parsed_version = _coerce_version(item)

                # Store any item which is a pre-release for later unless we've
                # already found a final version or we are accepting prereleases
                if parsed_version.is_prerelease and not prereleases:
                    if not filtered:
                        found_prereleases.append(item)
                else:
                    filtered.append(item)

            # If we've found no items except for pre-releases, then we'll go
            # ahead and use the pre-releases
            if not filtered and found_prereleases and prereleases is None:
                return iter(found_prereleases)

            return iter(filtered)

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?>();