Skip to content

Commit c637f2b

Browse files
author
esblinov
committed
returns check for superfunctions
1 parent 6ad6949 commit c637f2b

3 files changed

Lines changed: 28 additions & 8 deletions

File tree

transfunctions/decorators/superfunction.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
from transfunctions.transformer import FunctionTransformer
2-
from inspect import currentframe
3-
4-
51
import sys
62
import weakref
7-
3+
from ast import NodeTransformer, Expr, AST
4+
from inspect import currentframe
85
from functools import wraps
9-
from typing import Dict, Any
6+
from typing import Dict, Any, Optional, Union, List
107
from collections.abc import Coroutine
118

129
if sys.version_info <= (3, 10): # pragma: no cover
@@ -16,6 +13,9 @@
1613

1714
from displayhooks import not_display
1815

16+
from transfunctions.transformer import FunctionTransformer
17+
from transfunctions.errors import WrongTransfunctionSyntaxError
18+
1919

2020
if sys.version_info <= (3, 9): # pragma: no cover
2121
CoroutineClass = Coroutine
@@ -55,7 +55,16 @@ async def async_sleep_option(flags: Dict[str, bool], args, kwargs, transformer)
5555
not_display(UsageTracer)
5656

5757
def superfunction(function):
58-
transformer = FunctionTransformer(function, currentframe().f_back.f_lineno, 'superfunction')
58+
class NoReturns(NodeTransformer):
59+
def visit_Return(self, node: Expr) -> Optional[Union[AST, List[AST]]]:
60+
raise WrongTransfunctionSyntaxError('A superfunction cannot contain a return statement.')
61+
62+
transformer = FunctionTransformer(
63+
function,
64+
currentframe().f_back.f_lineno,
65+
'superfunction',
66+
extra_transformers=[NoReturns()],
67+
)
5968

6069
@wraps(function)
6170
def wrapper(*args, **kwargs):

transfunctions/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ class DualUseOfDecoratorError(SyntaxError):
88

99
class WrongDecoratorSyntaxError(SyntaxError):
1010
pass
11+
12+
13+
class WrongTransfunctionSyntaxError(SyntaxError):
14+
pass

transfunctions/transformer.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
class FunctionTransformer:
15-
def __init__(self, function: Callable, decorator_lineno: int, decorator_name: str) -> None:
15+
def __init__(self, function: Callable, decorator_lineno: int, decorator_name: str, extra_transformers: Optional[List[NodeTransformer]] = None) -> None:
1616
if isinstance(function, type(self)):
1717
raise DualUseOfDecoratorError(f"You cannot use the '{decorator_name}' decorator twice for the same function.")
1818
if not isfunction(function):
@@ -25,6 +25,7 @@ def __init__(self, function: Callable, decorator_lineno: int, decorator_name: st
2525
self.function = function
2626
self.decorator_lineno = decorator_lineno
2727
self.decorator_name = decorator_name
28+
self.extra_transformers = extra_transformers
2829
self.base_object = None
2930
self.cache = {}
3031

@@ -105,6 +106,12 @@ def extract_context(self, context_name: str, addictional_transformers: Optional[
105106
except OSError:
106107
source_code = dill_getsource(self.function)
107108

109+
if addictional_transformers is None:
110+
addictional_transformers = self.extra_transformers
111+
else:
112+
if self.extra_transformers is not None:
113+
addictional_transformers = addictional_transformers + self.extra_transformers
114+
108115
converted_source_code = self.clear_spaces_from_source_code(source_code)
109116
tree = parse(converted_source_code)
110117
original_function = self.function

0 commit comments

Comments
 (0)