Skip to main content

A backport of the `yield from` semantic from Python 3.x to Python 2.7

Project description

A backport of the yield from semantic from Python 3.x to Python 2.7

If you want to nest generators in Python 3.x, you can use the yield from keywords. This allows you to automatically iterate over sub-generators and transparently pass exceptions and return values from the top level caller to the lowest generator.

def subgen():
    yield 2
    yield 3

def gen():
    yield 1
    yield from subgen()  # Python 3.x only
    yield 4

def main():
    for i in gen():
        print i,

>>> main()
... 1 2 3 4

This functionality is not available in Python 2.x, and we emulate it using the yieldfrom decorator and the helper From class:

from yieldfrom import yieldfrom, From
def subgen():
    yield 2
    yield 3

@yieldfrom
def gen():
    yield 1
    yield From(subgen())
    yield 4

def main():
    for i in gen():
        print i,

>>> main()
... 1 2 3 4

Advanced usage allows returning a value from the subgenerator using StopIteration. Using Return does this conveniently:

from yieldfrom import yieldfrom, From, Return

def subgen():
    yield 2
    yield 3
    Return(100)  # Raises `StopIteration(100)`

@yieldfrom
def gen():
    yield 1
    ret = (yield From(subgen()))
    yield 4
    yield ret

def main():
    for i in gen():
        print i,

>>> main()
... 1 2 3 4 100

Subgenerators can be nested on multiple levels, each one requiring additional decoration by yieldfrom:

def subsubgen():
    yield 2

@yieldfrom
def subgen():
    yield From(subsubgen())
    yield 3

@yieldfrom
def gen():
    yield 1
    yield From(subgen())
    yield 4

def main():
    for i in gen():
        print i,

>>> main()
... 1 2 3 4

Exceptions thrown into the top-level generator can be handled in relevant subgenerators:

def subsubgen():
    try:
        yield 2
    except ValueError:
        yield 200

@yieldfrom
def subgen():
    yield From(subsubgen())
    yield 3

@yieldfrom
def gen():
    yield 1
    yield From(subgen())
    yield 4

def main():
    try:
        g = gen()
        while True:
            i = g.next()
            if i == 2:
                i = g.throw(ValueError())
        print i,
    except StopIteration:
        pass

>>> main()
... 1 200 3 4

Note that if you use yield From() on a simple iterable (list, tuple, etc) then the individual members of the iterator will be yielded on each iteration (perhaps in that case you need the usual yield).

@yieldfrom
def gen():
    yield From([1, 2, 3])
    yield [1, 2, 3]

def main():
    for i in gen():
        print i

>>> main()
... 1
... 2
... 3
... [1, 2, 3]

Passing non-iterable objects to From will result in an empty generator that does nothing.

@yieldfrom
def gen():
    yield From(None)
    yield 1

def main():
    for i in gen():
        print i

>>> main()
... 1

This module is an adaptation of the following Python recipe: http://code.activestate.com/recipes/576727
Modifications include bug fixes in exception handling, naming, documentation, handling of empty generators, etc.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yieldfrom-1.0.4.tar.gz (5.0 kB view details)

Uploaded Source

Built Distribution

yieldfrom-1.0.4-py2-none-any.whl (6.1 kB view details)

Uploaded Python 2

File details

Details for the file yieldfrom-1.0.4.tar.gz.

File metadata

  • Download URL: yieldfrom-1.0.4.tar.gz
  • Upload date:
  • Size: 5.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.6.2 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/2.7.12

File hashes

Hashes for yieldfrom-1.0.4.tar.gz
Algorithm Hash digest
SHA256 09c4e32402ec1c098e66ef5e25e036134f0e84f72ff5817641728707a168f5b3
MD5 98182ff0e861458e9e3dfaa0d47a47af
BLAKE2b-256 6ed2dc48e4cc6bbe48afd022da745f981cf0437ab7e658de9078bf56747b1d73

See more details on using hashes here.

File details

Details for the file yieldfrom-1.0.4-py2-none-any.whl.

File metadata

  • Download URL: yieldfrom-1.0.4-py2-none-any.whl
  • Upload date:
  • Size: 6.1 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.6.2 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/2.7.10

File hashes

Hashes for yieldfrom-1.0.4-py2-none-any.whl
Algorithm Hash digest
SHA256 ab62daf50776de62b7ea98f5264f372c1cb33ca8af1a244bd5c42405381edf8e
MD5 c94df2ec41cee7e89dc23f3549ec3026
BLAKE2b-256 a7a968ac74ef7b1b8950a8aa40493f99b8756e69cbcbccdd020a523d532697c6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page