Skip to content

Commit 8b62fd5

Browse files
authored
Merge pull request #1 from pomponchik/develop
0.0.1
2 parents c03fe5a + bdd69a8 commit 8b62fd5

23 files changed

Lines changed: 1288 additions & 1 deletion
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: bug
6+
assignees: pomponchik
7+
8+
---
9+
10+
## Short description
11+
12+
Replace this text with a short description of the error and the behavior that you expected to see instead.
13+
14+
15+
## Describe the bug in detail
16+
17+
Please add this test in such a way that it reproduces the bug you found and does not pass:
18+
19+
```python
20+
def test_your_bug():
21+
...
22+
```
23+
24+
Writing the test, please keep compatibility with the [`pytest`](https://docs.pytest.org/) framework.
25+
26+
If for some reason you cannot describe the error in the test format, describe here the steps to reproduce it.
27+
28+
29+
## Environment
30+
- OS: ...
31+
- Python version (the output of the `python --version` command): ...
32+
- Version of this package: ...
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: Documentation fix
3+
about: Add something to the documentation, delete it, or change it
4+
title: ''
5+
labels: documentation
6+
assignees: pomponchik
7+
---
8+
9+
## It's cool that you're here!
10+
11+
Documentation is an important part of the project, we strive to make it high-quality and keep it up to date. Please adjust this template by outlining your proposal.
12+
13+
14+
## Type of action
15+
16+
What do you want to do: remove something, add it, or change it?
17+
18+
19+
## Where?
20+
21+
Specify which part of the documentation you want to make a change to? For example, the name of an existing documentation section or the line number in a file `README.md`.
22+
23+
24+
## The essence
25+
26+
Please describe the essence of the proposed change
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: enhancement
6+
assignees: pomponchik
7+
8+
---
9+
10+
## Short description
11+
12+
What do you propose and why do you consider it important?
13+
14+
15+
## Some details
16+
17+
If you can, provide code examples that will show how your proposal will work. Also, if you can, indicate which alternatives to this behavior you have considered. And finally, how do you propose to test the correctness of the implementation of your idea, if at all possible?

.github/ISSUE_TEMPLATE/question.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
name: Question or consultation
3+
about: Ask anything about this project
4+
title: ''
5+
labels: guestion
6+
assignees: pomponchik
7+
8+
---
9+
10+
## Your question
11+
12+
Here you can freely describe your question about the project. Please, before doing this, read the documentation provided, and ask the question only if the necessary answer is not there. In addition, please keep in mind that this is a free non-commercial project and user support is optional for its author. The response time is not guaranteed in any way.

.github/workflows/lint.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Lint
2+
3+
on:
4+
push
5+
6+
jobs:
7+
build:
8+
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
13+
14+
steps:
15+
- uses: actions/checkout@v2
16+
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v3
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install dependencies
23+
shell: bash
24+
run: pip install -r requirements_dev.txt
25+
26+
- name: Install the library
27+
shell: bash
28+
run: pip install .
29+
30+
- name: Run ruff
31+
shell: bash
32+
run: ruff check transfunctions
33+
34+
- name: Run ruff for tests
35+
shell: bash
36+
run: ruff check tests

.github/workflows/release.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
pypi-publish:
10+
name: upload release to PyPI
11+
runs-on: ubuntu-latest
12+
# Specifying a GitHub environment is optional, but strongly encouraged
13+
environment: release
14+
permissions:
15+
# IMPORTANT: this permission is mandatory for trusted publishing
16+
id-token: write
17+
steps:
18+
- uses: actions/checkout@v2
19+
20+
- name: Set up Python ${{ matrix.python-version }}
21+
uses: actions/setup-python@v1
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install dependencies
26+
shell: bash
27+
run: pip install -r requirements_dev.txt
28+
29+
- name: Build the project
30+
shell: bash
31+
run: python -m build .
32+
33+
- name: Publish package distributions to PyPI
34+
uses: pypa/gh-action-pypi-publish@release/v1
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Tests
2+
3+
on:
4+
push
5+
6+
jobs:
7+
build:
8+
9+
runs-on: ${{ matrix.os }}
10+
strategy:
11+
matrix:
12+
os: [macos-latest, ubuntu-latest, windows-latest]
13+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v3
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install the library
23+
shell: bash
24+
run: pip install .
25+
26+
- name: Install dependencies
27+
shell: bash
28+
run: pip install -r requirements_dev.txt
29+
30+
- name: Print all libs
31+
shell: bash
32+
run: pip list
33+
34+
- name: Run tests and show coverage on the command line
35+
run: |
36+
coverage run --source=transfunctions --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=90
37+
coverage xml
38+
39+
- name: Upload coverage to Coveralls
40+
if: runner.os == 'Linux'
41+
env:
42+
COVERALLS_REPO_TOKEN: ${{secrets.COVERALLS_REPO_TOKEN}}
43+
uses: coverallsapp/github-action@v2
44+
with:
45+
format: cobertura
46+
file: coverage.xml
47+
48+
- name: Run tests and show the branch coverage on the command line
49+
run: coverage run --branch --source=transfunctions --omit="*tests*" -m pytest --cache-clear --assert=plain && coverage report -m --fail-under=90

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
__pycache__
2+
.pytest_cache
3+
.DS_Store
4+
test.py
5+
*.egg-info
6+
dist
7+
venv
8+
build
9+
.ruff_cache
10+
.mypy_cache
11+
.coverage

.ruff.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lint.ignore = ['E501', 'E712']

README.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,76 @@
1-
# transfunctions
1+
# transfunctions
2+
3+
[![Downloads](https://static.pepy.tech/badge/transfunctions/month)](https://pepy.tech/project/transfunctions)
4+
[![Downloads](https://static.pepy.tech/badge/transfunctions)](https://pepy.tech/project/transfunctions)
5+
[![Coverage Status](https://coveralls.io/repos/github/pomponchik/transfunctions/badge.svg?branch=main)](https://coveralls.io/github/pomponchik/transfunctions?branch=develop)
6+
[![Lines of code](https://sloc.xyz/github/pomponchik/transfunctions/?category=code)](https://github.com/boyter/scc/)
7+
[![Hits-of-Code](https://hitsofcode.com/github/pomponchik/transfunctions?branch=main)](https://hitsofcode.com/github/pomponchik/transfunctions/view?branch=main)
8+
[![Test-Package](https://github.com/pomponchik/transfunctions/actions/workflows/tests_and_coverage.yml/badge.svg)](https://github.com/pomponchik/transfunctions/actions/workflows/tests_and_coverage.yml)
9+
[![Python versions](https://img.shields.io/pypi/pyversions/transfunctions.svg)](https://pypi.python.org/pypi/transfunctions)
10+
[![PyPI version](https://badge.fury.io/py/transfunctions.svg)](https://badge.fury.io/py/transfunctions)
11+
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](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

Comments
 (0)