15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.ModuleNode import ModuleNode
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.Symtab import ModuleScope
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.TestUtils import TransformTest
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.Visitor import MethodDispatcherTransform
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.ParseTreeTransforms import (
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NormalizeTree, AnalyseDeclarationsTransform,
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AnalyseExpressionsTransform, InterpretCompilerDirectives)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TestMethodDispatcherTransform(TransformTest):
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    _tree = None
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def _build_tree(self):
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if self._tree is None:
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            context = None
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            def fake_module(node):
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                scope = ModuleScope('test', None, None)
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return ModuleNode(node.pos, doc=None, body=node,
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  scope=scope, full_module_name='test',
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  directive_comments={})
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            pipeline = [
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                fake_module,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                NormalizeTree(context),
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                InterpretCompilerDirectives(context, {}),
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                AnalyseDeclarationsTransform(context),
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                AnalyseExpressionsTransform(context),
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            ]
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self._tree = self.run_pipeline(pipeline, u"""
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                cdef bytes s = b'asdfg'
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                cdef dict d = {1:2}
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                x = s * 3
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                d.get('test')
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            """)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return self._tree
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_builtin_method(self):
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        calls = [0]
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        class Test(MethodDispatcherTransform):
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            def _handle_simple_method_dict_get(self, node, func, args, unbound):
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                calls[0] += 1
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return node
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tree = self._build_tree()
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Test(None)(tree)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(1, calls[0])
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_binop_method(self):
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        calls = {'bytes': 0, 'object': 0}
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        class Test(MethodDispatcherTransform):
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            def _handle_simple_method_bytes___mul__(self, node, func, args, unbound):
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                calls['bytes'] += 1
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return node
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            def _handle_simple_method_object___mul__(self, node, func, args, unbound):
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                calls['object'] += 1
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                return node
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        tree = self._build_tree()
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        Test(None)(tree)
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(1, calls['bytes'])
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(0, calls['object'])
62