On 2020/07/28 23:34, C. Michael Pilato wrote: > Hey, all. > > I'm writing some code that performs commits via the Subversion Python > bindings, and I'm struggling to understand some things I see there. > > In the svn_fs.i interface file, there's this block of code: > > /* ----------------------------------------------------------------------- > Fix the return value for svn_fs_commit_txn(). If the conflict result is > NULL, then %append_output() is passed Py_None, but that goofs up > because that is *also* the marker for "I haven't started assembling a > multi-valued return yet" which means the second return value (new_rev) > will not cause a 2-tuple to be manufactured. > > The answer is to explicitly create a 2-tuple return value. > > FIXME: Do the Perl and Ruby bindings need to do something similar? > */ > #ifdef SWIGPYTHON > %typemap(argout) (const char **conflict_p, svn_revnum_t *new_rev) { > /* this is always Py_None */ > Py_DECREF($result); > /* build the result tuple */ > $result = Py_BuildValue("zi", *$1, (long)*$2); > } > #endif
Ah, it returns a tuple of str and int, not a tuple of bytes and int. > This reads and claims to behave exactly as I'd expect, given the dual > return values of svn_fs_commit_txn (and svn_repos_fs_commit_txn which wraps > it). And since this interface file is included from svn_repos.i, I would > expect those typemaps to apply also to svn_repos_fs_commit_txn, which has > matching parameter types and names. It seems it isn't match because svn_repos_fs_commit_txn have extra argument "svn_repos_t *repos" between them. > But this isn't how the code appears to work in practice. A successful > commit gets back from svn.repos.fs_commit_txn not a 2-tuple, but just the > newly created revision number. Moreover, if my commit succeeds but the > post-commit hook fails, svn.repos.fs_commit_txn() raises an Exception, > masking the return of the newly created revision number altogether. Now, > the masked revision number thing I can understand -- it's hard to do in > Python what we promise to do in C (which is to return an svn_error_t but > still set the new_rev return value). But the 2-tuple thing I have no > explanation for. Any ideas? I think it is need one more typemap for it in svn_repos.i like [[[ #ifdef SWIGPYTHON %typemap(argout) (const char **conflict_p, svn_repos_t *repos, svn_revnum_t *new_rev) { /* this is always Py_None */ Py_DECREF($result); /* build the result tuple */ $result = Py_BuildValue("zi", *$1, (long)*$3); } #endif ]]] but I didn't tried yet. Cheers, -- Yasuhito FUTATSUKI <futat...@yf.bsclub.org>