Skip to content

Instantly share code, notes, and snippets.

@jun66j5
Last active May 20, 2020 05:48
Show Gist options
  • Save jun66j5/88ed4adb2658977626ea65a4548ee070 to your computer and use it in GitHub Desktop.
Save jun66j5/88ed4adb2658977626ea65a4548ee070 to your computer and use it in GitHub Desktop.
Handle correctly multiple apr_pool_t * arguments of function in Python
bindings to fix negative ref count of _global_py_pool object.
* subversion/bindings/swig/include/svn_types.swg
(%typemap(default) apr_pool_t *): Retrieve apr_pool_t * pointer from args
parameter only when _global_pool is NULL in order to increase correctly ref
count.
(%typemap(in) apr_pool_t *): Retrieve apr_pool_t * pointer from the Python
object when an argument is not the last apr_pool_t * argument.
(%typemap(freearg) apr_pool_t *): Decreament ref count of Python object only
once.
* subversion/bindings/swig/python/tests/client.py
(test_inherited_props): Add tests which TypeError raises when passing non
apr_pool_t * object to function which has multiple apr_pool_t * arguments.
Index: subversion/bindings/swig/include/svn_types.swg
===================================================================
--- subversion/bindings/swig/include/svn_types.swg (revision 1877889)
+++ subversion/bindings/swig/include/svn_types.swg (working copy)
@@ -554,23 +554,34 @@
%typemap(default, noblock=1) apr_pool_t
*(apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL)
{
- if (svn_swig_py_get_pool_arg(args, $descriptor,
- &_global_py_pool, &_global_pool))
+ if (_global_pool == NULL &&
+ svn_swig_py_get_pool_arg(args, $descriptor, &_global_py_pool,
+ &_global_pool))
SWIG_fail;
$1 = _global_pool;
}
%typemap(in, noblock=1) apr_pool_t * {
- /* Verify that the user supplied a valid pool */
- if ($input != Py_None && $input != _global_py_pool) {
- SWIG_Python_TypeError(SWIG_TypePrettyName($descriptor), $input);
- SWIG_arg_fail($svn_argnum);
- SWIG_fail;
- }
+ if ($input != Py_None && $input != _global_py_pool)
+ {
+ void *ptr;
+ if (svn_swig_py_convert_ptr($input, &ptr, $descriptor) == 0)
+ $1 = ptr;
+ else
+ {
+ SWIG_Python_TypeError(SWIG_TypePrettyName($descriptor), $input);
+ SWIG_arg_fail($svn_argnum);
+ SWIG_fail;
+ }
+ }
}
%typemap(freearg) apr_pool_t * {
- Py_XDECREF(_global_py_pool);
+ if (_global_py_pool != NULL)
+ {
+ Py_XDECREF(_global_py_pool);
+ _global_py_pool = NULL;
+ }
}
#endif
Index: subversion/bindings/swig/python/tests/client.py
===================================================================
--- subversion/bindings/swig/python/tests/client.py (revision 1877889)
+++ subversion/bindings/swig/python/tests/client.py (working copy)
@@ -477,6 +477,10 @@
def test_inherited_props(self):
"""Test inherited props"""
+ pool = core.Pool()
+ result_pool = core.Pool(pool)
+ scratch_pool = core.Pool(pool)
+
trunk_url = self.repos_uri + b'/trunk'
client.propset_remote(b'svn:global-ignores', b'*.q', trunk_url,
False, 12, {}, None, self.client_ctx)
@@ -483,6 +487,12 @@
head = core.svn_opt_revision_t()
head.kind = core.svn_opt_revision_head
+ self.assertRaises(TypeError, client.propget5, b'svn:global-ignores',
+ trunk_url, head, head, core.svn_depth_infinity, None,
+ self.client_ctx, 42)
+ self.assertRaises(TypeError, client.propget5, b'svn:global-ignores',
+ trunk_url, head, head, core.svn_depth_infinity, None,
+ self.client_ctx, None, 42)
props, iprops, rev = client.propget5(b'svn:global-ignores', trunk_url,
head, head, core.svn_depth_infinity,
None, self.client_ctx)
@@ -491,7 +501,8 @@
dir1_url = trunk_url + b'/dir1'
props, iprops, rev = client.propget5(b'svn:global-ignores', dir1_url,
head, head, core.svn_depth_infinity,
- None, self.client_ctx)
+ None, self.client_ctx, result_pool,
+ scratch_pool)
self.assertEqual(iprops[trunk_url], {b'svn:global-ignores':b'*.q\n'})
self.proplist_receiver_trunk_calls = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment