mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
have functor
This commit is contained in:
parent
67b6d2abe9
commit
037b9e002b
2 changed files with 104 additions and 7 deletions
|
@ -274,3 +274,67 @@ def test_functor_oneline_onecall_both():
|
||||||
yield from block_checks_glb('f', glbs, body, {'x': 86})
|
yield from block_checks_glb('f', glbs, body, {'x': 86})
|
||||||
|
|
||||||
|
|
||||||
|
XA_WITH = ('x = [1]\n'
|
||||||
|
'with Functor() as f:\n'
|
||||||
|
'{body}'
|
||||||
|
'x.append(2)\n'
|
||||||
|
'{calls}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_functor_oneline_append():
|
||||||
|
body = ' x.append(3)\n'
|
||||||
|
calls = 'f()\n'
|
||||||
|
s = XA_WITH.format(body=body, calls=calls)
|
||||||
|
glbs = {'Functor': Functor}
|
||||||
|
check_exec(s, glbs=glbs, locs=None)
|
||||||
|
yield from block_checks_glb('f', glbs, body, {'x': [1, 2, 3]})
|
||||||
|
|
||||||
|
|
||||||
|
def test_functor_return():
|
||||||
|
body = ' x = 42\n'
|
||||||
|
t = ('res = 0\n'
|
||||||
|
'with Functor(rtn="x") as f:\n'
|
||||||
|
'{body}\n'
|
||||||
|
'res = f()\n')
|
||||||
|
s = t.format(body=body)
|
||||||
|
glbs = {'Functor': Functor}
|
||||||
|
check_exec(s, glbs=glbs, locs=None)
|
||||||
|
yield from block_checks_glb('f', glbs, body, {'res': 42})
|
||||||
|
|
||||||
|
|
||||||
|
def test_functor_args():
|
||||||
|
body = ' x = 42 + a\n'
|
||||||
|
t = ('res = 0\n'
|
||||||
|
'with Functor(args=("a",), rtn="x") as f:\n'
|
||||||
|
'{body}\n'
|
||||||
|
'res = f(2)\n')
|
||||||
|
s = t.format(body=body)
|
||||||
|
glbs = {'Functor': Functor}
|
||||||
|
check_exec(s, glbs=glbs, locs=None)
|
||||||
|
yield from block_checks_glb('f', glbs, body, {'res': 44})
|
||||||
|
|
||||||
|
|
||||||
|
def test_functor_kwargs():
|
||||||
|
body = ' x = 42 + a + b\n'
|
||||||
|
t = ('res = 0\n'
|
||||||
|
'with Functor(kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
|
||||||
|
'{body}\n'
|
||||||
|
'res = f(b=6)\n')
|
||||||
|
s = t.format(body=body)
|
||||||
|
glbs = {'Functor': Functor}
|
||||||
|
check_exec(s, glbs=glbs, locs=None)
|
||||||
|
yield from block_checks_glb('f', glbs, body, {'res': 49})
|
||||||
|
|
||||||
|
|
||||||
|
def test_functor_fullsig():
|
||||||
|
body = ' x = 42 + a + b + c\n'
|
||||||
|
t = ('res = 0\n'
|
||||||
|
'with Functor(args=("c",), kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
|
||||||
|
'{body}\n'
|
||||||
|
'res = f(55)\n')
|
||||||
|
s = t.format(body=body)
|
||||||
|
glbs = {'Functor': Functor}
|
||||||
|
check_exec(s, glbs=glbs, locs=None)
|
||||||
|
yield from block_checks_glb('f', glbs, body, {'res': 110})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Context management tools for xonsh."""
|
"""Context management tools for xonsh."""
|
||||||
import sys
|
import sys
|
||||||
import builtins
|
import builtins
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from xonsh.tools import XonshBlockError
|
from xonsh.tools import XonshBlockError
|
||||||
|
|
||||||
|
@ -43,8 +44,17 @@ class Functor(Block):
|
||||||
object, bound to the execution context it was created in.
|
object, bound to the execution context it was created in.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, args=(), kwargs=None, rtn=''):
|
||||||
"""
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
args : Sequence of str, optional
|
||||||
|
A tuple of argument names for the functor.
|
||||||
|
kwargs : Mapping of str to values or list of item tuples, optional
|
||||||
|
Keyword argument names and values, if available.
|
||||||
|
rtn : str, optional
|
||||||
|
Name of object to return, if available.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
func : function
|
func : function
|
||||||
|
@ -53,6 +63,14 @@ class Functor(Block):
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.func = None
|
self.func = None
|
||||||
|
self.args = args
|
||||||
|
if kwargs is None:
|
||||||
|
self.kwargs = []
|
||||||
|
elif isinstance(kwargs, Mapping):
|
||||||
|
self.kwargs = sorted(kwargs.items())
|
||||||
|
else:
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.rtn = rtn
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
super().__enter__()
|
super().__enter__()
|
||||||
|
@ -60,14 +78,27 @@ class Functor(Block):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
rtn = super().__exit__(exc_type, exc_value, traceback)
|
res = super().__exit__(exc_type, exc_value, traceback)
|
||||||
if not rtn:
|
if not res:
|
||||||
return rtn
|
return res
|
||||||
body = '\n'.join(self.lines)
|
body = '\n'.join(self.lines)
|
||||||
uid = hash(body) + sys.maxsize # should always be a positive int
|
uid = hash(body) + sys.maxsize # should always be a positive int
|
||||||
name = '__xonsh_functor_{uid}__'.format(uid=uid)
|
name = '__xonsh_functor_{uid}__'.format(uid=uid)
|
||||||
fstr = 'def {name}():\n{body}\n'
|
# construct signature string
|
||||||
fstr = fstr.format(name=name, body=body)
|
sig = rtn = ''
|
||||||
|
sig = ', '.join(self.args)
|
||||||
|
kwstr = ', '.join([k + '=None' for k, _ in self.kwargs])
|
||||||
|
if len(kwstr) > 0:
|
||||||
|
sig = kwstr if len(sig) == 0 else sig + ', ' + kwstr
|
||||||
|
# construct return string
|
||||||
|
rtn = str(self.rtn)
|
||||||
|
if len(rtn) > 0:
|
||||||
|
line0 = self.lines[0]
|
||||||
|
ws = line0[:-len(line0.lstrip())]
|
||||||
|
rtn = ws + 'return ' + rtn + '\n'
|
||||||
|
# construct function string
|
||||||
|
fstr = 'def {name}({sig}):\n{body}\n{rtn}'
|
||||||
|
fstr = fstr.format(name=name, sig=sig, body=body, rtn=rtn)
|
||||||
glbs = self.glbs
|
glbs = self.glbs
|
||||||
locs = self.locs
|
locs = self.locs
|
||||||
#locs = glbs if self.locs is None else self.locs
|
#locs = glbs if self.locs is None else self.locs
|
||||||
|
@ -79,8 +110,10 @@ class Functor(Block):
|
||||||
func = glbs[name]
|
func = glbs[name]
|
||||||
else:
|
else:
|
||||||
raise exc_value
|
raise exc_value
|
||||||
|
if len(self.kwargs) > 0:
|
||||||
|
func.__defaults__ = tuple(v for _, v in self.kwargs)
|
||||||
self.func = func
|
self.func = func
|
||||||
return rtn
|
return res
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
"""Dispatches to func."""
|
"""Dispatches to func."""
|
||||||
|
|
Loading…
Add table
Reference in a new issue