|
1 | | -# transfunctions |
| 1 | +# transfunctions |
| 2 | + |
| 3 | +[](https://pepy.tech/project/transfunctions) |
| 4 | +[](https://pepy.tech/project/transfunctions) |
| 5 | +[](https://coveralls.io/github/pomponchik/transfunctions?branch=develop) |
| 6 | +[](https://github.com/boyter/scc/) |
| 7 | +[](https://hitsofcode.com/github/pomponchik/transfunctions/view?branch=main) |
| 8 | +[](https://github.com/pomponchik/transfunctions/actions/workflows/tests_and_coverage.yml) |
| 9 | +[](https://pypi.python.org/pypi/transfunctions) |
| 10 | +[](https://badge.fury.io/py/transfunctions) |
| 11 | +[](https://github.com/astral-sh/ruff) |
| 12 | + |
| 13 | +This library is designed to solve one of the most important problems in python programming - dividing all written code into 2 camps: sync and async. We get rid of code duplication by using templates. |
| 14 | + |
| 15 | + |
| 16 | +## Table of contents |
| 17 | + |
| 18 | +- [**Quick start**](#quick-start) |
| 19 | +- [**The problem**](#the-problem) |
| 20 | + |
| 21 | + |
| 22 | +## Quick start |
| 23 | + |
| 24 | +Install it: |
| 25 | + |
| 26 | +```bash |
| 27 | +pip install transfunctions |
| 28 | +``` |
| 29 | + |
| 30 | +And use: |
| 31 | + |
| 32 | +```python |
| 33 | +from asyncio import run |
| 34 | +from transfunctions import ( |
| 35 | + transfunction, |
| 36 | + sync_context, |
| 37 | + async_context, |
| 38 | + generator_context, |
| 39 | +) |
| 40 | + |
| 41 | +@transfunction |
| 42 | +def template(): |
| 43 | + print('so, ', end='') |
| 44 | + with sync_context: |
| 45 | + print("it's just usual function!") |
| 46 | + with async_context: |
| 47 | + print("it's an async function!") |
| 48 | + with generator_context: |
| 49 | + print("it's a generator function!") |
| 50 | + yield |
| 51 | + |
| 52 | +function = template.get_usual_function() |
| 53 | +function() |
| 54 | +#> so, it's just usual function! |
| 55 | + |
| 56 | +async_function = template.get_async_function() |
| 57 | +run(async_function()) |
| 58 | +#> so, it's an async function! |
| 59 | + |
| 60 | +generator_function = template.get_generator_function() |
| 61 | +list(generator_function()) |
| 62 | +#> so, it's a generator function! |
| 63 | +``` |
| 64 | + |
| 65 | +As you can see, in this case, 3 different functions were created based on the template, including both common parts and unique ones for a specific type of function. |
| 66 | + |
| 67 | +You can also quickly try out this and other packages without having to install using [instld](https://github.com/pomponchik/instld). |
| 68 | + |
| 69 | + |
| 70 | +## The problem |
| 71 | + |
| 72 | +Since the `asyncio` module appeared in Python more than 10 years ago, many well-known libraries have received their asynchronous alternates. A lot of the code in the Python ecosystem has been [duplicated](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself), and you probably know many such examples. |
| 73 | + |
| 74 | +The reason for this problem is that the Python community has chosen a way to implement asynchrony expressed through syntax. There are new keywords in the language, such as `async` and `await`. Their use makes the code so-called "[multicolored](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/)": all the functions in it can be red or blue, and depending on the color, the rules for calling them are different. You can only call blue functions from red ones, but not vice versa. |
| 75 | + |
| 76 | +I must say that implementing asynchronous calls using a special syntax is not the only solution. There are languages like Go where runtime can independently determine "under the hood" where a function should be asynchronous and where not, and choose the correct way to call it. A programmer does not need to manually "colorize" their functions there. Personally, I think that choosing a different path is the mistake of the Python community, but that's not what we're discussing here. |
0 commit comments