ROOT logo
// @(#)root/pyroot:$Id: TPyReturn.cxx 38562 2011-03-22 22:12:45Z wlav $
// Author: Wim Lavrijsen, May 2004

// Bindings
#include "PyROOT.h"
#include "TPyReturn.h"
#include "ObjectProxy.h"

// ROOT
#include "TObject.h"
#include "TInterpreter.h"

// Standard
#include <stdexcept>


//______________________________________________________________________________
//                        Python expression eval result
//                        =============================
//
// Transport class for bringing objects from python (dynamically typed) to CINT
// (statically typed). It is best to immediately cast a TPyReturn to the real
// type, either implicitly (for builtin types) or explicitly (through a void*
// cast for pointers to ROOT objects).
//
// Examples:
//
//  root [0] TBrowser* b = (void*)TPython::Eval( "ROOT.TBrowser()" );
//  root [1] int i = TPython::Eval( "1+1" );
//  root [2] i
//  (int)2
//  root [3] double d = TPython::Eval( "1+3.1415" );
//  root [4] d
//  (double)4.14150000000000063e+00


//- data ---------------------------------------------------------------------
ClassImp(TPyReturn)


//- constructors/destructor --------------------------------------------------
TPyReturn::TPyReturn()
{
// Construct a TPyReturn object from Py_None.
   Py_INCREF( Py_None );
   fPyObject = Py_None;
}

//____________________________________________________________________________
TPyReturn::TPyReturn( PyObject* pyobject )
{
// Construct a TPyReturn from a python object. The python object may represent
// a ROOT object. Steals reference to given python object.
   if ( ! pyobject ) {
      Py_INCREF( Py_None );
      fPyObject = Py_None;
   } else
      fPyObject = pyobject;             // steals reference
}

//____________________________________________________________________________
TPyReturn::TPyReturn( const TPyReturn& other )
{
// Copy constructor. Applies python object reference counting.
   Py_INCREF( other.fPyObject );
   fPyObject = other.fPyObject;
}

//____________________________________________________________________________
TPyReturn& TPyReturn::operator=( const TPyReturn& other )
{
// Assignment operator. Applies python object reference counting.
   if ( this != &other ) {
      Py_INCREF( other.fPyObject );
      Py_DECREF( fPyObject );
      fPyObject = other.fPyObject;
   }
   
   return *this;
}

//____________________________________________________________________________
TPyReturn::~TPyReturn()
{
// Destructor. Reference counting for the held python object is in effect.
   Py_DECREF( fPyObject );
}


//- public members -----------------------------------------------------------
TPyReturn::operator const char*() const
{
// Cast python return value to C-style string (may fail).
   if ( fPyObject == Py_None )     // for void returns
      return 0;

   const char* s = PyBytes_AsString( fPyObject );
   if ( PyErr_Occurred() ) {
      PyErr_Print();
      return 0;
   }

   return s;
}

//____________________________________________________________________________
TPyReturn::operator Char_t() const
{
// Cast python return value to C++ char (may fail).
   std::string s = operator const char*();
   if ( s.size() )
      return s[0];

   return '\0';
}

//____________________________________________________________________________
TPyReturn::operator Long_t() const
{
// Cast python return value to C++ long (may fail).
   Long_t l = PyLong_AsLong( fPyObject );

   if ( PyErr_Occurred() )
      PyErr_Print();

   return l;
}

//____________________________________________________________________________
TPyReturn::operator ULong_t() const
{
// Cast python return value to C++ unsigned long (may fail).
   ULong_t ul = PyLong_AsUnsignedLong( fPyObject );

   if ( PyErr_Occurred() )
      PyErr_Print();

   return ul;
}


//____________________________________________________________________________
TPyReturn::operator Double_t() const
{
// Cast python return value to to C++ double (may fail).
   Double_t d = PyFloat_AsDouble( fPyObject );

   if ( PyErr_Occurred() )
      PyErr_Print();

   return d;
}

//____________________________________________________________________________
TPyReturn::operator void*() const
{
// Cast python return value to ROOT object with dictionary (may fail; note that
// you have to use the void* converter, as CINT will not call any other).
   if ( fPyObject == Py_None )
      return 0;

   if ( PyROOT::ObjectProxy_Check( fPyObject ) ) {
      ((PyROOT::ObjectProxy*)fPyObject)->Release();
      return ((PyROOT::ObjectProxy*)fPyObject)->GetObject();
   } else 
      return fPyObject;                 // borrows reference
}

