class ForwardWrapperBase(object):
    """Generic base for all forward wrapper generators.

    Forward wrappers all have the following general structure in common:

     1. 'declarations' -- variable declarations; for compatibility
            with older C compilers it is very important that all
            declarations come before any simple statement.
            Declarations can be added with the add_declaration()
            method on the 'declarations' attribute.  Two standard
            declarations are always predeclared: '<return-type>
            retval', unless return-type is void, and 'PyObject
            \\*py_retval';

     2. 'code before parse' -- code before the
         PyArg_ParseTupleAndKeywords call; code can be freely added to
         it by accessing the 'before_parse' (a CodeBlock instance)
         attribute;

     3. A PyArg_ParseTupleAndKeywords call; uses items from the
         parse_params object;

     4. 'code before call' -- this is a code block dedicated to contain
         all code that is needed before calling the C function; code can be
         freely added to it by accessing the 'before_call' (a CodeBlock
         instance) attribute;

     5. 'call into C' -- this is realized by a C/C++ call; the list of
         parameters that should be used is in the 'call_params' wrapper
         attribute;

     6. 'code after call' -- this is a code block dedicated to contain
         all code that must come after calling into Python; code can be
         freely added to it by accessing the 'after_call' (a CodeBlock
         instance) attribute;

     7. A py_retval = Py_BuildValue(...) call; this call can be
        customized, so that out/inout parameters can add additional
        return values, by accessing the 'build_params' (a
        BuildValueParameters instance) attribute;

     8. Cleanup and return.

    Object constructors cannot return values, and so the step 7 is to
    be omitted for them.

    """

    PARSE_TUPLE = 1
    PARSE_TUPLE_AND_KEYWORDS = 2

    HAVE_RETURN_VALUE = False # change to true if the wrapper
                              # generates a return value even if the
                              # return_value attribute is None

    def __init__(self, return_value, parameters,
                 parse_error_return, error_return,
                 force_parse=None, no_c_retval=False,
                 unblock_threads=False):
        '''
        Base constructor

        :param return_value: type handler for the return value
        :param parameters: a list of type handlers for the parameters
        :param parse_error_return: statement to return an error during parameter parsing
        :param error_return: statement to return an error after parameter parsing
        :param force_parse: force generation of code to parse parameters even if there are none
        :param no_c_retval: force the wrapper to not have a C return value
        :param unblock_threads: generate code to unblock python threads during the C function call
        '''
        assert isinstance(return_value, ReturnValue) or return_value is None
        assert isinstance(parameters, list)
        assert all([isinstance(param, Parameter) for param in parameters])

        self.return_value = return_value
        self.parameters = parameters
        self.declarations = DeclarationsScope()
        self.before_parse = CodeBlock(parse_error_return, self.declarations)
        self.before_call = CodeBlock(parse_error_return, self.declarations,
                                     predecessor=self.before_parse)
        self.after_call = CodeBlock(error_return, self.declarations,
                                    predecessor=self.before_call)
        self.build_params = BuildValueParameters()
        self.parse_params = ParseTupleParameters()
        self.call_params = []
        self.force_parse = force_parse
        self.meth_flags = []
        self.unblock_threads = unblock_threads
        self.no_c_retval = no_c_retval
        self.overload_index = None
        self.deprecated = False

        # The following 3 variables describe the C wrapper function
        # prototype; do not confuse with the python function/method!
        self.wrapper_actual_name = None # name of the wrapper function/method
        self.wrapper_return = None # C type expression for the wrapper return
        self.wrapper_args = None # list of arguments to the wrapper function

        self._init_code_generation_state()

    def _init_code_generation_state(self):
        if self.return_value is not None or self.HAVE_RETURN_VALUE:
            self.declarations.declare_variable('PyObject*', 'py_retval')
        if (not self.no_c_retval and (self.return_value is not None or self.HAVE_RETURN_VALUE)
            and self.return_value.ctype != 'void'
            and not self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR
            and not self.return_value.NO_RETVAL_DECL):
            self.declarations.declare_variable(str(self.return_value.type_traits.ctype_no_const_no_ref), 'retval')

        self.declarations.reserve_variable('args')
        self.declarations.reserve_variable('kwargs')

    def reset_code_generation_state(self):
        self.declarations.clear()
        self.before_parse.clear()
        self.before_call.clear()
        self.after_call.clear()
        self.build_params.clear()
        self.parse_params.clear()
        self.call_params = []
        self.meth_flags = []

        self._init_code_generation_state()

    def set_parse_error_return(self, parse_error_return):
        self.before_parse.error_return = parse_error_return
        self.before_call.error_return = parse_error_return

    def generate_call(self):
        """Generates the code (into self.before_call) to call into
        Python, storing the result in the variable 'py_retval'; should
        also check for call error.
        """
        raise NotImplementedError

    def _before_call_hook(self):
        """
        Optional hook that lets subclasses add code after all
        parameters are parsed, but before the C function/method call.
        Subclasses may add code to self.before_call.
        """
        pass

    def _before_return_hook(self):
        """
        Optional hook that lets subclasses add code after all
        parameters are parsed and after the function C return value is
        processed, but after the python wrapper return value (py_ret)
        is built and returned.  Subclasses may add code to
        self.after_call, which will be placed before py_ret is
        created.
        """
        pass

    def write_open_wrapper(self, code_sink, add_static=False):
        assert self.wrapper_actual_name is not None
        assert self.wrapper_return is not None
        assert isinstance(self.wrapper_args, list)
        if add_static:
            code_sink.writeln("static " + self.wrapper_return)
        else:
            code_sink.writeln(self.wrapper_return)
        code_sink.writeln("%s(%s)" % (self.wrapper_actual_name, ', '.join(self.wrapper_args)))
        code_sink.writeln('{')
        code_sink.indent()

    def write_close_wrapper(self, code_sink):
        code_sink.unindent()
        code_sink.writeln('}')


    def generate_body(self, code_sink, gen_call_params=()):
        """Generate the wrapper function body
        code_sink -- a CodeSink object that will receive the code
        """

        if self.unblock_threads:
            py_thread_state = self.declarations.declare_variable("PyThreadState*", "py_thread_state", "NULL")
            self.after_call.write_code(
                "\nif (%s)\n"
                "     PyEval_RestoreThread(%s);\n" % (py_thread_state, py_thread_state))

        ## convert the input parameters
        for param in self.parameters:
            try:
                param.convert_python_to_c(self)
            except NotImplementedError:
                raise CodeGenerationError(
                    'convert_python_to_c method of parameter %s not implemented'
                    % (param.ctype,))

        if self.deprecated:
            if isinstance(self.deprecated, string_types):
                msg = self.deprecated
            else:
                msg = "Deprecated"
            self.before_call.write_error_check( 'PyErr_Warn(PyExc_DeprecationWarning, (char *) "%s")' % msg)

        self._before_call_hook()

        if self.unblock_threads:
            self.before_call.write_code(
                "\nif (PyEval_ThreadsInitialized ())\n"
                "     %s = PyEval_SaveThread();\n"
                % (py_thread_state, ))

        self.generate_call(*gen_call_params)

        params = self.parse_params.get_parameters()
        assert params[0][0] == '"'
        params_empty = (params == ['""'])
        params[0] = '(char *) ' + params[0]
        keywords = self.parse_params.get_keywords()
        if not params_empty or self.force_parse != None:
            self.meth_flags.append("METH_VARARGS")
            if keywords is None \
                    and self.force_parse != self.PARSE_TUPLE_AND_KEYWORDS:

                param_list = ['args'] + params
                self.before_parse.write_error_check('!PyArg_ParseTuple(%s)' %
                                                    (', '.join(param_list),))
            else:
                if keywords is None:
                    keywords = []
                keywords_var = self.declarations.declare_variable(
                    'const char *', 'keywords',
                    '{' + ', '.join(['"%s"' % kw for kw in keywords] + ['NULL']) + '}',
                     '[]')
                param_list = ['args', 'kwargs', params[0], '(char **) ' + keywords_var] + params[1:]
                self.before_parse.write_error_check('!PyArg_ParseTupleAndKeywords(%s)' %
                                                    (', '.join(param_list),))
                self.meth_flags.append("METH_KEYWORDS")
        else:
            self.meth_flags.append("METH_NOARGS")

        ## convert the return value(s)
        if self.return_value is None and not self.HAVE_RETURN_VALUE:

            assert self.build_params.get_parameters() == ['""'], \
                   "this wrapper is not supposed to return values"
            self._before_return_hook()
            self.after_call.write_cleanup()

        else:

            if self.return_value is not None:
                try:
                    self.return_value.convert_c_to_python(self)
                except NotImplementedError:
                    raise CodeGenerationError(
                        'convert_c_to_python method of return value %s not implemented'
                        % (self.return_value.ctype,))

            self._before_return_hook()

            params = self.build_params.get_parameters()
            if params:
                if params == ['""']:
                    self.after_call.write_code('Py_INCREF(Py_None);')
                    self.after_call.write_code('py_retval = Py_None;')
                else:
                    assert params[0][0] == '"'
                    params[0] = "(char *) " + params[0]
                    self.after_call.write_code('py_retval = Py_BuildValue(%s);' %
                                               (', '.join(params),))

            ## cleanup and return
            self.after_call.write_cleanup()
            self.after_call.write_code('return py_retval;')

        ## now write out the wrapper function body itself
        self.declarations.get_code_sink().flush_to(code_sink)
        code_sink.writeln()
        self.before_parse.sink.flush_to(code_sink)
        self.before_call.sink.flush_to(code_sink)
        self.after_call.sink.flush_to(code_sink)

    def get_py_method_def_flags(self):
        """
        Get a list of PyMethodDef flags that should be used for this wrapper.
        """
        flags = set(self.meth_flags)
        if flags:
            return list(flags)

        tmp_sink = codesink.NullCodeSink()
        try:
