import types

from data import Data
from data.decorators import auto_instantiate, annotate, data

import pytest


# based on https://stackoverflow.com/questions/6527633
#          /how-can-i-make-a-deepcopy-of-a-function-in-python
# fixed for python 3 support
def copy_func(f, name=None):
    return types.FunctionType(f.__code__, f.__globals__, name or f.__name__,
                              f.__defaults__, f.__closure__)


def sample_func(a, b, *c, **d):
    return (a, b, c, d)


@pytest.fixture
def decfunc_all():
    f = copy_func(sample_func)
    f = annotate(a=int, b=str)(f)
    f = auto_instantiate()(f)
    return f


@pytest.fixture
def decfunc_b():
    f = copy_func(sample_func)
    f = annotate(b=str)(f)
    f = auto_instantiate()(f)
    return f


@pytest.fixture
def decfunc_int():
    f = copy_func(sample_func)
    f = annotate(a=int, b=str)(f)
    f = auto_instantiate(int)(f)
    return f


@pytest.fixture
def decfunc_data():
    f = copy_func(sample_func)
    return data('b')(f)


def test_auto_instantiation(decfunc_all):
    assert (3, '4', (), {}) == decfunc_all(3.5, 4)


def test_partial_auto_instantiation_b(decfunc_b):
    assert (3.5, '4', (), {}) == decfunc_b(3.5, 4)


def test_partial_auto_instantiation_int(decfunc_int):
    assert (3, 4, (), {}) == decfunc_int(3.5, 4)


def test_data_decorator(decfunc_data):
    a, b, c, d = decfunc_data('hello', 'world')

    assert isinstance(b, Data)
    assert not isinstance(a, Data)

@@ -536,34 +536,49 @@
 func(sample_func
+, 'decfunc_all'
 )%0A
-
     f = annotate
@@ -694,32 +694,45 @@
 func(sample_func
+, 'decfunc_b'
 )%0A    f = annota
@@ -849,24 +849,39 @@
 (sample_func
+, 'decfunc_int'
 )%0A    f = an
@@ -984,24 +984,24 @@
 unc_data():%0A
-
     f = copy
@@ -1017,16 +1017,32 @@
 ple_func
+, 'decfunc_data'
 )%0A    re

Set function name when copying functions.