MCPcopy Create free account
hub / github.com/pybind/pybind11 / test_args_refcount

Function test_args_refcount

tests/test_kwargs_and_defaults.py:419–473  ·  view source on GitHub ↗

Issue/PR #1216 - py::args elements get double-inc_ref()ed when combined with regular arguments

()

Source from the content-addressed store, hash-verified

417
418@pytest.mark.skipif("env.GRAALPY", reason="Different refcounting mechanism")
419def test_args_refcount():
420 """Issue/PR #1216 - py::args elements get double-inc_ref()ed when combined with regular
421 arguments"""
422 refcount = m.arg_refcount_h
423
424 myval = object()
425 expected = refcount(myval)
426 assert m.arg_refcount_h(myval) == expected
427 assert m.arg_refcount_o(myval) == expected + 1
428 assert m.arg_refcount_h(myval) == expected
429 assert refcount(myval) == expected
430
431 assert m.mixed_plus_args(1, 2.0, "a", myval) == (1, 2.0, ("a", myval))
432 assert refcount(myval) == expected
433
434 assert m.mixed_plus_kwargs(3, 4.0, a=1, b=myval) == (3, 4.0, {"a": 1, "b": myval})
435 assert refcount(myval) == expected
436
437 assert m.args_function(-1, myval) == (-1, myval)
438 assert refcount(myval) == expected
439
440 assert m.mixed_plus_args_kwargs(5, 6.0, myval, a=myval) == (
441 5,
442 6.0,
443 (myval,),
444 {"a": myval},
445 )
446 assert refcount(myval) == expected
447
448 assert m.args_kwargs_function(7, 8, myval, a=1, b=myval) == (
449 (7, 8, myval),
450 {"a": 1, "b": myval},
451 )
452 assert refcount(myval) == expected
453
454 assert m.args_kwargs_subclass_function(7, 8, myval, a=1, b=myval) == (
455 (7, 8, myval),
456 {"a": 1, "b": myval},
457 )
458 assert refcount(myval) == expected
459
460 exp3 = refcount(myval, myval, myval)
461 # if we have to create a new tuple internally, then it will hold an extra reference for each item in it.
462 assert m.args_refcount(myval, myval, myval) == (exp3 + 3, exp3 + 3, exp3 + 3)
463 assert refcount(myval) == expected
464
465 # This function takes the first arg as a `py::object` and the rest as a `py::args`. Unlike the
466 # previous case, when we have both positional and `py::args` we need to construct a new tuple
467 # for the `py::args`; in the previous case, we could simply inc_ref and pass on Python's input
468 # tuple without having to inc_ref the individual elements, but here we can't, hence the extra
469 # refs.
470 exp3_3 = exp3 + 3
471 assert m.mixed_args_refcount(myval, myval, myval) == (exp3_3, exp3_3, exp3_3)
472
473 assert m.class_default_argument() == "<class 'decimal.Decimal'>"

Callers

nothing calls this directly

Calls 1

objectFunction · 0.50

Tested by

no test coverage detected