#             try:
#                 self.generate_body(tmp_sink)
#             except CodegenErrorBase:
#                 return []
#             else:
#                 return list(set(self.meth_flags))
            self.generate_body(tmp_sink)
            return list(set(self.meth_flags))
        finally:
            self.reset_code_generation_state() class ReverseWrapperBase(object):
    """Generic base for all reverse wrapper generators.

    Reverse wrappers all have the following general structure in common:

     1. 'declarations' -- variable declarations; for compatibility with
        older C compilers it is very important that all declarations
        come before any simple statement.  Declarations can be added
        with the add_declaration() method on the 'declarations'
        attribute.  Two standard declarations are always predeclared:
        '<return-type> retval', unless return-type is void, and 'PyObject
        \\*py_retval';

     2. 'code before call' -- this is a code block dedicated to contain
        all code that is needed before calling into Python; code can be
        freely added to it by accessing the 'before_call' (a CodeBlock
        instance) attribute;

     3. 'call into python' -- this is realized by a
        PyObject_CallMethod(...) or similar Python API call; the list
        of parameters used in this call can be customized by accessing
        the 'build_params' (a BuildValueParameters instance) attribute;

     4. 'code after call' -- this is a code block dedicated to contain
        all code that must come after calling into Python; code can be
        freely added to it by accessing the 'after_call' (a CodeBlock
        instance) attribute;

     5. A 'return retval' statement (or just 'return' if return_value is void)

    """

    NO_GIL_LOCKING = False

    def __init__(self, return_value, parameters, error_return=None):
        '''
        Base constructor

        :param return_value: type handler for the return value
        :param parameters: a list of type handlers for the parameters

        '''

        assert isinstance(return_value, TypeHandler)
        assert isinstance(parameters, list)
        assert all([isinstance(param, Parameter) for param in parameters])

        self.return_value = return_value
        self.parameters = parameters

        if error_return is None:
            error_return = return_value.get_c_error_return()
        self.error_return = error_return
        self.declarations = DeclarationsScope()
        self.before_call = CodeBlock(error_return, self.declarations)
        self.after_call = CodeBlock(error_return, self.declarations,
                                    predecessor=self.before_call)
        self.build_params = BuildValueParameters()
        self.parse_params = ParseTupleParameters()
        self._generate_gil_code()

    def set_error_return(self, error_return):
        self.error_return = error_return
        self.before_call.error_return = error_return
        self.after_call.error_return = error_return

    def reset_code_generation_state(self):
        self.declarations.clear()
        self.before_call.clear()
        self.after_call.clear()
        self.build_params.clear()
        self.parse_params.clear()
        self._generate_gil_code()

    def _generate_gil_code(self):
        if self.NO_GIL_LOCKING:
            return
        ## reverse wrappers are called from C/C++ code, when the Python GIL may not be held...
        gil_state_var = self.declarations.declare_variable('PyGILState_STATE', '__py_gil_state')
        self.before_call.write_code('%s = (PyEval_ThreadsInitialized() ? PyGILState_Ensure() : (PyGILState_STATE) 0);'
                                    % gil_state_var)
        self.before_call.add_cleanup_code('if (PyEval_ThreadsInitialized())\n'
                                          '    PyGILState_Release(%s);' % gil_state_var)


    def generate_python_call(self):
        """Generates the code (into self.before_call) to call into
        Python, storing the result in the variable 'py_retval'; should
        also check for call error.
        """
        raise NotImplementedError

    def generate(self, code_sink, wrapper_name, decl_modifiers=('static',),
                 decl_post_modifiers=()):
        """Generate the wrapper

        :param code_sink: a CodeSink object that will receive the code
        :param wrapper_name: C/C++ identifier of the function/method to generate
        :param decl_modifiers: list of C/C++ declaration modifiers, e.g. 'static'
        """
        assert isinstance(decl_modifiers, (list, tuple))
        assert all([isinstance(mod, string_types) for mod in decl_modifiers])

        #import sys
        #print("generate", self, file=sys.stderr)
        py_retval = self.declarations.declare_variable('PyObject*', 'py_retval')
        assert py_retval == "py_retval", "py_retval already declared: "\
          "generating the same wrapper twice without a reset() in between?"

        if self.return_value.ctype != 'void' \
                and not self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR \
                and not self.return_value.NO_RETVAL_DECL:
            self.declarations.declare_variable(self.return_value.ctype, 'retval')

        ## convert the input parameters
        for param in self.parameters:
            param.convert_c_to_python(self)

        ## generate_python_call should include something like
        ## self.after_call.write_error_check('py_retval == NULL')
        self.generate_python_call()

        ## convert the return value(s)
        self.return_value.convert_python_to_c(self)

        if self.parse_params.is_empty():
            self.before_call.write_error_check('py_retval != Py_None',
                                               'PyErr_SetString(PyExc_TypeError, "function/method should return None");')
        else:
            ## parse the return value
            ## this ensures that py_retval is always a tuple
            self.before_call.write_code('py_retval = Py_BuildValue((char*) "(N)", py_retval);')

            parse_tuple_params = ['py_retval']
            parse_params = self.parse_params.get_parameters()
            assert parse_params[0][0] == '"'
            parse_params[0] = '(char *) ' + parse_params[0]
            parse_tuple_params.extend(parse_params)
            self.before_call.write_error_check('!PyArg_ParseTuple(%s)' %
                                               (', '.join(parse_tuple_params),),
                                               failure_cleanup='PyErr_Print();')

        ## cleanup and return
        self.after_call.write_cleanup()
        if self.return_value.ctype == 'void':
            self.after_call.write_code('return;')
        else:
            self.after_call.write_code('return retval;')

        ## now write out the wrapper function itself

        ## open function
        retline = list(decl_modifiers)
        retline.append(self.return_value.ctype)
        code_sink.writeln(' '.join(retline))

        params_list = ', '.join([join_ctype_and_name(param.ctype, param.name)
                                 for param in self.parameters])
        code_sink.writeln("%s(%s)%s" % (wrapper_name, params_list,
                                        ' '.join([''] + list(decl_post_modifiers))))

        ## body
        code_sink.writeln('{')
        code_sink.indent()
        self.declarations.get_code_sink().flush_to(code_sink)
        code_sink.writeln()
        self.before_call.sink.flush_to(code_sink)
        self.after_call.sink.flush_to(code_sink)

        ## close function
        code_sink.unindent()
        code_sink.writeln('}') def join_ctype_and_name(ctype, name):
    """
    Utility method that joins a C type and a variable name into
    a single string

    >>> join_ctype_and_name('void*', 'foo')
    'void *foo'
    >>> join_ctype_and_name('void *', 'foo')
    'void *foo'
    >>> join_ctype_and_name("void**", "foo")
    'void **foo'
    >>> join_ctype_and_name("void **", "foo")
    'void **foo'
    >>> join_ctype_and_name('C*', 'foo')
    'C *foo'
    """
    if ctype[-1] == '*':
        for i in range(-1, -len(ctype) - 1, -1):
            if ctype[i] != '*':
                if ctype[i] == ' ':
                    return "".join([ctype[:i+1], ctype[i+1:], name])
                else:
                    return "".join([ctype[:i+1], ' ', ctype[i+1:], name])
        raise ValueError((ctype, name))
    else:
        return " ".join([ctype, name]) class CodeGenerationError(CodegenErrorBase):
    """Exception that is raised when wrapper generation fails for some reason.""" class ReturnValue(_ReturnValue):
    __metaclass__ = ReturnValueMeta class Parameter(_Parameter):
    __metaclass__ = ParameterMeta PY3 = (sys.version_info[0] >= 3)
