Py::Object pysvn_client::cmd_unlock( const Py::Tuple &a_args, const Py::Dict &a_kws )
{
    static argument_description args_desc[] =
    {
    { true,  name_url_or_path },
    { false, name_force },
    { false, NULL }
    };
    FunctionArguments args( "unlock", args_desc, a_args, a_kws );
    args.check();

    SvnPool pool( m_context );

    apr_array_header_t *targets = targetsFromStringOrList( args.getArg( name_url_or_path ), pool );

    std::string type_error_message;
    try
    {
        type_error_message = "expecting boolean for force keyword arg";
        bool force = args.getBoolean( name_force, true );

        try
        {
            checkThreadPermission();

            PythonAllowThreads permission( m_context );

            svn_error_t *error = svn_client_unlock
                (
                targets,
                force,
                m_context,
                pool
                );
            permission.allowThisThread();
            if( error != NULL )
                throw SvnException( error );
        }
        catch( SvnException &e )
        {
            // use callback error over ClientException
            m_context.checkForError( m_module.client_error );

            throw_client_error( e );
        }
    }
    catch( Py::TypeError & )
    {
        throw Py::TypeError( type_error_message );
    }

    return Py::None();
}
  void
  Client::unlock(const Targets & targets, bool force) throw(ClientException)
  {
    Pool pool;

    svn_error_t * error =
      svn_client_unlock(const_cast<apr_array_header_t*>(targets.array(pool)),
                        force,
                        *m_context,
                        pool);
    if (error != NULL)
      throw ClientException(error);
  }