15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.TestUtils import CythonTest
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import Cython.Compiler.Errors as Errors
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.Nodes import *
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.ParseTreeTransforms import *
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from Cython.Compiler.Buffer import *
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TestBufferParsing(CythonTest):
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # First, we only test the raw parser, i.e.
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # the number and contents of arguments are NOT checked.
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # However "dtype"/the first positional argument is special-cased
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    #  to parse a type argument rather than an expression
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def parse(self, s):
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        return self.should_not_fail(lambda: self.fragment(s)).root
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def not_parseable(self, expected_error, s):
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        e = self.should_fail(lambda: self.fragment(s),  Errors.CompileError)
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(expected_error, e.message_only)
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_basic(self):
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        t = self.parse(u"cdef object[float, 4, ndim=2, foo=foo] x")
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        bufnode = t.stats[0].base_type
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(isinstance(bufnode, TemplatedTypeNode))
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(2, len(bufnode.positional_args))
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#        print bufnode.dump()
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # should put more here...
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_type_pos(self):
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.parse(u"cdef object[short unsigned int, 3] x")
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_type_keyword(self):
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.parse(u"cdef object[foo=foo, dtype=short unsigned int] x")
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def test_pos_after_key(self):
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.not_parseable("Non-keyword arg following keyword arg",
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           u"cdef object[foo=1, 2] x")
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# See also tests/error/e_bufaccess.pyx and tets/run/bufaccess.pyx
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# THESE TESTS ARE NOW DISABLED, the code they test was pretty much
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# refactored away
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TestBufferOptions(CythonTest):
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # Tests the full parsing of the options within the brackets
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def nonfatal_error(self, error):
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        # We're passing self as context to transform to trap this
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.error = error
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(self.expect_error)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def parse_opts(self, opts, expect_error=False):
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        assert opts != ""
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        s = u"def f():\n  cdef object[%s] x" % opts
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.expect_error = expect_error
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        root = self.fragment(s, pipeline=[NormalizeTree(self), PostParse(self)]).root
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if not expect_error:
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            vardef = root.stats[0].body.stats[0]
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            assert isinstance(vardef, CVarDefNode) # use normal assert as this is to validate the test code
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            buftype = vardef.base_type
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.assert_(isinstance(buftype, TemplatedTypeNode))
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.assert_(isinstance(buftype.base_type_node, CSimpleBaseTypeNode))
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.assertEqual(u"object", buftype.base_type_node.name)
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            return buftype
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        else:
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            self.assert_(len(root.stats[0].body.stats) == 0)
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def non_parse(self, expected_err, opts):
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.parse_opts(opts, expect_error=True)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#        e = self.should_fail(lambda: self.parse_opts(opts))
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(expected_err, self.error.message_only)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __test_basic(self):
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        buf = self.parse_opts(u"unsigned short int, 3")
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(3, buf.ndim)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __test_dict(self):
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        buf = self.parse_opts(u"ndim=3, dtype=unsigned short int")
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode))
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1)
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assertEqual(3, buf.ndim)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __test_ndim(self):
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.parse_opts(u"int, 2")
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.non_parse(ERR_BUF_NDIM, u"int, 'a'")
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.non_parse(ERR_BUF_NDIM, u"int, -34")
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    def __test_use_DEF(self):
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        t = self.fragment(u"""
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        DEF ndim = 3
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        def f():
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cdef object[int, ndim] x
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            cdef object[ndim=ndim, dtype=int] y
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        """, pipeline=[NormalizeTree(self), PostParse(self)]).root
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        stats = t.stats[0].body.stats
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(stats[0].base_type.ndim == 3)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.assert_(stats[1].base_type.ndim == 3)
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    # add exotic and impossible combinations as they come along...
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)if __name__ == '__main__':
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    import unittest
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    unittest.main()
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
106