Std::shared_ptr::reset in PyROOT


ROOT Version: 6.16.00
Platform: macOS 10.14
Compiler: Clang 10.0.1


How do I access std::shared_ptr::reset in PyROOT?

In [1]: import ROOT                                                             

In [2]: ROOT.gROOT.ProcessLine('std::shared_ptr<TCanvas> can;')                 
Out[2]: 4550143272

In [3]: ROOT.can.reset                                                          
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-7cd261822618> in <module>
----> 1 ROOT.can.reset

AttributeError: 'TCanvas' object has no attribute 'reset'

Hi @oxon ,

You can do:

ROOT.can.__smartptr__().reset()

Cheers,
Enric

Thank you. As I could not find __smartptr__, I tried using _get_smart_ptr instead. But I could not reset the pointer because of a template issue. Could you please tell me how to fix it again?

In [2]: import ROOT                                                                                         

In [3]: ROOT.gROOT.ProcessLine('std::shared_ptr<TCanvas> can(new TCanvas());')                              
Out[3]: 4431397272

In [5]: ROOT.can.__smartptr__()                                                                                    
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-e56709dfe148> in <module>
----> 1 c.__smartptr__()

AttributeError: 'TCanvas' object has no attribute '__smartptr__'

In [7]: ROOT.can._get_smart_ptr()                                                                           
Out[7]: <ROOT.shared_ptr<TCanvas> object at 0x10821c198>

In [8]: ROOT.can._get_smart_ptr().reset                                                                     
Out[8]: <ROOT.TemplateProxy at 0x11cc70ef8>

In [9]: ROOT.can._get_smart_ptr().reset(ROOT.TCanvas())                                                     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-92b0cbd81331> in <module>
----> 1 ROOT.can._get_smart_ptr().reset(ROOT.TCanvas())

TypeError: can not resolve method template call for 'reset'

Hi,

That looks like a bug in the template proxy. I created an issue for it:

https://sft.its.cern.ch/jira/browse/ROOT-10245

In the meantime, just like you create the smart pointer in C++ with ProcessLine, you could also reset its value via the same mechanism.

Cheers,
Enric

Thanks a lot. ProcessLine works, and it is good enough for the moment.

Just for fun, the current state of smart ptr’s in cppyy can now create them from python classes derived from (abstract) C++ ones and take care of all the memory handling, see below. Soon enough things like reset() will not be needed anymore. :slight_smile:

import cppyy

cppyy.cppdef("""
class AbstractCommand {
public:
    virtual ~AbstractCommand() { std::cerr << "command destroyed " << std::endl; }
    virtual int run() = 0;
};

int run_command(std::shared_ptr<AbstractCommand> ptr) {
    return ptr->run();
}
""")

from cppyy.interactive import *

class PyCommand(AbstractCommand):
    def __init__(self, val):
        super(PyCommand, self).__init__()
        self.val = val

    def run(self):
         print("Running PyCommand ...")
         return self.val

v = std.make_shared[PyCommand](42)

print(run_command(v))
del v
print('done')

which outputs:

Running PyCommand ...
42
command destroyed 
done

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.