Beispiel #1
0
    def test_empty_keywords(self):
        def f(**kwargs):
            assert False

        self.assertEqual(flatargs(f, (), {}), ({},))
        self.assertEqual(flatargs(f, (), {'a': 10}), ({'a': 10},))
        self.assertRaises(TypeError, flatargs, f, (1, 2, 3), {})
Beispiel #2
0
    def test_empty_keywords(self):
        def f(**kwargs):
            assert False

        self.assertEqual(flatargs(f, (), {}), ({}, ))
        self.assertEqual(flatargs(f, (), {'a': 10}), ({'a': 10}, ))
        self.assertRaises(TypeError, flatargs, f, (1, 2, 3), {})
Beispiel #3
0
    def test_empty_varargs(self):
        def f(*args):
            assert False

        self.assertEqual(flatargs(f, (), {}), ((),))
        self.assertEqual(flatargs(f, (1, 2, 3), {}), ((1, 2, 3),))
        self.assertRaises(TypeError, flatargs, f, (), {'a': 10})
Beispiel #4
0
    def test_empty_varargs(self):
        def f(*args):
            assert False

        self.assertEqual(flatargs(f, (), {}), ((), ))
        self.assertEqual(flatargs(f, (1, 2, 3), {}), ((1, 2, 3), ))
        self.assertRaises(TypeError, flatargs, f, (), {'a': 10})
Beispiel #5
0
    def test_all_the_above(self):
        def f(a, b=3, *args, **kwargs):
            assert False

        self.assertEqual(flatargs(f, (1,), {}), (1, 3, (), {}))
        self.assertEqual(flatargs(f, (1, 2), {}), (1, 2, (), {}))
        self.assertEqual(flatargs(f, (1,), {'b': 2}), (1, 2, (), {}))
        self.assertEqual(flatargs(f, (1, 2, 3, 4), {'d': 4}),
                         (1, 2, (3, 4), {'d': 4}))

        self.assertRaises(TypeError, flatargs(f, (1, 2, 3), {'b': 2, 'd': 4}))
Beispiel #6
0
    def test_args(self):
        def f(a, b):
            assert False

        self.assertEqual(flatargs(f, (1, 2), {}), (1, 2))
        self.assertEqual(flatargs(f, (1,), {'b': 2}), (1, 2))
        self.assertEqual(flatargs(f, (), {'a': 1, 'b': 2}), (1, 2))

        self.assertRaises(TypeError, flatargs, f, (1, 2, 3), {})
        self.assertRaises(TypeError, flatargs, f, (1,), {})
        self.assertRaises(TypeError, flatargs, f, (1, 2), {'b': 3})
        self.assertRaises(TypeError, flatargs, f, (), {'a': 1, 'b': 2, 'c': 3})
Beispiel #7
0
    def test_all_the_above(self):
        def f(a, b=3, *args, **kwargs):
            assert False

        self.assertEqual(flatargs(f, (1, ), {}), (1, 3, (), {}))
        self.assertEqual(flatargs(f, (1, 2), {}), (1, 2, (), {}))
        self.assertEqual(flatargs(f, (1, ), {'b': 2}), (1, 2, (), {}))
        self.assertEqual(flatargs(f, (1, 2, 3, 4), {'d': 4}), (1, 2, (3, 4), {
            'd': 4
        }))

        self.assertRaises(TypeError, flatargs(f, (1, 2, 3), {'b': 2, 'd': 4}))
Beispiel #8
0
    def test_args(self):
        def f(a, b):
            assert False

        self.assertEqual(flatargs(f, (1, 2), {}), (1, 2))
        self.assertEqual(flatargs(f, (1, ), {'b': 2}), (1, 2))
        self.assertEqual(flatargs(f, (), {'a': 1, 'b': 2}), (1, 2))

        self.assertRaises(TypeError, flatargs, f, (1, 2, 3), {})
        self.assertRaises(TypeError, flatargs, f, (1, ), {})
        self.assertRaises(TypeError, flatargs, f, (1, 2), {'b': 3})
        self.assertRaises(TypeError, flatargs, f, (), {'a': 1, 'b': 2, 'c': 3})