DEBUG = 0
class CodeSink(object):
class FileCodeSink(CodeSink):
class MemoryCodeSink(CodeSink):
class NullCodeSink(CodeSink):
    def __init__(self):
    def _format_code(self, code):
    def writeln(self, line=''):
    def indent(self, level=4):
    def unindent(self):
    def __init__(self, file_):
    def __repr__(self):
    def writeln(self, line=''):
    def __lt__(self, other):
    def __init__(self):
    def writeln(self, line=''):
    def flush_to(self, sink):
    def flush(self):
    def __init__(self):
    def writeln(self, line=''):
    def flush_to(self, sink):
    def flush(self): PY3 = (sys.version_info[0] >= 3)
    RETURN_TYPE = NotImplemented
    ERROR_RETURN = NotImplemented
def isiterable(obj):
def vector_counter(vec):
    def __init__(self, wrapper_name):
    def add(self, wrapper):
    def _normalize_py_method_flags(self):
    def _compute_all_wrappers(self):
    def generate(self, code_sink):
    def get_py_method_def(self, name):
    def generate_declaration(self, code_sink):
    def generate_class_declaration(self, code_sink):
    def reset_code_generation_state(self):
    def get_section(self):
class OverloadedWrapper(object): def _get_deprecated_virtuals():
    def handle_error(self, wrapper, exception, traceback_):
