Skip to content

Instantly share code, notes, and snippets.

@Ricyteach
Created October 18, 2021 13:34
Show Gist options
  • Save Ricyteach/b290849da903135a1ed5cce9b161b8c9 to your computer and use it in GitHub Desktop.
Save Ricyteach/b290849da903135a1ed5cce9b161b8c9 to your computer and use it in GitHub Desktop.
Proof of concept for an API providing more "English-like" function calls
"""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