Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions bindings/pyroot/cppyy/CPyCppyy/src/CPPInstance.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// Standard
#include <algorithm>
#include <sstream>
#include <iostream>


//- data _____________________________________________________________________
Expand Down Expand Up @@ -211,6 +212,9 @@ void CPyCppyy::op_dealloc_nofree(CPPInstance* pyobj) {
Cppyy::TCppType_t klass = pyobj->ObjectIsA(false /* check_smart */);
void*& cppobj = pyobj->GetObjectRaw();

if(cppobj == nullptr)
std::cout << "op_dealloc_noree with nullptr" << std::endl;

if (pyobj->fFlags & CPPInstance::kIsRegulated)
MemoryRegulator::UnregisterPyObject(pyobj, (PyObject*)Py_TYPE((PyObject*)pyobj));

Expand Down Expand Up @@ -447,20 +451,8 @@ static CPPInstance* op_new(PyTypeObject* subtype, PyObject*, PyObject*)
static void op_dealloc(CPPInstance* pyobj)
{
// Remove (Python-side) memory held by the object proxy.
PyObject_GC_UnTrack((PyObject*)pyobj);
op_dealloc_nofree(pyobj);
PyObject_GC_Del((PyObject*)pyobj);
Comment on lines -450 to -452
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should have PyObject_GC_UnTrack and the flag Py_TPFLAGS_HAVE_GC. One thing I can think of is a LinkedList kind of a case where the object as reference to itself.
I experimented with a few use cases, but the required destructor ran even without the Py_TPFLAGS_HAVE_GC flag.

But PyObject_GC_Del should be changed to Py_TYPE(pyobj)->tp_free((PyObject*)pyobj);

}

//----------------------------------------------------------------------------
static int op_clear(CPPInstance* pyobj)
{
// Garbage collector clear of held python member objects; this is a good time
// to safely remove this object from the memory regulator.
if (pyobj->fFlags & CPPInstance::kIsRegulated)
MemoryRegulator::UnregisterPyObject(pyobj, (PyObject*)Py_TYPE((PyObject*)pyobj));

return 0;
Py_TYPE(pyobj)->tp_free((PyObject*)pyobj);
}

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -1086,11 +1078,10 @@ PyTypeObject CPPInstance_Type = {
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_HAVE_GC, // tp_flags
Py_TPFLAGS_CHECKTYPES, // tp_flags
(char*)"cppyy object proxy (internal)", // tp_doc
(traverseproc)op_traverse, // tp_traverse
(inquiry)op_clear, // tp_clear
0, // tp_clear
(richcmpfunc)op_richcompare, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
Expand Down
2 changes: 2 additions & 0 deletions bindings/pyroot/cppyy/CPyCppyy/src/TemplateProxy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// Standard
#include <algorithm>
#include <iostream>


namespace CPyCppyy {
Expand Down Expand Up @@ -200,6 +201,7 @@ PyObject* TemplateProxy::Instantiate(const std::string& fname,
// can add already existing overloads to the set of methods.

std::string resname = Cppyy::GetMethodFullName(cppmeth);
std::cout << "resname : " << resname << std::endl;

// An initializer_list is preferred for the argument types, but should not leak into
// the argument types. If it did, replace with vector and lookup anew.
Expand Down
2 changes: 2 additions & 0 deletions bindings/pyroot/cppyy/cppyy/test/templates.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include <typeinfo>
#include <vector>
#include <iostream>

#ifndef _WIN32
#include <cxxabi.h>
Expand Down Expand Up @@ -530,6 +531,7 @@ using testptr = Test *;
template <typename T>
bool testfun(T const &x)
{
std::cout << "testfun " << x << std::endl;
return !(bool)x;
}

Expand Down
9 changes: 8 additions & 1 deletion bindings/pyroot/cppyy/cppyy/test/test_templates.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest, os

Check failure on line 1 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:1:16: F401 `os` imported but unused

Check failure on line 1 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E401)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:1:1: E401 Multiple imports on one line
from pytest import mark, raises
from support import setup_make, pylong, IS_WINDOWS

Check failure on line 3 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:3:41: F401 `support.IS_WINDOWS` imported but unused

Check failure on line 3 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:3:21: F401 `support.setup_make` imported but unused

Check failure on line 3 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:1:1: I001 Import block is un-sorted or un-formatted

Expand All @@ -23,8 +23,8 @@
def test01_template_member_functions(self):
"""Template member functions lookup and calls"""

import cppyy
import sys

Check failure on line 27 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:26:9: I001 Import block is un-sorted or un-formatted

m = cppyy.gbl.MyTemplatedMethodClass()

Expand All @@ -40,7 +40,7 @@
if sys.hexversion >= 0x3000000:
targ = 'long'
else:
targ = long

Check failure on line 43 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F821)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:43:20: F821 Undefined name `long`
assert m.get_size[targ]() == m.get_long_size()

import ctypes
Expand Down Expand Up @@ -104,15 +104,15 @@
from cppyy.gbl.std import vector
# float in, float out
ggsr = cppyy.gbl.global_get_some_result['std::vector<float>']
assert type(ggsr(vector['float']([0.5])).m_retval) == float

Check failure on line 107 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E721)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:107:16: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
assert ggsr(vector['float']([0.5])).m_retval == 0.5
# int in, float out
ggsr = cppyy.gbl.global_get_some_result['std::vector<int>']
assert type(ggsr(vector['int']([5])).m_retval) == float

Check failure on line 111 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E721)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:111:16: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
assert ggsr(vector['int']([5])).m_retval == 5.
# float in, int out
ggsr = cppyy.gbl.global_get_some_result['std::vector<float>, int']
assert type(ggsr(vector['float']([0.3])).m_retval) == int

Check failure on line 115 in bindings/pyroot/cppyy/cppyy/test/test_templates.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E721)

bindings/pyroot/cppyy/cppyy/test/test_templates.py:115:16: E721 Use `is` and `is not` for type comparisons, or `isinstance()` for isinstance checks
assert ggsr(vector['float']([0.3])).m_retval == 0
# int in, int out
ggsr = cppyy.gbl.global_get_some_result['std::vector<int>, int']
Expand Down Expand Up @@ -1133,16 +1133,23 @@

assert ns.testfun["testptr"](cppyy.bind_object(cppyy.nullptr, ns.Test))

print("step 1 done")

# TODO: raises TypeError; the problem is that the type is resolved
# from UsingPtr::Test*const& to UsingPtr::Test*& (ie. `const` is lost)
# assert ns.testfun["UsingPtr::testptr"](cppyy.nullptr)

assert ns.testptr.__name__ == "Test"
print("step 2 done")
assert ns.testptr.__cpp_name__ == "UsingPtr::Test*"
print("step 3 done")

assert cppyy.gbl.std.vector[ns.Test]
print("step 4 done")
assert ns.testptr
print("step 5 done")
assert cppyy.gbl.std.vector[ns.testptr]
print("step 6 done")

@mark.xfail(strict=True)
def test34_cstring_template_argument(self):
Expand Down Expand Up @@ -1410,4 +1417,4 @@


if __name__ == "__main__":
exit(pytest.main(args=['-v', '-ra', __file__]))
exit(pytest.main(args=['-sv', '-ra', __file__]))
Loading