From 216c341b068c27e2689c95c0d70dd914feb0d00a Mon Sep 17 00:00:00 2001 From: Erez Shinan Date: Tue, 16 Oct 2018 14:19:47 +0300 Subject: [PATCH] Fixed v_args handling of staticmethod and classmethod (Issue #246, #249) --- lark/visitors.py | 9 +++++++-- tests/test_trees.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lark/visitors.py b/lark/visitors.py index 4bc3866d..ad343273 100644 --- a/lark/visitors.py +++ b/lark/visitors.py @@ -69,6 +69,8 @@ def _apply_decorator(cls, decorator, **kwargs): if name.startswith('_') or name in libmembers: continue + if isinstance(cls.__dict__[name], (staticmethod, classmethod)): + kwargs['static'] = True setattr(cls, name, decorator(value, **kwargs)) return cls @@ -225,7 +227,7 @@ def inline_args(obj): # XXX Deprecated -def _visitor_args_func_dec(func, inline=False, meta=False, whole_tree=False): +def _visitor_args_func_dec(func, inline=False, meta=False, whole_tree=False, static=False): assert [whole_tree, meta, inline].count(True) <= 1 def create_decorator(_f, with_self): if with_self: @@ -236,7 +238,10 @@ def f(self, *args, **kwargs): return _f(*args, **kwargs) return f - f = smart_decorator(func, create_decorator) + if static: + f = wraps(func)(create_decorator(func, False)) + else: + f = smart_decorator(func, create_decorator) f.inline = inline f.meta = meta f.whole_tree = whole_tree diff --git a/tests/test_trees.py b/tests/test_trees.py index 1debd894..564d02ba 100644 --- a/tests/test_trees.py +++ b/tests/test_trees.py @@ -97,6 +97,25 @@ class T(Transformer): res = T().transform(t) self.assertEqual(res, 2.9) + def test_vargs(self): + @v_args() + class MyTransformer(Transformer): + @staticmethod + def integer(args): + return 1 # some code here + + @classmethod + def integer2(cls, args): + return 2 # some code here + + hello = staticmethod(lambda args: 'hello') + + x = MyTransformer().transform( Tree('integer', [2])) + self.assertEqual(x, 1) + x = MyTransformer().transform( Tree('integer2', [2])) + self.assertEqual(x, 2) + x = MyTransformer().transform( Tree('hello', [2])) + self.assertEqual(x, 'hello') if __name__ == '__main__':