| |
| 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_with_global_and_attr_same_name(): |
| try: |
| spam_minimal.spam_minimal |
| except AttributeError: |
| pass |
| |
| |
| 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_with_global_and_attr_same_name, |
| 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_with_global_and_attr_same_name, |
| 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, |
| spam_with_global_and_attr_same_name, |
| ] |
| |
| |
| # 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? |
| ] |