Ejemplo n.º 1
0
    def test_mapping_export(self):
        """Test `mapping` export"""

        if autowig.generator.plugin == 'pybind11_internal':
            os.environ['PYBIND11'] = "true"

        subprocess.check_call(
            [self.scons, 'cpp', '-c', '--prefix=' + self.prefix],
            cwd=self.srcdir)

        subprocess.check_call([self.scons, 'cpp', '--prefix=' + self.prefix],
                              cwd=self.srcdir)

        asg = autowig.AbstractSemanticGraph()

        if autowig.parser.plugin == 'libclang':
            kwargs = dict(silent=True)
        else:
            kwargs = dict()

        asg = autowig.parser(
            asg,
            self.incdir.files('*.h'),
            flags=['-x', 'c++', '-std=c++11', '-I' + str(self.incdir.parent)],
            **kwargs)

        autowig.controller.plugin = 'default'
        autowig.controller(asg)

        wrappers = autowig.generator(
            asg,
            module=self.srcdir / 'src' / 'py' / '__basic.cpp',
            decorator=self.srcdir / 'src' / 'py' / 'basic' / '_basic.py',
            prefix='wrapper_')
        wrappers.write()

        subprocess.check_call(
            [self.scons, 'py', '-c', '--prefix=' + self.prefix],
            cwd=self.srcdir)
        subprocess.check_call(
            [self.scons, 'py', '--prefix=' + self.prefix, '--package=basic'],
            cwd=self.srcdir)

        if autowig.generator.plugin == 'pybind11_internal':
            subprocess.check_call(['nosetests', 'test', '--pdb', '-v'],
                                  cwd=self.srcdir)

        for filepath in (self.srcdir / 'src' / 'py').walkfiles():
            if filepath.exists() and filepath.ext in ['.cpp', '.h']:
                filepath.remove()