Beispiel #9
0
    def test_empty(self):
        def f():
            assert False

        self.assertEqual(flatargs(f, (), {}), ())
        self.assertRaises(TypeError, flatargs, f, (1,), {})
        self.assertRaises(TypeError, flatargs, f, (), {'a': 10})
Beispiel #10
0
    def test_empty(self):
        def f():
            assert False

        self.assertEqual(flatargs(f, (), {}), ())
        self.assertRaises(TypeError, flatargs, f, (1, ), {})
        self.assertRaises(TypeError, flatargs, f, (), {'a': 10})
Beispiel #11
0
    def __call__(self, *args, **kwargs):
        from flypy.representation import byref, stack_allocate
        from flypy.conversion import (toctypes, fromctypes, toobject,
                                      fromobject, ctype)
        #from flypy.support.ctypes_support import CTypesStruct
        #from flypy.types import Function

        # Keep this alive for the duration of the call
        keepalive = list(args) + list(kwargs.values())

        # Order arguments
        args = flatargs(self.py_func, args, kwargs)

        # Translate
        cfunc, restype = self.translate([typeof(x) for x in args.flat])

        # Construct flypy values
        argtypes = [typeof(x) for x in args]
        arg_objs = list(starmap(fromobject, zip(args, argtypes)))

        # Map flypy values to a ctypes representation
        args = []
        for arg, argtype in zip(arg_objs, argtypes):
            c_arg = toctypes(arg, argtype, keepalive)
            if byref(argtype) and stack_allocate(argtype):
                c_arg = ctypes.pointer(c_arg)
            args.append(c_arg)

        # We need this cast since the ctypes function constructed from LLVM
        # IR has different structs (which are structurally equivalent)
        c_restype = ctype(restype)
        if byref(restype):
            c_result = c_restype()  # dummy result value
            args.append(ctypes.pointer(c_result))
            c_restype = None  # void

        c_signature = ctypes.PYFUNCTYPE(c_restype,
                                        *[type(arg) for arg in args])
        cfunc = ctypes.cast(cfunc, c_signature)

        # Handle calling convention
        if byref(restype):
            cfunc(*args)
        else:
            c_result = cfunc(*args)

        # Map ctypes result back to a python value
        result = fromctypes(c_result, restype)
        result_obj = toobject(result, restype)

        return result_obj
Beispiel #12
0
    def __call__(self, *args, **kwargs):
        from flypy.representation import byref, stack_allocate
        from flypy.conversion import (
            toctypes, fromctypes, toobject, fromobject, ctype)
        #from flypy.support.ctypes_support import CTypesStruct
        #from flypy.types import Function

        # Keep this alive for the duration of the call
        keepalive = list(args) + list(kwargs.values())

        # Order arguments
        args = flatargs(self.py_func, args, kwargs)

        # Translate
        cfunc, restype = self.translate([typeof(x) for x in args.flat])

        # Construct flypy values
        argtypes = [typeof(x) for x in args]
        arg_objs = list(starmap(fromobject, zip(args, argtypes)))

        # Map flypy values to a ctypes representation
        args = []
        for arg, argtype in zip(arg_objs, argtypes):
            c_arg = toctypes(arg, argtype, keepalive)
            if byref(argtype) and stack_allocate(argtype):
                c_arg = ctypes.pointer(c_arg)
            args.append(c_arg)

        # We need this cast since the ctypes function constructed from LLVM
        # IR has different structs (which are structurally equivalent)
        c_restype = ctype(restype)
        if byref(restype):
            c_result = c_restype() # dummy result value
            args.append(ctypes.pointer(c_result))
            c_restype = None # void

        c_signature = ctypes.PYFUNCTYPE(c_restype, *[type(arg) for arg in args])
        cfunc = ctypes.cast(cfunc, c_signature)

        # Handle calling convention
        if byref(restype):
            cfunc(*args)
        else:
            c_result = cfunc(*args)

        # Map ctypes result back to a python value
        result = fromctypes(c_result, restype)
        result_obj = toobject(result, restype)

        return result_obj
