Created
October 18, 2021 13:34
-
-
Save Ricyteach/b290849da903135a1ed5cce9b161b8c9 to your computer and use it in GitHub Desktop.
Proof of concept for an API providing more "English-like" function calls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Proof of concept for an API providing "English-like" function calls. | |
See original python-ideas [thread](https://mail.python.org/archives/list/[email protected]/thread/YMFRX6K22TZNNAP2PPVV7RGNI5HLC764/#WF232SOAJJWM33ZAY327OAPCONFOUXVX). | |
API: | |
``` | |
from curry_helper import curry_helper | |
# apply the curry_helper decorator with a list of function "suffixes" | |
# each argument after the first argument corresponds to a single suffix | |
@curry_helper(suffixes=["a", "b"] | |
def f(x, y, z): | |
... # TODO | |
f(x).a(y).b(z) | |
``` | |
""" | |
from functools import partial | |
from inspect import signature | |
def curry_helper(func=None, *, suffixes): | |
if func is None: | |
return partial(curry_helper, suffixes=suffixes) | |
return CurryHelper(func, suffixes) | |
class CurryHelper: | |
def __init__(self, func, suffixes): | |
self._func = func | |
self._nparams = len(signature(func).parameters) | |
self._suffixes = set(suffixes) | |
if self._nparams-1 != len(self._suffixes): | |
raise Exception("the number of suffixes must match the number of function arguments, less 1") | |
def __getattr__(self, attr): | |
... # TODO | |
def __call__(self, arg=None): | |
return CalledCurryHelper(self, arg) | |
class CalledCurryHelper: | |
def __init__(self, curry_helper, arg): | |
self._args = [arg] | |
self._curry_helper = curry_helper | |
def __call__(self, arg): | |
self._args.append(arg) | |
if len(self._args)==self._curry_helper._nparams: | |
return self._curry_helper._func(*self._args) | |
return self | |
def __getattr__(self, attr): | |
if attr in self._curry_helper._suffixes: | |
return self | |
raise AttributeError(f"{type(self).__name__!r} object has no attribute {attr!r}") | |
if __name__=="__main__": | |
from typing import Any | |
@curry_helper(suffixes=["into"]) | |
def insert(x: Any, y: list): | |
y.append(x) | |
item = 1 | |
container = [] | |
insert(item).into(container) | |
assert container == [item] | |
@curry_helper(suffixes=["an_instance_of_"]) | |
def is_(obj, cls): | |
return isinstance(obj, cls) | |
obj = 1 | |
assert is_(obj).an_instance_of_(int) | |
@curry_helper(suffixes=["a", "b"]) | |
def f(x, y, z): | |
... # TODO | |
x,y,z = None,None,None | |
assert f(x).a(y).b(z) is None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment