mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00

Since http://bugs.python.org/issue27999, global after use is a SyntaxError; reusing variable name in tests/test_contexts.py lead to failure. Should close #1718
339 lines
9.1 KiB
Python
339 lines
9.1 KiB
Python
"""Tests xonsh contexts."""
|
|
from tools import check_exec
|
|
from xonsh.contexts import Block, Functor
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
|
|
return xonsh_execer
|
|
|
|
#
|
|
# helpers
|
|
#
|
|
|
|
X1_WITH = ('x = 1\n'
|
|
'with Block() as b:\n')
|
|
SIMPLE_WITH = 'with Block() as b:\n'
|
|
FUNC_WITH = ('x = 1\n'
|
|
'def func():\n'
|
|
' y = 1\n'
|
|
' with Block() as b:\n'
|
|
'{body}'
|
|
' y += 1\n'
|
|
' return b\n'
|
|
'x += 1\n'
|
|
'rtn = func()\n'
|
|
'x += 1\n')
|
|
|
|
FUNC_OBSG = {'x': 3}
|
|
FUNC_OBSL = {'y': 1}
|
|
|
|
def block_checks_glb(name, glbs, body, obs=None):
|
|
block = glbs[name]
|
|
obs = obs or {}
|
|
for k, v in obs.items():
|
|
assert v == glbs[k]
|
|
if isinstance(body, str):
|
|
body = body.splitlines()
|
|
assert body == block.lines
|
|
assert glbs is block.glbs
|
|
assert block.locs is None
|
|
|
|
|
|
def block_checks_func(name, glbs, body, obsg=None, obsl=None):
|
|
block = glbs[name]
|
|
obsg = obsg or {}
|
|
for k, v in obsg.items():
|
|
assert v == glbs[k]
|
|
if isinstance(body, str):
|
|
body = body.splitlines()
|
|
assert body == block.lines
|
|
assert glbs is block.glbs
|
|
# local context tests
|
|
locs = block.locs
|
|
assert locs is not None
|
|
obsl = obsl or {}
|
|
for k, v in obsl.items():
|
|
assert v == locs[k]
|
|
|
|
|
|
#
|
|
# Block tests
|
|
#
|
|
|
|
def test_block_noexec():
|
|
s = ('x = 1\n'
|
|
'with Block():\n'
|
|
' x += 42\n')
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
assert 1 == glbs['x']
|
|
|
|
|
|
def test_block_oneline():
|
|
body = ' x += 42\n'
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body, {'x': 1})
|
|
|
|
|
|
def test_block_manylines():
|
|
body = (' ![echo wow mom]\n'
|
|
'# bad place for a comment\n'
|
|
' x += 42')
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body, {'x': 1})
|
|
|
|
|
|
def test_block_leading_comment():
|
|
# leading comments do not show up in block lines
|
|
body = (' # I am a leading comment\n'
|
|
' x += 42\n')
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
|
|
|
|
|
|
def test_block_trailing_comment():
|
|
# trailing comments do not show up in block lines
|
|
body = (' x += 42\n'
|
|
' # I am a trailing comment\n')
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
|
|
|
|
|
|
def test_block_trailing_line_continuation():
|
|
body = (' x += \\\n'
|
|
' 42\n')
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body, {'x': 1})
|
|
|
|
|
|
def test_block_trailing_close_paren():
|
|
body = (' x += int("42"\n'
|
|
' )\n')
|
|
s = X1_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body, {'x': 1})
|
|
|
|
|
|
def test_block_trailing_close_many():
|
|
body = (' x = {None: [int("42"\n'
|
|
' )\n'
|
|
' ]\n'
|
|
' }\n')
|
|
s = SIMPLE_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body)
|
|
|
|
|
|
def test_block_trailing_triple_string():
|
|
body = (' x = """This\n'
|
|
'is\n'
|
|
'"probably"\n'
|
|
'\'not\' what I meant.\n'
|
|
'"""\n')
|
|
s = SIMPLE_WITH + body
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('b', glbs, body)
|
|
|
|
|
|
def test_block_func_oneline():
|
|
body = ' x += 42\n'
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_manylines():
|
|
body = (' ![echo wow mom]\n'
|
|
'# bad place for a comment\n'
|
|
' x += 42\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_leading_comment():
|
|
# leading comments do not show up in block lines
|
|
body = (' # I am a leading comment\n'
|
|
' x += 42\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, ' x += 42\n',
|
|
FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_trailing_comment():
|
|
# trailing comments do not show up in block lines
|
|
body = (' x += 42\n'
|
|
' # I am a trailing comment\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, ' x += 42\n',
|
|
FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_blockfunc__trailing_line_continuation():
|
|
body = (' x += \\\n'
|
|
' 42\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_trailing_close_paren():
|
|
body = (' x += int("42"\n'
|
|
' )\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_trailing_close_many():
|
|
body = (' x = {None: [int("42"\n'
|
|
' )\n'
|
|
' ]\n'
|
|
' }\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
def test_block_func_trailing_triple_string():
|
|
body = (' x = """This\n'
|
|
'is\n'
|
|
'"probably"\n'
|
|
'\'not\' what I meant.\n'
|
|
'"""\n')
|
|
s = FUNC_WITH.format(body=body)
|
|
glbs = {'Block': Block}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
|
|
|
|
|
|
#
|
|
# Functor tests
|
|
#
|
|
|
|
X2_WITH = ('{var} = 1\n'
|
|
'with Functor() as f:\n'
|
|
'{body}'
|
|
'{var} += 1\n'
|
|
'{calls}\n'
|
|
)
|
|
|
|
def test_functor_oneline_onecall_class():
|
|
body = (' global y\n'
|
|
' y += 42\n')
|
|
calls = 'f()'
|
|
s = X2_WITH.format(body=body, calls=calls, var='y')
|
|
glbs = {'Functor': Functor}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('f', glbs, body, {'y': 44})
|
|
|
|
|
|
def test_functor_oneline_onecall_func():
|
|
body = (' global z\n'
|
|
' z += 42\n')
|
|
calls = 'f.func()'
|
|
s = X2_WITH.format(body=body, calls=calls, var='z')
|
|
glbs = {'Functor': Functor}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
block_checks_glb('f', glbs, body, {'z': 44})
|
|
|
|
|
|
def test_functor_oneline_onecall_both():
|
|
body = (' global x\n'
|
|
' x += 42\n')
|
|
calls = 'f()\nf.func()'
|
|
s = X2_WITH.format(body=body, calls=calls, var='x')
|
|
glbs = {'Functor': Functor}
|
|
check_exec(s, glbs=glbs, locs=None)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
block_checks_glb('f', glbs, body, {'res': 110})
|
|
|
|
|