Ejemplo n.º 2
0
def controller(asg):
    autowig.controller.plugin = 'default'
    asg = autowig.controller(asg)
    # for function in asg['::statiskit::stl'].functions():
    #     if function.localname in ['generator', 'insert']:
    #         parameter = function.parameters[0].qualified_type.desugared_type
    #         if parameter.is_class:
    #             function.parent = parameter.unqualified_type
    for cls in asg['class ::std::vector'].specializations(partial=False):
        for method in cls.methods():
            if method.localname in ['resize', 'shrink_to_fit', 'operator[]']:
                if isinstance(method.boost_python_export, bool):
                    method.boost_python_export = False
        for constructor in cls.constructors():
            if not (constructor.nb_parameters == 0
                    or constructor.nb_parameters == 1 and
                    constructor.parameters[0].qualified_type.unqualified_type
                    == cls):
                if isinstance(constructor.boost_python_export, bool):
                    constructor.boost_python_export = False
    # for cls in asg['class ::std::set'].specializations(partial = False):
    #     for method in cls.methods():
    #         if method.localname in ['swap', 'key_comp', 'value_comp', 'get_allocator']:
    #             if isinstance(method.boost_python_export, bool):
    #                 method.boost_python_export = False
    #     for constructor in cls.constructors():
    #         if not(constructor.nb_parameters == 0 or constructor.nb_parameters == 1 and constructor.parameters[0].qualified_type.unqualified_type == cls):
    #             if isinstance(constructor.boost_python_export, bool):
    #                 constructor.boost_python_export = False
    # for cls in asg['class ::std::less'].specializations(partial = False):
    #     cls.boost_python_export = False
    for cls in asg['class ::std::allocator'].specializations(partial=False):
        cls.boost_python_export = False
    if 'class ::std::reverse_iterator' in asg:
        for cls in asg['class ::std::reverse_iterator'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::initializer_list' in asg:
        for cls in asg['class ::std::initializer_list'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::default_delete' in asg:
        for cls in asg['class ::std::default_delete'].specializations(
                partial=False):
            cls.boost_python_export = False
    for mtd in asg[
            '::std::string'].qualified_type.desugared_type.unqualified_type.methods(
            ):
        if mtd.localname in ['substr', 'compare']:
            mtd.boost_python_export = False
    # for spec in asg['class ::std::basic_ostream'].specializations(partial = False):
    #     spec.boost_python_export = False
    for cls in [
            'class ::std::basic_ostream< char, struct ::std::char_traits< char > >',
            'class ::std::basic_streambuf< char, struct ::std::char_traits< char > >',
            'class ::std::basic_filebuf< char, struct ::std::char_traits< char > >',
            'class ::std::basic_ifstream< char, struct ::std::char_traits< char > >'
    ]:
        asg[cls].boost_python_export = False
    return asg
Ejemplo n.º 3
0
    def test_mapping_export(self):
        """Test `mapping` export"""

        subprocess.check_call(
            [self.scons, 'cpp', '-c', '--prefix=' + self.prefix],
            cwd=self.srcdir)

        subprocess.check_call([self.scons, 'cpp', '--prefix=' + self.prefix],
                              cwd=self.srcdir)

        asg = autowig.AbstractSemanticGraph()

        if autowig.parser.plugin == 'libclang':
            kwargs = dict(silent=True)
        else:
            kwargs = dict()

        asg = autowig.parser(
            asg,
            self.incdir.files('*.h'),
            flags=['-x', 'c++', '-std=c++11', '-I' + str(self.incdir.parent)],
            **kwargs)

        autowig.controller.plugin = 'default'
        autowig.controller(asg)
        # for node in  ['enum ::max_align_t', '::max_align_t::__clang_max_align_nonce1', '::max_align_t::__clang_max_align_nonce2']:
        #     if node in asg:
        #         asg[node].boost_python_export = False

        wrappers = autowig.generator(
            asg,
            module=self.srcdir / 'src' / 'py' / '__basic.cpp',
            decorator=self.srcdir / 'src' / 'py' / 'basic' / '_basic.py',
            prefix='wrapper_')
        wrappers.write()

        subprocess.check_call(
            [self.scons, 'py', '-c', '--prefix=' + self.prefix],
            cwd=self.srcdir)
        subprocess.check_call(
            [self.scons, 'py', '--prefix=' + self.prefix, '--package=basic'],
            cwd=self.srcdir)

        for filepath in (self.srcdir / 'src' / 'py').walkfiles():
            if filepath.exists() and filepath.ext in ['.cpp', '.h']:
                filepath.remove()
Ejemplo n.º 4
0
    def test_with_none_overload_export(self, overload="none"):
        """Test `feedback` with 'none' overload"""

        asg = autowig.AbstractSemanticGraph()

        asg = autowig.parser(
            asg, [self.srcdir / 'test.h'],
            ['-x', 'c++', '-std=c++11', '-I' + str(self.srcdir)],
            silent=True)

        autowig.controller.plugin = 'default'
        autowig.controller(asg, overload=overload)

        module = autowig.generator(asg,
                                   module=self.srcdir / '_module.cpp',
                                   decorator=self.srcdir / '_module.py',
                                   prefix='wrapper_')

        from autowig._controller import cleaning
        cleaning(asg)

        module.write()

        s = subprocess.Popen(['scons', 'py'],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        prev, curr = s.communicate()

        while curr and not prev == curr:
            prev = curr
            if six.PY3:
                curr = curr.decode('ascii', 'ignore')
            code = autowig.feedback(curr, '.', asg)
            if code:
                exec(code, locals())
            s = subprocess.Popen(['scons', 'py'],
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            _, curr = s.communicate()

        for filepath in self.srcdir.walkfiles():
            if filepath.exists() and filepath.basename().startswith(
                    'wrapper_') or filepath.startswith('_module'):
                filepath.remove()
Ejemplo n.º 5
0
def controller(asg):
    autowig.controller.plugin = 'default'
    asg = autowig.controller(asg)
    # for function in asg['::statiskit::stl'].functions():
    #     if function.localname in ['generator', 'insert']:
    #         parameter = function.parameters[0].qualified_type.desugared_type
    #         if parameter.is_class:
    #             function.parent = parameter.unqualified_type
    for cls in asg['class ::std::vector'].specializations(partial = False):
        for method in cls.methods():
            if method.localname in ['resize', 'shrink_to_fit', 'operator[]']:
                if isinstance(method.boost_python_export, bool):
                    method.boost_python_export = False
        for constructor in cls.constructors():
            if not(constructor.nb_parameters == 0 or constructor.nb_parameters == 1 and constructor.parameters[0].qualified_type.unqualified_type == cls):
                if isinstance(constructor.boost_python_export, bool):
                    constructor.boost_python_export = False
    # for cls in asg['class ::std::set'].specializations(partial = False):
    #     for method in cls.methods():
    #         if method.localname in ['swap', 'key_comp', 'value_comp', 'get_allocator']:
    #             if isinstance(method.boost_python_export, bool):
    #                 method.boost_python_export = False
    #     for constructor in cls.constructors():
    #         if not(constructor.nb_parameters == 0 or constructor.nb_parameters == 1 and constructor.parameters[0].qualified_type.unqualified_type == cls):
    #             if isinstance(constructor.boost_python_export, bool):
    #                 constructor.boost_python_export = False
    # for cls in asg['class ::std::less'].specializations(partial = False):
    #     cls.boost_python_export = False
    for cls in asg['class ::std::allocator'].specializations(partial = False):
        cls.boost_python_export = False
    if 'class ::std::reverse_iterator' in asg:
        for cls in asg['class ::std::reverse_iterator'].specializations(partial = False):
            cls.boost_python_export = False
    if 'class ::std::initializer_list' in asg:
        for cls in asg['class ::std::initializer_list'].specializations(partial = False):
            cls.boost_python_export = False
    if 'class ::std::default_delete' in asg:
        for cls in asg['class ::std::default_delete'].specializations(partial = False):
            cls.boost_python_export = False
    for mtd in asg['::std::string'].qualified_type.desugared_type.unqualified_type.methods():
        if mtd.localname in ['substr', 'compare']:
            mtd.boost_python_export = False
    # for spec in asg['class ::std::basic_ostream'].specializations(partial = False):
    #     spec.boost_python_export = False
    for cls in ['class ::std::basic_ostream< char, struct ::std::char_traits< char > >',
                'class ::std::basic_streambuf< char, struct ::std::char_traits< char > >',
                'class ::std::basic_filebuf< char, struct ::std::char_traits< char > >',
                'class ::std::basic_ifstream< char, struct ::std::char_traits< char > >']:
        asg[cls].boost_python_export = False
    return asg
Ejemplo n.º 6
0
 def boost_python_builder(target, source, env):
     SITE_AUTOWIG = env['SITE_AUTOWIG']
     if 'AUTOWIG_ASG' in env:
         env['AUTOWIG_ASG'][env['AUTOWIG_generator_module'].abspath].remove()
     env['AUTOWIG_ASG'] = autowig.AbstractSemanticGraph()
     asg = env['AUTOWIG_ASG']
     for dependency in env['AUTOWIG_DEPENDS']:
         with open(os.path.join(SITE_AUTOWIG, 'ASG', dependency + '.pkl'), 'rb') as filehandler:
             asg.merge(pickle.load(filehandler))
     AUTOWIG_PARSER = env['AUTOWIG_PARSER']
     if not AUTOWIG_PARSER in autowig.parser:
         parser = import_module('scons_tools.site_autowig.parser.' +  AUTOWIG_PARSER)
         autowig.parser[AUTOWIG_PARSER] = parser.parser
     autowig.parser.plugin = AUTOWIG_PARSER
     autowig.parser(asg, [header.abspath for header in source],
                    flags = ['-x', 'c++'] + env.subst('$CCFLAGS $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS').split(),
                    **{kwarg[len('AUTOWIG_parser_'):] : env[kwarg] for kwarg in env.Dictionary() if isinstance(kwarg, basestring) and kwarg.startswith('AUTOWIG_parser_')})
     AUTOWIG_CONTROLLER = env['AUTOWIG_CONTROLLER']
     if not AUTOWIG_CONTROLLER in autowig.controller:
         controller = import_module('scons_tools.site_autowig.controller.' +  AUTOWIG_CONTROLLER)
         autowig.controller[AUTOWIG_CONTROLLER] = controller.controller
     autowig.controller.plugin = AUTOWIG_CONTROLLER
     asg = autowig.controller(asg, 
                              **{kwarg[len('AUTOWIG_controller_'):] : env[kwarg] for kwarg in env.Dictionary() if isinstance(kwarg, basestring) and kwarg.startswith('AUTOWIG_controller_')})
     AUTOWIG_GENERATOR = env['AUTOWIG_GENERATOR']
     if not AUTOWIG_GENERATOR in autowig.generator:
         generator = import_module('scons_tools.site_autowig.generator.' +  AUTOWIG_GENERATOR)
         autowig.generator[AUTOWIG_GENERATOR] = generator.generator
     autowig.generator.plugin = AUTOWIG_GENERATOR
     wrappers = autowig.generator(asg,
                                  **{kwarg[len('AUTOWIG_generator_'):] : env[kwarg] for kwarg in env.Dictionary() if isinstance(kwarg, basestring) and kwarg.startswith('AUTOWIG_generator_')})
     wrappers.header.helder = env['AUTOWIG_HELDER']
     wrappers.write()
     with open(target[-1].abspath, 'wb') as filehandler:
         pickle.dump(asg, filehandler)
     return None
Ejemplo n.º 7
0
    ]:
        asg[noncopyable].is_copyable = False
    for cls in asg.classes():
        for fld in cls.fields(access='public'):
            if fld.qualified_type.unqualified_type.globalname == 'class ::std::locale::id':
                fld.boost_python_export = False
    for specialization in asg['class ::std::reverse_iterator'].specializations(
    ):
        specialization.boost_python_export = False
    asg['::std::ios_base::openmode'].qualified_type.boost_python_export = True
    return asg


autowig.controller['stat_tool'] = stat_tool_controller
autowig.controller.plugin = 'stat_tool'
asg = autowig.controller(asg)

autowig.generator.plugin = 'boost_python_internal'
wrappers = autowig.generator(
    asg,
    module=root / 'src' / 'py' / 'wrapper' / '_stat_tool.cpp',
    decorator=root / 'src' / 'py' / 'stat_tool' / '_stat_tool.py',
    prefix='wrapper_')

wrappers.write()

shutil.rmtree('include')

import pickle
with open('ASG.pkl', 'w') as filehandler:
    pickle.dump(asg, filehandler)
Ejemplo n.º 8
0
 def boost_python_builder(target, source, env):
     SITE_AUTOWIG = env['SITE_AUTOWIG']
     if 'AUTOWIG_ASG' in env:
         try:
             env['AUTOWIG_ASG'][
                 env['AUTOWIG_generator_module'].abspath].remove()
         except:
             pass
     env['AUTOWIG_ASG'] = autowig.AbstractSemanticGraph()
     asg = env['AUTOWIG_ASG']
     for dependency in env['AUTOWIG_DEPENDS']:
         with open(
                 os.path.join(SITE_AUTOWIG, 'ASG',
                              dependency + '.pkl'),
                 'rb') as filehandler:
             asg.merge(pickle.load(filehandler))
     AUTOWIG_PARSER = env['AUTOWIG_PARSER']
     if not AUTOWIG_PARSER in autowig.parser:
         filename = os.path.join(SITE_AUTOWIG, 'parser',
                                 AUTOWIG_PARSER + '.py')
         exec(
             compile(open(filename, "rb").read(), filename, 'exec'),
             globals(), locals())
         autowig.parser[AUTOWIG_PARSER] = locals()['parser']
     autowig.parser.plugin = AUTOWIG_PARSER
     kwargs = {
         kwarg[len('AUTOWIG_parser_'):]: env[kwarg]
         for kwarg in env.Dictionary()
         if isinstance(kwarg, basestring)
         and kwarg.startswith('AUTOWIG_parser_')
     }
     for key, value in kwargs.items():
         if isinstance(value, File):
             kwargs[key] = str(value.abspath)
     if env['SYSTEM'] == 'win' and 'MSVC_VERSION' in env and not 'msvc_version' in kwargs:
         kwargs['msvc_version'] = env['MSVC_VERSION']
     autowig.parser(
         asg, [header.abspath for header in source],
         flags=['-x', 'c++'] + env.subst(
             '$CCFLAGS $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
         ).split(),
         **kwargs)
     AUTOWIG_CONTROLLER = env['AUTOWIG_CONTROLLER']
     if not AUTOWIG_CONTROLLER in autowig.controller:
         filename = os.path.join(SITE_AUTOWIG, 'controller',
                                 AUTOWIG_CONTROLLER + '.py')
         exec(
             compile(open(filename, "rb").read(), filename, 'exec'),
             globals(), locals())
         autowig.controller[AUTOWIG_CONTROLLER] = locals(
         )['controller']
     autowig.controller.plugin = AUTOWIG_CONTROLLER
     kwargs = {
         kwarg[len('AUTOWIG_controller_'):]: env[kwarg]
         for kwarg in env.Dictionary()
         if isinstance(kwarg, basestring)
         and kwarg.startswith('AUTOWIG_controller_')
     }
     for key, value in kwargs.items():
         if isinstance(value, File):
             kwargs[key] = str(value.abspath)
     asg = autowig.controller(asg, **kwargs)
     AUTOWIG_GENERATOR = env['AUTOWIG_GENERATOR']
     if not AUTOWIG_GENERATOR in autowig.generator:
         filename = os.path.join(SITE_AUTOWIG, 'generator',
                                 AUTOWIG_GENERATOR + '.py')
         exec(
             compile(open(filename, "rb").read(), filename, 'exec'),
             globals(), locals())
         autowig.generator[AUTOWIG_GENERATOR] = locals(
         )['generator']
     autowig.generator.plugin = AUTOWIG_GENERATOR
     kwargs = {
         kwarg[len('AUTOWIG_generator_'):]: env[kwarg]
         for kwarg in env.Dictionary()
         if isinstance(kwarg, basestring)
         and kwarg.startswith('AUTOWIG_generator_')
     }
     for key, value in kwargs.items():
         if isinstance(value, File):
             kwargs[key] = str(value.abspath)
     wrappers = autowig.generator(asg, **kwargs)
     wrappers.header.helder = env['AUTOWIG_HELDER']
     if not env['AUTOWIG_NO_WRAPPERS']:
         wrappers.write()
     target = target[-1].abspath
     target_dir = os.path.abspath(os.path.join(target, os.pardir))
     if not os.path.exists(target_dir):
         os.makedirs(target_dir)
     with open(target, 'wb') as filehandler:
         pickle.dump(asg, filehandler)
     return None
Ejemplo n.º 9
0
def controller(asg, library=True, **kwargs):
    autowig.controller.plugin = 'default'
    asg = autowig.controller(asg, clean=False, **kwargs)
    if library:
        for function in asg['::statiskit::stl'].functions():
            if function.localname in ['generator', 'insert']:
                parameter = function.parameters[
                    0].qualified_type.desugared_type
                if parameter.is_class:
                    function.parent = parameter.unqualified_type
        for mtd in asg[
                '::statiskit::stl::String'].qualified_type.desugared_type.unqualified_type.methods(
                ):
            mtd.boost_python_export = False
    if 'class ::std::vector' in asg:
        for cls in asg['class ::std::vector'].specializations(partial=False):
            for method in cls.methods():
                if method.localname in [
                        'resize', 'shrink_to_fit', 'operator[]'
                ]:
                    if isinstance(method.boost_python_export, bool):
                        method.boost_python_export = False
            for constructor in cls.constructors():
                if not (constructor.nb_parameters == 0
                        or constructor.nb_parameters == 1 and constructor.
                        parameters[0].qualified_type.unqualified_type == cls):
                    if isinstance(constructor.boost_python_export, bool):
                        constructor.boost_python_export = False
    if 'class ::std::set' in asg:
        for cls in asg['class ::std::set'].specializations(partial=False):
            for method in cls.methods():
                if method.localname in [
                        'swap', 'key_comp', 'value_comp', 'get_allocator'
                ]:
                    if isinstance(method.boost_python_export, bool):
                        method.boost_python_export = False
            for constructor in cls.constructors():
                if not (constructor.nb_parameters == 0
                        or constructor.nb_parameters == 1 and constructor.
                        parameters[0].qualified_type.unqualified_type == cls):
                    if isinstance(constructor.boost_python_export, bool):
                        constructor.boost_python_export = False
    if 'class ::std::less' in asg:
        for cls in asg['class ::std::less'].specializations(partial=False):
            cls.boost_python_export = False
    if 'class ::std::hash' in asg:
        for cls in asg['class ::std::hash'].specializations(partial=False):
            cls.boost_python_export = False
    if 'class ::std::char_traits' in asg:
        for cls in asg['class ::std::char_traits'].specializations(
                partial=False):
            for mtd in cls.methods(access='public'):
                cls.boost_python_export = False
    if 'class ::std::allocator' in asg:
        for cls in asg['class ::std::allocator'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::reverse_iterator' in asg:
        for cls in asg['class ::std::reverse_iterator'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::initializer_list' in asg:
        for cls in asg['class ::std::initializer_list'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::default_delete' in asg:
        for cls in asg['class ::std::default_delete'].specializations(
                partial=False):
            cls.boost_python_export = False
    if 'class ::std::move_iterator' in asg:
        for cls in asg['class ::std::move_iterator'].specializations(
                partial=False):
            cls.boost_python_export = False
    for supercls in [
            'class ::std::_Rb_tree_const_iterator',
            'class ::std::_Rb_tree_iterator',
            'class ::std::__detail::_Node_const_iterator',
            'class ::std::__detail::_Node_iterator'
    ]:
        if supercls in asg:
            for cls in asg[supercls].specializations(partial=False):
                cls.boost_python_export = False
            for cls in asg.classes(templated=False, specialized=True):
                for template in cls.templates:
                    template = template.desugared_type.unqualified_type
                    if isinstance(
                            template, TemplateSpecializationProxy
                    ) and template.specialize.globalname == supercls:
                        cls.boost_python_export = False
    return asg
Ejemplo n.º 10
0
    def test_libclang_parser(self):
        """Test `libclang` parser"""

        headers = [self.incdir / 'tool.h']

        asg = autowig.AbstractSemanticGraph()
        asg = autowig.parser(
            asg,
            headers,
            flags=[
                '-x', 'c++', '-std=c++11', '-D__STDC_LIMIT_MACROS',
                '-D__STDC_CONSTANT_MACROS', '-I' + str(self.incdir.parent),
                '-I' + str(self.incdir.parent.abspath() / 'python2.7')
            ],
            bootstrap=False,
            silent=True)

        def clanglite_controller(asg):
            for node in asg['::boost::python'].classes(nested=True):
                node.is_copyable = True

            for node in asg.classes():
                node.boost_python_export = False
            for node in asg.functions(free=True):
                node.boost_python_export = False
            for node in asg.variables(free=True):
                node.boost_python_export = False
            for node in asg.enumerations():
                node.boost_python_export = False
            for node in asg.enumerators():
                if node.parent.boost_python_export:
                    node.boost_python_export = False
            for node in asg.typedefs():
                node.boost_python_export = False

            from autowig.default_controller import refactoring
            asg = refactoring(asg)

            if autowig.parser.plugin == 'libclang':
                for fct in asg.functions(free=False):
                    asg._nodes[fct._node]['_is_virtual'] = False
                    asg._nodes[fct._node]['_is_pure'] = False
                asg['class ::clang::QualType'].is_abstract = False
                asg['class ::clang::QualType'].is_copyable = True
                asg['class ::llvm::StringRef'].is_abstract = False
                asg['class ::llvm::StringRef'].is_copyable = True
                asg['class ::clang::FileID'].is_abstract = False
                asg['class ::clang::FileID'].is_copyable = True
                asg['class ::clang::SourceLocation'].is_abstract = False
                asg['class ::clang::SourceLocation'].is_copyable = True
                asg['class ::clang::TemplateArgument'].is_abstract = False
                asg['class ::clang::TemplateArgument'].is_copyable = True
                for cls in [
                        '::clang::FriendDecl', '::clang::CapturedDecl',
                        '::clang::OMPThreadPrivateDecl',
                        '::clang::NonTypeTemplateParmDecl',
                        '::clang::TemplateArgumentList', '::clang::ImportDecl',
                        '::clang::TemplateTemplateParmDecl',
                        '::clang::CapturedDecl',
                        '::clang::OMPThreadPrivateDecl',
                        '::clang::NonTypeTemplateParmDecl',
                        '::clang::TemplateArgumentList', '::clang::ImportDecl',
                        '::clang::TemplateTemplateParmDecl'
                ]:
                    asg['class ' + cls].is_abstract = False

            asg['class ::boost::python::api::object'].boost_python_export = True
            asg['class ::boost::python::list'].boost_python_export = True
            asg['class ::boost::python::str'].boost_python_export = True

            subset = []
            classes = [
                asg['class ::clang::QualType'], asg['class ::clang::Type'],
                asg['class ::clang::Decl']
            ]
            subset += classes
            for cls in classes:
                subset += cls.subclasses(recursive=True)
            for cls in subset:
                if not cls.globalname.strip('class ') in [
                        '::clang::QualType', '::llvm::StringRef',
                        '::clang::FileID', '::clang::SourceLocation',
                        '::clang::TemplateArgument', '::clang::FriendDecl',
                        '::clang::CapturedDecl',
                        '::clang::OMPThreadPrivateDecl',
                        '::clang::NonTypeTemplateParmDecl',
                        '::clang::TemplateArgumentList', '::clang::ImportDecl',
                        '::clang::TemplateTemplateParmDecl'
                ]:
                    cls.is_copyable = False
                else:
                    cls.is_copyable = True
            subset.append(asg['class ::llvm::StringRef'])

            subset.append(asg['class ::clang::Sema'])
            subset.append(asg['class ::clang::ASTUnit'])
            subset.append(asg['class ::clang::ASTContext'])
            subset.append(asg['class ::clang::SourceManager'])
            subset.append(asg['class ::clang::FileID'])

            subset.append(asg['class ::clang::SourceLocation'])

            subset.append(asg['class ::clang::CXXBaseSpecifier'])
            subset.append(asg['class ::clang::DeclContext'])
            subset.append(asg['class ::clang::TemplateArgument'])

            subset.append(asg['class ::clang::TemplateArgumentList'])
            subset.append(asg['enum ::clang::Type::TypeClass'])
            subset.append(asg['enum ::clang::AccessSpecifier'])
            subset.append(asg['enum ::clang::LinkageSpecDecl::LanguageIDs'])
            subset.append(asg['enum ::clang::BuiltinType::Kind'])
            subset.append(asg['enum ::clang::TemplateArgument::ArgKind'])
            subset.append(asg['enum ::clang::Decl::Kind'])
            subset.extend(
                asg.nodes('::clanglite::build_ast_from_code_with_args'))

            for node in subset:
                node.boost_python_export = True

            for fct in asg['::clanglite'].functions():
                if not fct.localname == 'build_ast_from_code_with_args':
                    fct.parent = fct.parameters[
                        0].qualified_type.desugared_type.unqualified_type
                fct.boost_python_export = True

            for mtd in asg['class ::clang::ASTContext'].methods(
                    pattern='.*getSourceManager.*'):
                if mtd.return_type.globalname == 'class ::clang::SourceManager &':
                    mtd.boost_python_export = True
                    break

            if autowig.parser.plugin == 'libclang':
                for node in (
                        asg.functions(pattern='.*(llvm|clang).*_(begin|end)') +
                        asg.functions(
                            pattern='::clang::CXXRecordDecl::getCaptureFields')
                        + asg.functions(
                            pattern='.*(llvm|clang).*getNameAsString') +
                        asg.nodes(
                            '::clang::NamedDecl::getQualifiedNameAsString') +
                        asg.functions(pattern='.*::clang::ObjCProtocolDecl') +
                        asg.nodes(
                            '::clang::ObjCProtocolDecl::collectInheritedProtocolProperties'
                        ) + asg.nodes('::clang::ASTUnit::LoadFromASTFile') +
                        asg.nodes('::clang::ASTUnit::getCachedCompletionTypes')
                        + asg.nodes('::clang::ASTUnit::getBufferForFile') +
                        asg.nodes('::clang::CXXRecordDecl::getCaptureFields') +
                        asg.nodes('::clang::ASTContext::SectionInfos') +
                        asg.nodes('::clang::ASTContext::getAllocator') +
                        asg.nodes('::clang::ASTContext::getObjCEncoding.*') +
                        asg.nodes('::clang::ASTContext::getAllocator') +
                        asg.nodes('::clang::QualType::getAsString') +
                        asg.nodes('::clang::SourceLocation::printToString') +
                        asg['class ::llvm::StringRef'].methods()):
                    node.boost_python_export = False

            if autowig.parser.plugin == 'clanglite':
                for mtd in asg['class ::clang::Decl'].methods():
                    if mtd.localname == 'hasAttr':
                        mtd.boost_python_export = False

            import sys
            try:
                from path import path as Path
            except:
                from path import Path

            import platform
            if any(platform.win32_ver()):
                for header in (Path(sys.prefix) / 'Library' / 'include' /
                               'clang').walkfiles('*.h'):
                    asg[header.abspath()].is_external_dependency = False
            else:
                for header in (Path(sys.prefix) / 'include' /
                               'clang').walkfiles('*.h'):
                    asg[header.abspath()].is_external_dependency = False

            return asg

        autowig.controller['clanglite'] = clanglite_controller
        autowig.controller.plugin = 'clanglite'
        asg = autowig.controller(asg)

        asg['enum ::max_align_t'].boost_python_export = False
        asg['::max_align_t::__clang_max_align_nonce1'].boost_python_export = False

        autowig.generator.plugin = 'boost_python_internal'
        module = autowig.generator(
            asg,
            module=self.srcdir / 'py' / 'wrapper' / '_clanglite.cpp',
            decorator=self.srcdir / 'py' / 'clanglite' / '_clanglite.py',
            closure=False)

        module.write()

        for filepath in (self.srcdir / 'src' / 'py' / 'wrapper').walkfiles():
            if filepath.exists() and filepath.ext in ['.cpp', '.h']:
                filepath.remove()