# Path: pywrap/utils.py
# def lines(*args):
#     """Make multi-line string."""
#     return os.linesep.join(args)
# 
# def replace_keyword_argnames(argname):
#     """Replace Python keywords.
# 
#     We will add the prefix "_".
#     """
#     if keyword.iskeyword(argname):
#         argname = "_" + argname
#     return argname
# 
# Path: pywrap/templates.py
# def render(template, **kwargs):
#     """Render a Jinja2 template.
# 
#     Parameters
#     ----------
#     template : str
#         Name of the template file (without '.template' suffix). It must be
#         located in the directory 'pywrap/template_data'.
# 
#     kwargs : dict
#         Template arguments.
# 
#     Returns
#     -------
#     text : str
#         Rendered template.
#     """
#     template_file = resource_filename(
#         "pywrap", os.path.join("template_data", template + ".template"))
#     if not os.path.exists(template_file):
#         raise IOError("No template for '%s' found." % template)
#     template = jinja2.Template(open(template_file, "r").read())
#     return template.render(**kwargs)


import os
import re
from abc import ABCMeta, abstractmethod
from .utils import lines, replace_keyword_argnames
from .templates import render

    def python_type_decl(self):
        spec = self.type_info.get_specialization(self.tname)
        return "cpp.%s %s" % (spec, self.python_argname)

    def cpp_type_decl(self):
        raise NotImplementedError("Cannot declare new enum instance")


class CythonTypeConverter(AbstractTypeConverter):
    def matches(self):
        return (self.type_info.underlying_type(self.tname) in
                self.type_info.classes)

    def n_cpp_args(self):
        return 1

    def add_includes(self, includes):
        includes.add_include_for_deref()

    def python_to_cpp(self):
        cython_argname = "cpp_" + self.python_argname
        return ("%s * %s = %s.thisptr"
                % (self.cpp_type_decl(), cython_argname, self.python_argname))

    def cpp_call_args(self):
        return ["deref(cpp_%s)" % self.python_argname]

    def return_output(self, copy=True):
        # TODO only works with default and assignment operator

# Path: pywrap/utils.py
# def lines(*args):
#     """Make multi-line string."""
#     return os.linesep.join(args)
# 
# def replace_keyword_argnames(argname):
#     """Replace Python keywords.
# 
#     We will add the prefix "_".
#     """
#     if keyword.iskeyword(argname):
#         argname = "_" + argname
#     return argname
# 
# Path: pywrap/templates.py
# def render(template, **kwargs):
#     """Render a Jinja2 template.
# 
#     Parameters
#     ----------
#     template : str
#         Name of the template file (without '.template' suffix). It must be
#         located in the directory 'pywrap/template_data'.
# 
#     kwargs : dict
#         Template arguments.
# 
#     Returns
#     -------
#     text : str
#         Rendered template.
#     """
#     template_file = resource_filename(
#         "pywrap", os.path.join("template_data", template + ".template"))
#     if not os.path.exists(template_file):
#         raise IOError("No template for '%s' found." % template)
#     template = jinja2.Template(open(template_file, "r").read())
#     return template.render(**kwargs)


# Path: pywrap/type_conversion.py
import os
import re
from abc import ABCMeta, abstractmethod
from .utils import lines, replace_keyword_argnames
from .templates import render


    def python_type_decl(self):
        spec = self.type_info.get_specialization(self.tname)
        return "cpp.%s %s" % (spec, self.python_argname)

    def cpp_type_decl(self):
        raise NotImplementedError("Cannot declare new enum instance")


class CythonTypeConverter(AbstractTypeConverter):
    def matches(self):
        return (self.type_info.underlying_type(self.tname) in
                self.type_info.classes)

    def n_cpp_args(self):
        return 1

    def add_includes(self, includes):
        includes.add_include_for_deref()

    def python_to_cpp(self):
        cython_argname = "cpp_" + self.python_argname
        return ("%s * %s = %s.thisptr"
                % (self.cpp_type_decl(), cython_argname, self.python_argname))

    def cpp_call_args(self):
        return ["deref(cpp_%s)" % self.python_argname]

    def return_output(self, copy=True):
        # TODO only works with default and assignment operator

        return lines("ret = %s()" % self.tname,