Greengen
Greengen is a python package that allows implementing generators without yielding items all the way up. Instead, any inner function called from a greengen generator, can yield items directly to the outer generator.
Installation
pip install greengen
Usage
For example, suppose we want to implement a function that performs some heavy business logic, and generates logs. We want to handle the logs the moment they are created. But our function has to call a deep stack of helper functions, which in their turn call more functions, and logs may be written anywhere inside any function. The implementation with regular generators will be utterly annoying:
import time
def do_business_logic_and_yield_logs(some_input):
yield from _helper_function(some_input)
yield from _more_helper_function(some_input)
def _helper_function(some_input):
for i in range(some_input):
logs_and_result = _inner_helper_function(i)
# Notice the enormous effort needed in order to retrieve the last result (using StopIteration etc.)
while True:
try:
yield next(logs_and_result) # This is a log
except StopIteration as e:
result = e.value # This is the result
yield log('Result for {} is {}'.format(i, result))
break
def _more_helper_function(some_input):
yield from _helper_function(some_input * 100)
yield from _helper_function(some_input ** 2)
def _inner_helper_function(some_input):
yield log('Started calculating')
result = 2 ** some_input # (Or whatever other heavy calculation)
yield log('Finished calculating')
return result # Will be raised as StopIteration
def log(stuff):
return {'message': str(stuff), 'timestamp': time.time()}
def main():
for l in do_business_logic_and_yield_logs(42):
# Consume the logs however we want
print('{}: {}'.format(l['timestamp'], l['message']))
Using Greengen, this example can be simplified into the following:
import time
import greengen
@greengen.greengen
def do_business_logic_and_yield_logs(some_input):
# Notice how we don't need the "yield from" anymore
_helper_function(some_input)
_more_helper_function(some_input)
def _helper_function(some_input):
for i in range(some_input):
# Notice how easy it is to retrieve the result now
result = _inner_helper_function(i)
log('Result for {} is {}'.format(i, result))
def _more_helper_function(some_input):
_helper_function(some_input * 100)
_helper_function(some_input ** 2)
def _inner_helper_function(some_input):
log('Started calculating')
result = 2 ** some_input # (Or whatever other heavy calculation)
log('Finished calculating')
return result
def log(stuff):
# This is the only place in the entire code where we need to be aware of the fact that we are inside a generator.
# This will directly yield the log as the next item in the outer generator ("do_business_logic_and_yield_logs")
greengen.yield_({'message': str(stuff), 'timestamp': time.time()})
def main():
for l in do_business_logic_and_yield_logs(42):
# Consume the logs however we want
print('{}: {}'.format(l['timestamp'], l['message']))
Contributing
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request :D
History
TODO: Write history
Credits
TODO: Write credits
License
TODO: Write license
Release files for greengen 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| greengen-1.0.1.tar.gz | 3.2 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| greengen-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
| greengen-1.0.1-py2-none-any.whl | Python 2 | none | any | Details |
Total release size: 10.8 kB
Release files / greengen-1.0.1.tar.gz
| Download URL | greengen-1.0.1.tar.gz |
|---|---|
| Size | 3.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
16568936a550d00025a9fd8bc5c1fc15fe4d29d8e02e37746d28b806c94c4462
|
|
BLAKE2b-256 checksum How to use checksums |
5f45919ecfbfc017d385968a457f70ebf1af3043381d950337aa12722e332697
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
|
Release files / greengen-1.0.1-py3-none-any.whl
| Download URL | greengen-1.0.1-py3-none-any.whl |
|---|---|
| Size | 3.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3551339d45055d59c029bfd3ffdb3ca413d26f00834d07a1bdc3abc1e810a250
|
|
BLAKE2b-256 checksum How to use checksums |
16129d99c7b462c92d24d60115347a46ba3c5afbca67efb0126ae75548d3d3f6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
|
Release files / greengen-1.0.1-py2-none-any.whl
| Download URL | greengen-1.0.1-py2-none-any.whl |
|---|---|
| Size | 3.8 kB |
| Tags | Python 2 |
|
SHA-256 checksum How to use checksums |
d65086bb296af0458ba0732dc036d725724383e06dff9c12310e28a8e3e50cc9
|
|
BLAKE2b-256 checksum How to use checksums |
bc4a63887d2337122a5791279fe4003a41288666e91e0660847ce12b6ccc3933
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
|