Where can I find a good introduction to using the subversion python bindings?
I found one section in the svnbook that talks about it; and some basic examples from 1.3.
Is there something a bit more thorough and up-to-date?
Where can I find a good introduction to using the subversion python bindings?
I found one section in the svnbook that talks about it; and some basic examples from 1.3.
Is there something a bit more thorough and up-to-date?
Just wanted to add a little clarification here.
Thanks to the above two answers (@BenjaminWohlwend and @Logan), I became aware there are more than one set of Python bindings/interfaces for Subversion; I did this on my Ubuntu 11.04 box:
$ apt-cache search '[Ss]vn|[Ss]ubversion' | grep -i python
python-svn - A(nother) Python interface to Subversion
python-svn-dbg - A(nother) Python interface to Subversion (debug extension)
python-subversion - Python bindings for Subversion
python-subversion-dbg - Python bindings for Subversion (debug extension)
python-opster - a python command line parsing speedster
python-py - Advanced Python testing tool and networking lib
python-rope - Python refactoring library
python-subvertpy - Alternative Python bindings for Subversion
One can look at the Debian package filelist, to determine which libraries these refer to; so we have:
python-subversion
- or SWIG bindings (or libsvn
, libsvn_swig_py
) filelist
import svn.core, svn.client
; from svn import fs, core, repos
python-svn
- or pysvn
filelist
python-subvertpy
- or subvertpy
filelist
from subvertpy import delta, repos
, from subvertpy.ra import RemoteAccess, Auth
... and I also found another in the repository:
ctypes-python
- or csvn
source
import csvn.core
, from csvn.repos import *
The link http://svn.apache.org/repos/asf/subversion (which I got from @BenjaminWohlwend) is apparently the Apache Software Foundation (asf?) Subversion repository for Subversion source code itself.
The OP's quest for documentation seems related to python-subversion
(or SWIG bindings (or libsvn
); whose build-from-source instructions are in @Logan's post. I couldn't find much better documentation source from the svn.developer: Using the APIs already referred in the OP, except for the bindings/swig/python/README; it explains how SWIG generates Python interfaces from C:
TRANSLATING PARAMETER LISTS
The argument-reductions laws of the SWIG bindings something go like
this:- The module prefix can be omitted. o: void *some_C_function = svn_client_foo; becomes: import svn.client func = svn.client.foo
[...]
Then, one could look in, say, svn/core.py, and find functions (and "Symbols defined explicitly") like svn_mergeinfo_merge
; noting that core.py
imports libsvn.core
- where libsvn
probably refers to the shared object (.so
) files built from the C file libsvn_swig_py/swigutil_py.c.
Then, we can look up svn_mergeinfo_merge
, and find a commit message like SVNSearch: Subversion (commit 23570 05.03.2007), which refers to that function, and a svn_mergeinfo.h
; looking up that file further, we find it in the ASF repository: svn_mergeinfo.h, which indeed contains:
/** Like svn_mergeinfo_merge2, but uses only one pool.
*
* @deprecated Provided for backward compatibility with the 1.5 API.
*/
SVN_DEPRECATED
svn_error_t *
svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo,
svn_mergeinfo_t changes,
apr_pool_t *pool);
Seeing DEPRECATED
there, it's probably good here to refer to svn commit: r1175903 (Mon Sep 26 2011):
subversion/libsvn_subr/mergeinfo.c
(svn_mergeinfo_merge2): New.
(svn_mergeinfo_merge): Move to deprecated.c.
(svn_mergeinfo_catalog_merge): Use the new API.
That is - that particular function has been deprecated in 2011 - so hopefully, one's Python SVN bindings and SVN installation should be matching...
If you build Subversion from source the Subversion Python bindings aren't automatically included. You have to specifically build and include them. Luckily, you can do this after you've installed Subversion. The source for the bindings is included within the Subversion source code.
These instructions are for Subversion 1.5.9 and Python 2.4.3 on Red Hat Enterprise Linux, but they should be easily hackable for recent versions of Subversion and Python and generic unix installs.
First, download swig from http://downloads.sourceforge.net/swig
tar -xvf swig-<version>.tar.gz
cd swig-<version>
At this point you have to make a decision. You can install swig for all supported languages or you can install for just what you need. 'make check' can take up to an hour to run and may fail due to errors from languages you aren't concerned with.
If you want to use all supported languages run:
./configure
If you want to scope down to just python, run:
./configure --with-python=/usr/local/bin/python2.4 --without-perl --without-ruby --without-php4
Next, run:
make
If you opted for the full install, run:
make -k check
If you scoped down to just python you only need to run the python tests:
make check-python-examples
make check-python-test-suite
If everything's OK, you're ready to install swig:
make install
From here, installing the subversion python bindings should be fairly straightforward:
tar -xvf subversion-1.5.9.tar.gz --gzip
cd subversion-1.5.9
make swig-py
make install-swig-py
touch /usr/lib64/python2.4/site-packages/svn-python.pth
echo /usr/local/lib/svn-python > /usr/lib64/python2.4/site-packages/svn-python.pth
As always, your mileage may vary depending on your specific versions and architecture. Good luck.
This looks like a pretty complete documentation:
http://pysvn.tigris.org/docs/pysvn_prog_ref.html
And here are a couple examples:
http://svn.apache.org/repos/asf/subversion/trunk/tools/examples/
Hope it's OK with another post re: python-subversion
: I wanted to try Example 8.3. A Python status crawler - Using the APIs (svnbook). on Ubuntu 11.04, Python 2.7, svn_client_status2
crashed on a filename with UTF-8 characters with "Error (22): Error converting entry in directory 'path' to UTF-8" - the solution to this is to call setlocale
before any calls to this function.
I also realized there are svn_client_status3
and svn_client_status4
in the Python API;
svn_client_status3
has a slightly different call, and also needs setlocale
. However, svn_client_status4
should NOT be used - it segfaults, since it needs a struct argument which Python cannot deliver; for more, see #16027750 Debugging: stepping through Python script using gdb?.
To wrap it up, here is the Example 8.3 with locale setting which uses svn_client_status3
- and doesn't crash on my system (even on filenames with UTF-8 characters):
#!/usr/bin/env python
# modified from:
# http://svnbook.red-bean.com/en/1.5/svn.developer.usingapi.html
# does the same as `svn status`, and is marked:
"""Crawl a working copy directory, printing status information."""
# tested on Python 2.7, Ubuntu Natty 11.04; needs:
# sudo apt-get install python-subversion
import locale
print locale.getlocale() # (None, None) - in C: ANSI_X3.4-1968
locale.setlocale(locale.LC_ALL, '') # would print en_US.UTF-8
print locale.getlocale() # NOW it is ('en_US', 'UTF-8')
import sys
import os.path
import getopt
import svn.core, svn.client, svn.wc
def generate_status_code(status):
"""Translate a status value into a single-character status code,
using the same logic as the Subversion command-line client."""
code_map = { svn.wc.svn_wc_status_none : ' ',
svn.wc.svn_wc_status_normal : ' ',
svn.wc.svn_wc_status_added : 'A',
svn.wc.svn_wc_status_missing : '!',
svn.wc.svn_wc_status_incomplete : '!',
svn.wc.svn_wc_status_deleted : 'D',
svn.wc.svn_wc_status_replaced : 'R',
svn.wc.svn_wc_status_modified : 'M',
svn.wc.svn_wc_status_merged : 'G',
svn.wc.svn_wc_status_conflicted : 'C',
svn.wc.svn_wc_status_obstructed : '~',
svn.wc.svn_wc_status_ignored : 'I',
svn.wc.svn_wc_status_external : 'X',
svn.wc.svn_wc_status_unversioned : '?',
}
return code_map.get(status, '?')
def do_status(wc_path, verbose):
# Build a client context baton.
ctx = svn.client.svn_client_ctx_t()
def _status_callback(path, status):
"""A callback function for svn_client_status."""
# Print the path, minus the bit that overlaps with the root of
# the status crawl
text_status = generate_status_code(status.text_status)
prop_status = generate_status_code(status.prop_status)
print '%s%s %s' % (text_status, prop_status, path)
# Do the status crawl, using _status_callback() as our callback function.
revision = svn.core.svn_opt_revision_t()
revision.type = svn.core.svn_opt_revision_head
#~ svn.client.svn_client_status2(wc_path, revision, _status_callback,
#~ svn.core.svn_depth_infinity, verbose,
#~ 0, 0, 1, ctx)
svn.client.svn_client_status3(wc_path, revision, _status_callback,
svn.core.svn_depth_infinity, verbose,
0, 0, 1, (), ctx)
# DO NOT USE svn_client_status4! (needs a C struct argument)
def usage_and_exit(errorcode):
"""Print usage message, and exit with ERRORCODE."""
stream = errorcode and sys.stderr or sys.stdout
stream.write("""Usage: %s OPTIONS WC-PATH
Options:
--help, -h : Show this usage message
--verbose, -v : Show all statuses, even uninteresting ones
""" % (os.path.basename(sys.argv[0])))
sys.exit(errorcode)
if __name__ == '__main__':
# Parse command-line options.
try:
opts, args = getopt.getopt(sys.argv[1:], "hv", ["help", "verbose"])
except getopt.GetoptError:
usage_and_exit(1)
verbose = 0
for opt, arg in opts:
if opt in ("-h", "--help"):
usage_and_exit(0)
if opt in ("-v", "--verbose"):
verbose = 1
if len(args) != 1:
usage_and_exit(2)
# Canonicalize the repository path.
wc_path = svn.core.svn_path_canonicalize(args[0])
# Do the real work.
try:
do_status(wc_path, verbose)
except svn.core.SubversionException, e:
sys.stderr.write("Error (%d): %s\n" % (e.apr_err, e.message))
sys.exit(1)