Better error messages on invalid macro arguments
This commit is contained in:
parent
920b35f129
commit
f18007955d
19
hy/macros.py
19
hy/macros.py
@ -18,6 +18,7 @@
|
|||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
# DEALINGS IN THE SOFTWARE.
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from inspect import getargspec, formatargspec
|
||||||
from hy.models import replace_hy_obj, wrap_value
|
from hy.models import replace_hy_obj, wrap_value
|
||||||
from hy.models.expression import HyExpression
|
from hy.models.expression import HyExpression
|
||||||
from hy.models.string import HyString
|
from hy.models.string import HyString
|
||||||
@ -122,6 +123,16 @@ def load_macros(module_name):
|
|||||||
_import(module)
|
_import(module)
|
||||||
|
|
||||||
|
|
||||||
|
def make_emtpy_fn_copy(fn):
|
||||||
|
argspec = getargspec(fn)
|
||||||
|
formatted_args = formatargspec(*argspec)
|
||||||
|
fn_str = 'lambda {}: None'.format(
|
||||||
|
formatted_args.lstrip('(').rstrip(')'))
|
||||||
|
|
||||||
|
empty_fn = eval(fn_str)
|
||||||
|
return empty_fn
|
||||||
|
|
||||||
|
|
||||||
def macroexpand(tree, module_name):
|
def macroexpand(tree, module_name):
|
||||||
"""Expand the toplevel macros for the `tree`.
|
"""Expand the toplevel macros for the `tree`.
|
||||||
|
|
||||||
@ -155,6 +166,14 @@ def macroexpand_1(tree, module_name):
|
|||||||
if m is None:
|
if m is None:
|
||||||
m = _hy_macros[None].get(fn)
|
m = _hy_macros[None].get(fn)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
|
try:
|
||||||
|
m_copy = make_emtpy_fn_copy(m)
|
||||||
|
m_copy(*ntree[1:])
|
||||||
|
except TypeError as e:
|
||||||
|
msg = "expanding `" + str(tree[0]) + "': "
|
||||||
|
msg += str(e).replace("<lambda>()", "", 1).strip()
|
||||||
|
raise HyMacroExpansionError(tree, msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
obj = wrap_value(m(*ntree[1:]))
|
obj = wrap_value(m(*ntree[1:]))
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from hy.models.string import HyString
|
|||||||
from hy.models.list import HyList
|
from hy.models.list import HyList
|
||||||
from hy.models.symbol import HySymbol
|
from hy.models.symbol import HySymbol
|
||||||
from hy.models.expression import HyExpression
|
from hy.models.expression import HyExpression
|
||||||
|
from hy.errors import HyMacroExpansionError
|
||||||
|
|
||||||
|
|
||||||
@macro("test")
|
@macro("test")
|
||||||
@ -35,3 +36,13 @@ def test_preprocessor_expression():
|
|||||||
obj = HyList([HyString("one"), HyString("two")])
|
obj = HyList([HyString("one"), HyString("two")])
|
||||||
obj = tokenize('(shill ["one" "two"])')[0][1]
|
obj = tokenize('(shill ["one" "two"])')[0][1]
|
||||||
assert obj == macroexpand(obj, '')
|
assert obj == macroexpand(obj, '')
|
||||||
|
|
||||||
|
|
||||||
|
def test_preprocessor_exceptions():
|
||||||
|
""" Test that macro expansion raises appropriate exceptions"""
|
||||||
|
try:
|
||||||
|
macroexpand(tokenize('(defn)')[0], __name__)
|
||||||
|
assert False
|
||||||
|
except HyMacroExpansionError as e:
|
||||||
|
assert "_hy_anon_fn_" not in str(e)
|
||||||
|
assert "TypeError" not in str(e)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user