Skip to content

Commit 501bb60

Browse files
authored
Merge pull request #3 from pomponchik/develop
0.0.3
2 parents 875c6d0 + 0cc2d20 commit 501bb60

File tree

4 files changed

+26
-25
lines changed

4 files changed

+26
-25
lines changed

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "transfunctions"
7-
version = "0.0.2"
7+
version = "0.0.3"
88
authors = [
99
{ name="Evgeniy Blinov", email="zheni-b@yandex.ru" },
1010
]
@@ -14,6 +14,7 @@ requires-python = ">=3.8"
1414
dependencies = [
1515
'displayhooks>=0.0.4',
1616
'dill==0.4.0',
17+
'typing_extensions ; python_version <= "3.10"',
1718
]
1819
classifiers = [
1920
"Operating System :: OS Independent",
@@ -37,6 +38,9 @@ keywords = [
3738
'async',
3839
'sync to async',
3940
'async to sync',
41+
'code generation',
42+
'ast manipulation',
43+
'magic',
4044
]
4145

4246
[tool.setuptools.package-data]

transfunctions/decorators/superfunction.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import sys
22
import weakref
3-
from ast import NodeTransformer, Expr, AST
3+
from ast import NodeTransformer, Return, AST
44
from inspect import currentframe
55
from functools import wraps
66
from typing import Dict, Any, Optional, Union, List
@@ -42,10 +42,7 @@ def __await__(self) -> Any: # pragma: no cover
4242
return self.coroutine.__await__()
4343

4444
def __invert__(self):
45-
print(self.finalizer)
46-
print(self.finalizer.alive)
4745
result = self.finalizer()
48-
print('result:', result)
4946
return result
5047

5148
def send(self, value: Any) -> Any:
@@ -73,7 +70,7 @@ async def async_sleep_option(flags: Dict[str, bool], args, kwargs, transformer)
7370

7471
def superfunction(function):
7572
class NoReturns(NodeTransformer):
76-
def visit_Return(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
73+
def visit_Return(self, node: Return) -> Optional[Union[AST, List[AST]]]:
7774
raise WrongTransfunctionSyntaxError('A superfunction cannot contain a return statement.')
7875

7976
transformer = FunctionTransformer(

transfunctions/markers.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
from typing import Any
1+
from typing import Any, NoReturn, Generator
22
from contextlib import contextmanager
33

44

55
@contextmanager
6-
def create_async_context():
7-
yield
6+
def create_async_context() -> Generator[NoReturn, None, None]:
7+
yield # type: ignore[misc] # pragma: no cover
88

99
@contextmanager
10-
def create_sync_context():
11-
yield
10+
def create_sync_context() -> Generator[NoReturn, None, None]:
11+
yield # type: ignore[misc] # pragma: no cover
1212

1313
@contextmanager
14-
def create_generator_context():
15-
yield
14+
def create_generator_context() -> Generator[NoReturn, None, None]:
15+
yield # type: ignore[misc] # pragma: no cover
1616

1717

1818
async_context = create_async_context()
1919
sync_context = create_sync_context()
2020
generator_context = create_generator_context()
2121

2222

23-
def await_it(some_expression: Any):
24-
pass
23+
def await_it(some_expression: Any) -> Any:
24+
pass # pragma: no cover

transfunctions/transformer.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from sys import version_info
2-
from typing import Optional, Union, List, Any
2+
from typing import Optional, Union, List, Dict, Any
33
from types import MethodType, FunctionType
44
from collections.abc import Callable
55
from inspect import isfunction, iscoroutinefunction, getsource, getfile
6-
from ast import parse, NodeTransformer, Expr, AST, FunctionDef, AsyncFunctionDef, increment_lineno, Await, Return, Name, Load, Assign, Constant, Store, arguments
6+
from ast import parse, NodeTransformer, AST, FunctionDef, AsyncFunctionDef, increment_lineno, Await, Call, With, Return, Name, Load, Assign, Constant, Store, arguments
77
from functools import wraps, update_wrapper
88

9-
from dill.source import getsource as dill_getsource
9+
from dill.source import getsource as dill_getsource # type: ignore[import-untyped]
1010

1111
from transfunctions.errors import CallTransfunctionDirectlyError, DualUseOfDecoratorError, WrongDecoratorSyntaxError
1212

@@ -27,7 +27,7 @@ def __init__(self, function: Callable, decorator_lineno: int, decorator_name: st
2727
self.decorator_name = decorator_name
2828
self.extra_transformers = extra_transformers
2929
self.base_object = None
30-
self.cache = {}
30+
self.cache: Dict[str, Callable] = {}
3131

3232
def __call__(self, *args: Any, **kwargs: Any) -> None:
3333
raise CallTransfunctionDirectlyError("You can't call a transfunction object directly, create a function, a generator function or a coroutine function from it.")
@@ -49,7 +49,7 @@ def get_async_function(self):
4949
original_function = self.function
5050

5151
class ConvertSyncFunctionToAsync(NodeTransformer):
52-
def visit_FunctionDef(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
52+
def visit_FunctionDef(self, node: FunctionDef) -> Optional[Union[AST, List[AST]]]:
5353
if node.name == original_function.__name__:
5454
return AsyncFunctionDef(
5555
name=original_function.__name__,
@@ -62,7 +62,7 @@ def visit_FunctionDef(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
6262
return node
6363

6464
class ExtractAwaitExpressions(NodeTransformer):
65-
def visit_Call(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
65+
def visit_Call(self, node: Call) -> Optional[Union[AST, List[AST]]]:
6666
if node.func.id == 'await_it':
6767
return Await(
6868
value=node.args[0],
@@ -102,7 +102,7 @@ def extract_context(self, context_name: str, addictional_transformers: Optional[
102102
if context_name in self.cache:
103103
return self.cache[context_name]
104104
try:
105-
source_code = getsource(self.function)
105+
source_code: str = getsource(self.function)
106106
except OSError:
107107
source_code = dill_getsource(self.function)
108108

@@ -119,15 +119,15 @@ def extract_context(self, context_name: str, addictional_transformers: Optional[
119119
decorator_name = self.decorator_name
120120

121121
class RewriteContexts(NodeTransformer):
122-
def visit_With(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
122+
def visit_With(self, node: With) -> Optional[Union[AST, List[AST]]]:
123123
if len(node.items) == 1 and node.items[0].context_expr.id == context_name:
124124
return node.body
125125
elif len(node.items) == 1 and node.items[0].context_expr.id != context_name and context_name in ('async_context', 'sync_context', 'generator_context'):
126126
return None
127127
return node
128128

129129
class DeleteDecorator(NodeTransformer):
130-
def visit_FunctionDef(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
130+
def visit_FunctionDef(self, node: FunctionDef) -> Optional[Union[AST, List[AST]]]:
131131
if node.name == original_function.__name__:
132132
nonlocal transfunction_decorator
133133
transfunction_decorator = None
@@ -161,7 +161,7 @@ def visit_FunctionDef(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
161161
increment_lineno(tree, n=(self.decorator_lineno - transfunction_decorator.lineno - 1))
162162

163163
code = compile(tree, filename=getfile(self.function), mode='exec')
164-
namespace = {}
164+
namespace: Dict[str, Callable] = {}
165165
exec(code, namespace)
166166
function_factory = namespace['wrapper']
167167
result = function_factory()

0 commit comments

Comments
 (0)