314 lines
5.9 KiB
Python
314 lines
5.9 KiB
Python
|
|
def simple_script():
|
|
assert True
|
|
|
|
|
|
def complex_script():
|
|
obj = 'a string'
|
|
pickle = __import__('pickle')
|
|
def spam_minimal():
|
|
pass
|
|
spam_minimal()
|
|
data = pickle.dumps(obj)
|
|
res = pickle.loads(data)
|
|
assert res == obj, (res, obj)
|
|
|
|
|
|
def script_with_globals():
|
|
obj1, obj2 = spam(42)
|
|
assert obj1 == 42
|
|
assert obj2 is None
|
|
|
|
|
|
def script_with_explicit_empty_return():
|
|
return None
|
|
|
|
|
|
def script_with_return():
|
|
return True
|
|
|
|
|
|
def spam_minimal():
|
|
# no arg defaults or kwarg defaults
|
|
# no annotations
|
|
# no local vars
|
|
# no free vars
|
|
# no globals
|
|
# no builtins
|
|
# no attr access (names)
|
|
# no code
|
|
return
|
|
|
|
|
|
def spam_with_builtins():
|
|
x = 42
|
|
values = (42,)
|
|
checks = tuple(callable(v) for v in values)
|
|
res = callable(values), tuple(values), list(values), checks
|
|
print(res)
|
|
|
|
|
|
def spam_with_globals_and_builtins():
|
|
func1 = spam
|
|
func2 = spam_minimal
|
|
funcs = (func1, func2)
|
|
checks = tuple(callable(f) for f in funcs)
|
|
res = callable(funcs), tuple(funcs), list(funcs), checks
|
|
print(res)
|
|
|
|
|
|
def spam_full_args(a, b, /, c, d, *args, e, f, **kwargs):
|
|
return (a, b, c, d, e, f, args, kwargs)
|
|
|
|
|
|
def spam_full_args_with_defaults(a=-1, b=-2, /, c=-3, d=-4, *args,
|
|
e=-5, f=-6, **kwargs):
|
|
return (a, b, c, d, e, f, args, kwargs)
|
|
|
|
|
|
def spam_args_attrs_and_builtins(a, b, /, c, d, *args, e, f, **kwargs):
|
|
if args.__len__() > 2:
|
|
return None
|
|
return a, b, c, d, e, f, args, kwargs
|
|
|
|
|
|
def spam_returns_arg(x):
|
|
return x
|
|
|
|
|
|
def spam_raises():
|
|
raise Exception('spam!')
|
|
|
|
|
|
def spam_with_inner_not_closure():
|
|
def eggs():
|
|
pass
|
|
eggs()
|
|
|
|
|
|
def spam_with_inner_closure():
|
|
x = 42
|
|
def eggs():
|
|
print(x)
|
|
eggs()
|
|
|
|
|
|
def spam_annotated(a: int, b: str, c: object) -> tuple:
|
|
return a, b, c
|
|
|
|
|
|
def spam_full(a, b, /, c, d:int=1, *args, e, f:object=None, **kwargs) -> tuple:
|
|
# arg defaults, kwarg defaults
|
|
# annotations
|
|
# all kinds of local vars, except cells
|
|
# no free vars
|
|
# some globals
|
|
# some builtins
|
|
# some attr access (names)
|
|
x = args
|
|
y = kwargs
|
|
z = (a, b, c, d)
|
|
kwargs['e'] = e
|
|
kwargs['f'] = f
|
|
extras = list((x, y, z, spam, spam.__name__))
|
|
return tuple(a, b, c, d, e, f, args, kwargs), extras
|
|
|
|
|
|
def spam(x):
|
|
return x, None
|
|
|
|
|
|
def spam_N(x):
|
|
def eggs_nested(y):
|
|
return None, y
|
|
return eggs_nested, x
|
|
|
|
|
|
def spam_C(x):
|
|
a = 1
|
|
def eggs_closure(y):
|
|
return None, y, a, x
|
|
return eggs_closure, a, x
|
|
|
|
|
|
def spam_NN(x):
|
|
def eggs_nested_N(y):
|
|
def ham_nested(z):
|
|
return None, z
|
|
return ham_nested, y
|
|
return eggs_nested_N, x
|
|
|
|
|
|
def spam_NC(x):
|
|
a = 1
|
|
def eggs_nested_C(y):
|
|
def ham_closure(z):
|
|
return None, z, y, a, x
|
|
return ham_closure, y
|
|
return eggs_nested_C, a, x
|
|
|
|
|
|
def spam_CN(x):
|
|
a = 1
|
|
def eggs_closure_N(y):
|
|
def ham_C_nested(z):
|
|
return None, z
|
|
return ham_C_nested, y, a, x
|
|
return eggs_closure_N, a, x
|
|
|
|
|
|
def spam_CC(x):
|
|
a = 1
|
|
def eggs_closure_C(y):
|
|
b = 2
|
|
def ham_C_closure(z):
|
|
return None, z, b, y, a, x
|
|
return ham_C_closure, b, y, a, x
|
|
return eggs_closure_C, a, x
|
|
|
|
|
|
eggs_nested, *_ = spam_N(1)
|
|
eggs_closure, *_ = spam_C(1)
|
|
eggs_nested_N, *_ = spam_NN(1)
|
|
eggs_nested_C, *_ = spam_NC(1)
|
|
eggs_closure_N, *_ = spam_CN(1)
|
|
eggs_closure_C, *_ = spam_CC(1)
|
|
|
|
ham_nested, *_ = eggs_nested_N(2)
|
|
ham_closure, *_ = eggs_nested_C(2)
|
|
ham_C_nested, *_ = eggs_closure_N(2)
|
|
ham_C_closure, *_ = eggs_closure_C(2)
|
|
|
|
|
|
TOP_FUNCTIONS = [
|
|
# shallow
|
|
simple_script,
|
|
complex_script,
|
|
script_with_globals,
|
|
script_with_explicit_empty_return,
|
|
script_with_return,
|
|
spam_minimal,
|
|
spam_with_builtins,
|
|
spam_with_globals_and_builtins,
|
|
spam_full_args,
|
|
spam_full_args_with_defaults,
|
|
spam_args_attrs_and_builtins,
|
|
spam_returns_arg,
|
|
spam_raises,
|
|
spam_with_inner_not_closure,
|
|
spam_with_inner_closure,
|
|
spam_annotated,
|
|
spam_full,
|
|
spam,
|
|
# outer func
|
|
spam_N,
|
|
spam_C,
|
|
spam_NN,
|
|
spam_NC,
|
|
spam_CN,
|
|
spam_CC,
|
|
]
|
|
NESTED_FUNCTIONS = [
|
|
# inner func
|
|
eggs_nested,
|
|
eggs_closure,
|
|
eggs_nested_N,
|
|
eggs_nested_C,
|
|
eggs_closure_N,
|
|
eggs_closure_C,
|
|
# inner inner func
|
|
ham_nested,
|
|
ham_closure,
|
|
ham_C_nested,
|
|
ham_C_closure,
|
|
]
|
|
FUNCTIONS = [
|
|
*TOP_FUNCTIONS,
|
|
*NESTED_FUNCTIONS,
|
|
]
|
|
|
|
STATELESS_FUNCTIONS = [
|
|
simple_script,
|
|
complex_script,
|
|
script_with_explicit_empty_return,
|
|
script_with_return,
|
|
spam,
|
|
spam_minimal,
|
|
spam_with_builtins,
|
|
spam_full_args,
|
|
spam_args_attrs_and_builtins,
|
|
spam_returns_arg,
|
|
spam_raises,
|
|
spam_annotated,
|
|
spam_with_inner_not_closure,
|
|
spam_with_inner_closure,
|
|
spam_N,
|
|
spam_C,
|
|
spam_NN,
|
|
spam_NC,
|
|
spam_CN,
|
|
spam_CC,
|
|
eggs_nested,
|
|
eggs_nested_N,
|
|
ham_nested,
|
|
ham_C_nested
|
|
]
|
|
STATELESS_CODE = [
|
|
*STATELESS_FUNCTIONS,
|
|
script_with_globals,
|
|
spam_full_args_with_defaults,
|
|
spam_with_globals_and_builtins,
|
|
spam_full,
|
|
]
|
|
|
|
PURE_SCRIPT_FUNCTIONS = [
|
|
simple_script,
|
|
complex_script,
|
|
script_with_explicit_empty_return,
|
|
spam_minimal,
|
|
spam_with_builtins,
|
|
spam_raises,
|
|
spam_with_inner_not_closure,
|
|
spam_with_inner_closure,
|
|
]
|
|
SCRIPT_FUNCTIONS = [
|
|
*PURE_SCRIPT_FUNCTIONS,
|
|
script_with_globals,
|
|
spam_with_globals_and_builtins,
|
|
]
|
|
|
|
|
|
# generators
|
|
|
|
def gen_spam_1(*args):
|
|
for arg in args:
|
|
yield arg
|
|
|
|
|
|
def gen_spam_2(*args):
|
|
yield from args
|
|
|
|
|
|
async def async_spam():
|
|
pass
|
|
coro_spam = async_spam()
|
|
coro_spam.close()
|
|
|
|
|
|
async def asyncgen_spam(*args):
|
|
for arg in args:
|
|
yield arg
|
|
asynccoro_spam = asyncgen_spam(1, 2, 3)
|
|
|
|
|
|
FUNCTION_LIKE = [
|
|
gen_spam_1,
|
|
gen_spam_2,
|
|
async_spam,
|
|
asyncgen_spam,
|
|
]
|
|
FUNCTION_LIKE_APPLIED = [
|
|
coro_spam, # actually FunctionType?
|
|
asynccoro_spam, # actually FunctionType?
|
|
]
|