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
Metadata
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 | Provenance | |
|---|---|---|---|---|
| greengen-1.0.1.tar.gz | 3.2 kB | Without provenance | 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
|
Security for greengen 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.