The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
from ctypes import *
from tempfile import NamedTemporaryFile
import weakref, sys

class FILE(Structure):
    pass

# PyFile_AsFile converts Python files into regular "FILE *" objects
PyFile_AsFile = pythonapi.PyFile_AsFile
PyFile_AsFile.argtypes = [py_object]
PyFile_AsFile.restype = POINTER(FILE)

# A friendly wrapper for exceptions
class SubversionException(Exception):
    def __init__(self, err, message=None, inherited=False):
        if isinstance(err, (int, long)):
            err = svn_error_create(err, None, message)

        self._as_parameter_ = err

        # Get a nice error message with line numbers and everything 
        f = NamedTemporaryFile()
        svn_handle_error2(err, PyFile_AsFile(f.file), 0, "")
        f.seek(0)
        self.value = f.read()
        f.close()

        # Save off the message and apr_err stuff
        self.message = err[0].message
        self.apr_err = err[0].apr_err
        self.child = None
        if err[0].child:
            self.child = SubversionException(err[0].child, None, True)

        if not inherited:
            # Cleanup the error when we die
            self.weakself = weakref.ref(self, lambda x: svn_error_clear(err))

    def __str__(self):
        return self.value

# If a error is returned from a Subversion function,
# raise an exception 
def SVN_ERR(ret):
    if ret:
        err = cast(ret, POINTER(svn_error_t))
        raise SubversionException(err)
    return ret

# As of ctypes 1.0, ctypes does not support custom error-checking
# functions on callbacks, nor does it support custom datatypes on
# callbacks, so ctypesgen sets the return values for callbacks
# to c_void_p.
#
# Callback functions, therefore, won't have their errors checked
# automatically. Users who call these functions should wrap
# their function call using SVN_ERR so as to ensure that any
# exceptions are thrown appropriately.


###########################