class ErrorHandler(object): PY3 = (sys.version_info[0] >= 3)
    def any(iterable):
def write_preamble(code_sink, min_python_version=None):
def mangle_name(name):
def get_mangled_name(base_name, template_args):
def call_with_error_handling(callback, args, kwargs, wrapper,
                             exceptions_to_handle=(TypeConfigurationError,
                                                   CodeGenerationError,
                                                   NotSupportedError)):
def ascii(value):
def param(*args, **kwargs):
def retval(*args, **kwargs):
def parse_param_spec(param_spec):
def parse_retval_spec(retval_spec):
def eval_param(param_value, wrapper=None):
def eval_retval(retval_value, wrapper=None):
class SkipWrapper(Exception):
import warnings
import traceback
from copy import copy
from pybindgen.typehandlers.base import ForwardWrapperBase, ReverseWrapperBase, \
    join_ctype_and_name, CodeGenerationError
from pybindgen.typehandlers.base import ReturnValue, Parameter
from pybindgen.typehandlers import codesink
from pybindgen import overloading
from pybindgen import settings
from pybindgen import utils
from pybindgen.cppexception import CppException
        from . import cppclass
        from . import cppclass
        from . import cppclass
        from . import cppclass
        from . import cppclass
        from . import cppclass
                from . import cppclass
        if custodian == -1 or ward == -1:
            if postcall is None:
                postcall = True
            if not postcall:
                raise TypeConfigurationError("custodian/ward policy must be postcall "
                                             "when a return value is involved")
        else:
            if postcall is None:
                postcall = False
        self.custodians_and_wards.append((custodian, ward, postcall))


    def clone(self):
        """
        Creates a semi-deep copy of this constructor wrapper.  The
        returned constructor wrapper clone contains copies of all
        parameters, so they can be modified at will.
        """
        meth = type(self)([copy(param) for param in self.parameters])
        meth._class = self._class
        meth.wrapper_base_name = self.wrapper_base_name
        meth.wrapper_actual_name = self.wrapper_actual_name
        return meth

    def set_class(self, class_):
        "Set the class wrapper object (CppClass)"
        self._class = class_
        self.wrapper_base_name = "_wrap_%s__tp_init" % (
            class_.pystruct,)
    def get_class(self):
        "Get the class wrapper object (CppClass)"
        return self._class
    class_ = property(get_class, set_class)

    def generate_call(self, class_=None):
        "virtual method implementation; do not call"
        if class_ is None:
            class_ = self._class

        if self.throw:
            self.before_call.write_code('try\n{')
            self.before_call.indent()

        #assert isinstance(class_, CppClass)
        if class_.helper_class is None:
            class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params))
            class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params))
            self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
        else:
            ## We should only create a helper class instance when
            ## being called from a user python subclass.
            self.before_call.write_code("if (Py_TYPE(self) != &%s)" % class_.pytypestruct)
            self.before_call.write_code("{")
            self.before_call.indent()

            class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params),
                                         class_.helper_class.name)
            self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
            self.before_call.write_code('((%s*) self->obj)->set_pyobj((PyObject *)self);'
                                        % class_.helper_class.name)
            class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params),
                                                     class_.helper_class.name)

            self.before_call.unindent()
            self.before_call.write_code("} else {")
            self.before_call.indent()

            self.before_call.write_code("// visibility: %r" % self.visibility)
            try:
                if self.visibility not in ['public']:
                    raise CodeGenerationError("private/protected constructor")
                class_.get_construct_name()
            except CodeGenerationError:
                self.before_call.write_code('PyErr_SetString(PyExc_TypeError, "class \'%s\' '
                                            'cannot be constructed");' % class_.name)
                self.before_call.write_code('return -1;')
            else:
                class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params))
                self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
                class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params))

            self.before_call.unindent()
            self.before_call.write_code("}")

        if self.throw:
            for exc in self.throw:
                self.before_call.unindent()
                self.before_call.write_code('} catch (%s const &exc) {' % exc.full_name)
                self.before_call.indent()
                self.before_call.write_cleanup()
                exc.write_convert_to_python(self.before_call, 'exc')
                self.before_call.write_code('return -1;')
            self.before_call.unindent()
            self.before_call.write_code('}')

    def _before_call_hook(self):
        "hook that post-processes parameters and check for custodian=<n> CppClass parameters"
        cppclass.implement_parameter_custodians_precall(self)

    def _before_return_hook(self):
        "hook that post-processes parameters and check for custodian=<n> CppClass parameters"
        cppclass.implement_parameter_custodians_postcall(self)

    def generate(self, code_sink, wrapper_name=None, extra_wrapper_params=()):
        """
        Generates the wrapper code
        :param code_sink: a CodeSink instance that will receive the generated code
        :returns: the wrapper function name.

        """

        if self.visibility == 'private':
            raise utils.SkipWrapper("Class %r has a private constructor ->"
                                    " cannot generate a constructor for it" % self._class.full_name)
        elif self.visibility == 'protected':
            if self._class.helper_class is None:
                raise utils.SkipWrapper("Class %r has a protected constructor and no helper class"
                                        " -> cannot generate a constructor for it" % self._class.full_name)

        #assert isinstance(class_, CppClass)

        tmp_sink = codesink.MemoryCodeSink()