//____________________________________________________________________________
TPyReturn::operator PyObject*() const
{
// Direct return of the held PyObject; note the new reference.
   if ( fPyObject == Py_None )
      return 0;

   Py_INCREF( fPyObject );
   return fPyObject;
}
 TPyReturn.cxx:1
 TPyReturn.cxx:2
 TPyReturn.cxx:3
 TPyReturn.cxx:4
 TPyReturn.cxx:5
 TPyReturn.cxx:6
 TPyReturn.cxx:7
 TPyReturn.cxx:8
 TPyReturn.cxx:9
 TPyReturn.cxx:10
 TPyReturn.cxx:11
 TPyReturn.cxx:12
 TPyReturn.cxx:13
 TPyReturn.cxx:14
 TPyReturn.cxx:15
 TPyReturn.cxx:16
 TPyReturn.cxx:17
 TPyReturn.cxx:18
 TPyReturn.cxx:19
 TPyReturn.cxx:20
 TPyReturn.cxx:21
 TPyReturn.cxx:22
 TPyReturn.cxx:23
 TPyReturn.cxx:24
 TPyReturn.cxx:25
 TPyReturn.cxx:26
 TPyReturn.cxx:27
 TPyReturn.cxx:28
 TPyReturn.cxx:29
 TPyReturn.cxx:30
 TPyReturn.cxx:31
 TPyReturn.cxx:32
 TPyReturn.cxx:33
 TPyReturn.cxx:34
 TPyReturn.cxx:35
 TPyReturn.cxx:36
 TPyReturn.cxx:37
 TPyReturn.cxx:38
 TPyReturn.cxx:39
 TPyReturn.cxx:40
 TPyReturn.cxx:41
 TPyReturn.cxx:42
 TPyReturn.cxx:43
 TPyReturn.cxx:44
 TPyReturn.cxx:45
 TPyReturn.cxx:46
 TPyReturn.cxx:47
 TPyReturn.cxx:48
 TPyReturn.cxx:49
 TPyReturn.cxx:50
 TPyReturn.cxx:51
 TPyReturn.cxx:52
 TPyReturn.cxx:53
 TPyReturn.cxx:54
 TPyReturn.cxx:55
 TPyReturn.cxx:56
 TPyReturn.cxx:57
 TPyReturn.cxx:58
 TPyReturn.cxx:59
 TPyReturn.cxx:60
 TPyReturn.cxx:61
 TPyReturn.cxx:62
 TPyReturn.cxx:63
 TPyReturn.cxx:64
 TPyReturn.cxx:65
 TPyReturn.cxx:66
 TPyReturn.cxx:67
 TPyReturn.cxx:68
 TPyReturn.cxx:69
 TPyReturn.cxx:70
 TPyReturn.cxx:71
 TPyReturn.cxx:72
 TPyReturn.cxx:73
 TPyReturn.cxx:74
 TPyReturn.cxx:75
 TPyReturn.cxx:76
 TPyReturn.cxx:77
 TPyReturn.cxx:78
 TPyReturn.cxx:79
 TPyReturn.cxx:80
 TPyReturn.cxx:81
 TPyReturn.cxx:82
 TPyReturn.cxx:83
 TPyReturn.cxx:84
 TPyReturn.cxx:85
 TPyReturn.cxx:86
 TPyReturn.cxx:87
 TPyReturn.cxx:88
 TPyReturn.cxx:89
 TPyReturn.cxx:90
 TPyReturn.cxx:91
 TPyReturn.cxx:92
 TPyReturn.cxx:93
 TPyReturn.cxx:94
 TPyReturn.cxx:95
 TPyReturn.cxx:96
 TPyReturn.cxx:97
 TPyReturn.cxx:98
 TPyReturn.cxx:99
 TPyReturn.cxx:100
 TPyReturn.cxx:101
 TPyReturn.cxx:102
 TPyReturn.cxx:103
 TPyReturn.cxx:104
 TPyReturn.cxx:105
 TPyReturn.cxx:106
 TPyReturn.cxx:107
 TPyReturn.cxx:108
 TPyReturn.cxx:109
 TPyReturn.cxx:110
 TPyReturn.cxx:111
 TPyReturn.cxx:112
 TPyReturn.cxx:113
 TPyReturn.cxx:114
 TPyReturn.cxx:115
 TPyReturn.cxx:116
 TPyReturn.cxx:117
 TPyReturn.cxx:118
 TPyReturn.cxx:119
 TPyReturn.cxx:120
 TPyReturn.cxx:121
 TPyReturn.cxx:122
 TPyReturn.cxx:123
 TPyReturn.cxx:124
 TPyReturn.cxx:125
 TPyReturn.cxx:126
 TPyReturn.cxx:127
 TPyReturn.cxx:128
 TPyReturn.cxx:129
 TPyReturn.cxx:130
 TPyReturn.cxx:131
 TPyReturn.cxx:132
 TPyReturn.cxx:133
 TPyReturn.cxx:134
 TPyReturn.cxx:135
 TPyReturn.cxx:136
 TPyReturn.cxx:137
 TPyReturn.cxx:138
 TPyReturn.cxx:139
 TPyReturn.cxx:140
 TPyReturn.cxx:141
 TPyReturn.cxx:142
 TPyReturn.cxx:143
 TPyReturn.cxx:144
 TPyReturn.cxx:145
 TPyReturn.cxx:146
 TPyReturn.cxx:147
 TPyReturn.cxx:148
 TPyReturn.cxx:149
 TPyReturn.cxx:150
 TPyReturn.cxx:151
 TPyReturn.cxx:152
 TPyReturn.cxx:153
 TPyReturn.cxx:154
 TPyReturn.cxx:155
 TPyReturn.cxx:156
 TPyReturn.cxx:157
 TPyReturn.cxx:158
 TPyReturn.cxx:159
 TPyReturn.cxx:160
 TPyReturn.cxx:161
 TPyReturn.cxx:162
 TPyReturn.cxx:163
 TPyReturn.cxx:164
 TPyReturn.cxx:165
 TPyReturn.cxx:166
 TPyReturn.cxx:167
 TPyReturn.cxx:168
 TPyReturn.cxx:169
 TPyReturn.cxx:170
 TPyReturn.cxx:171
 TPyReturn.cxx:172
 TPyReturn.cxx:173
 TPyReturn.cxx:174
 TPyReturn.cxx:175
 TPyReturn.cxx:176
 TPyReturn.cxx:177
 TPyReturn.cxx:178