From e25bdba3a3a53b09be5269d8b065c13b73ab55c3 Mon Sep 17 00:00:00 2001 From: yum Date: Sun, 1 Jan 2023 21:05:27 -0800 Subject: Embed git in package package.ps1 fetches PortableGit and embeds it in the package. This eliminates all but one runtime dependency (MSVC++ Redistributable). * Move Python into a new FOSS folder. --- .../future-0.18.2/docs/custom_iterators.rst | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 FOSS/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst (limited to 'FOSS/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst') diff --git a/FOSS/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst b/FOSS/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst new file mode 100644 index 0000000..6ff389a --- /dev/null +++ b/FOSS/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst @@ -0,0 +1,94 @@ +.. _custom-iterators: + +Custom iterators +---------------- + +If you define your own iterators, there is an incompatibility in the method name +to retrieve the next item across Py3 and Py2. On Python 3 it is ``__next__``, +whereas on Python 2 it is ``next``. + +The most elegant solution to this is to derive your custom iterator class from +``builtins.object`` and define a ``__next__`` method as you normally +would on Python 3. On Python 2, ``object`` then refers to the +``future.types.newobject`` base class, which provides a fallback ``next`` +method that calls your ``__next__``. Use it as follows:: + + from builtins import object + + class Upper(object): + def __init__(self, iterable): + self._iter = iter(iterable) + def __next__(self): # Py3-style iterator interface + return next(self._iter).upper() + def __iter__(self): + return self + + itr = Upper('hello') + assert next(itr) == 'H' + assert next(itr) == 'E' + assert list(itr) == list('LLO') + + +You can use this approach unless you are defining a custom iterator as a +subclass of a base class defined elsewhere that does not derive from +``newobject``. In that case, you can provide compatibility across +Python 2 and Python 3 using the ``next`` function from ``future.builtins``:: + + from builtins import next + + from some_module import some_base_class + + class Upper2(some_base_class): + def __init__(self, iterable): + self._iter = iter(iterable) + def __next__(self): # Py3-style iterator interface + return next(self._iter).upper() + def __iter__(self): + return self + + itr2 = Upper2('hello') + assert next(itr2) == 'H' + assert next(itr2) == 'E' + +``next()`` also works with regular Python 2 iterators with a ``.next`` method:: + + itr3 = iter(['one', 'three', 'five']) + assert 'next' in dir(itr3) + assert next(itr3) == 'one' + +This approach is feasible whenever your code calls the ``next()`` function +explicitly. If you consume the iterator implicitly in a ``for`` loop or +``list()`` call or by some other means, the ``future.builtins.next`` function +will not help; the third assertion below would fail on Python 2:: + + itr2 = Upper2('hello') + + assert next(itr2) == 'H' + assert next(itr2) == 'E' + assert list(itr2) == list('LLO') # fails because Py2 implicitly looks + # for a ``next`` method. + +Instead, you can use a decorator called ``implements_iterator`` from +``future.utils`` to allow Py3-style iterators to work identically on Py2, even +if they don't inherit from ``future.builtins.object``. Use it as follows:: + + from future.utils import implements_iterator + + Upper2 = implements_iterator(Upper2) + + print(list(Upper2('hello'))) + # prints ['H', 'E', 'L', 'L', 'O'] + +This can of course also be used with the ``@`` decorator syntax when defining +the iterator as follows:: + + @implements_iterator + class Upper2(some_base_class): + def __init__(self, iterable): + self._iter = iter(iterable) + def __next__(self): # note the Py3 interface + return next(self._iter).upper() + def __iter__(self): + return self + +On Python 3, as usual, this decorator does nothing. -- cgit v1.2.3