Beispiel #13
0
def simplify_argtypes(func, env):
    """
    Simplify the argtypes for non-opaque functions:

        *args    -> tuple
        **kwargs -> dict
    """
    from flypy.compiler.signature import fill_missing_argtypes, flatargs

    argtypes = env["flypy.typing.argtypes"]

    if func.opaque:
        return argtypes

    # We make the simlifying assumption that `py_func` is the right overload,
    # which has not been determined yet. This means all overloads must have
    # the same types for defaults...
    py_func = func.py_func

    called_flags = env['flypy.state.called_flags']
    called_with_varargs = called_flags['varargs']
    called_with_keywords = called_flags['keywords']

    if called_with_varargs:
        argtypes = handle_unpacking_varargs(func, py_func, argtypes)
    else:
        # Fill out missing argtypes for defaults
        argtypes = fill_missing_argtypes(py_func, argtypes)

    # Handle varargs/keywords (*args, **kwargs)
    argtypes = flatargs(py_func, argtypes, {})
    result = list(argtypes)

    varargs, keywords = [], []
    if argtypes.have_keywords:
        #keywords = [result.pop()]
        raise TypeError("Keyword arguments are not yet supported")
    if argtypes.have_varargs:
        varargs = [make_tuple_type(result.pop())]

    argtypes = result + varargs + keywords
    #print(func, argtypes)
    return argtypes
Beispiel #14
0
def simplify_argtypes(func, env):
    """
    Simplify the argtypes for non-opaque functions:

        *args    -> tuple
        **kwargs -> dict
    """
    from flypy.compiler.signature import fill_missing_argtypes, flatargs

    argtypes = env["flypy.typing.argtypes"]

    if func.opaque:
        return argtypes

    # We make the simlifying assumption that `py_func` is the right overload,
    # which has not been determined yet. This means all overloads must have
    # the same types for defaults...
    py_func = func.py_func

    called_flags = env['flypy.state.called_flags']
    called_with_varargs = called_flags['varargs']
    called_with_keywords = called_flags['keywords']

    if called_with_varargs:
        argtypes = handle_unpacking_varargs(func, py_func, argtypes)
    else:
        # Fill out missing argtypes for defaults
        argtypes = fill_missing_argtypes(py_func, argtypes)

    # Handle varargs/keywords (*args, **kwargs)
    argtypes = flatargs(py_func, argtypes, {})
    result = list(argtypes)

    varargs, keywords = [], []
    if argtypes.have_keywords:
        #keywords = [result.pop()]
        raise TypeError("Keyword arguments are not yet supported")
    if argtypes.have_varargs:
        varargs = [make_tuple_type(result.pop())]

    argtypes = result + varargs + keywords
    #print(func, argtypes)
    return argtypes
Beispiel #15
0
    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if flags.get('varargs'):
            return

        # Retrieve any remaining arguments meant for *args
        flattened = flatargs(py_func, args, {})
        if flattened.have_varargs:
            b.position_before(op)
            #print(py_func, flattened.varargs)

            # -- Build the tuple -- #
            result = caller.apply_constructor(EmptyTuple)
            for item in flattened.varargs:
                result = caller.apply_constructor(StaticTuple,
                                                  args=[item, result])

            # -- Patch callsite -- #
            args = list(flattened.positional) + [result]
            op.set_args([f, args])
Beispiel #16
0
    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if flags.get('varargs'):
            return

        # Retrieve any remaining arguments meant for *args
        flattened = flatargs(py_func, args, {})
        if flattened.have_varargs:
            b.position_before(op)
            #print(py_func, flattened.varargs)

            # -- Build the tuple -- #
            result = caller.apply_constructor(EmptyTuple)
            for item in flattened.varargs:
                result = caller.apply_constructor(StaticTuple,
                                                  args=[item, result])

            # -- Patch callsite -- #
            args = list(flattened.positional) + [result]
            op.set_args([f, args])