<commit_before>// @(#)root/pyroot:$Id$
// Author: <NAME>, Apr 2004

// Bindings
#include "PyROOT.h"
#include "TConstructorHolder.h"
#include "Adapters.h"
#include "Executors.h"
#include "ObjectProxy.h"
#include "TMemoryRegulator.h"

// ROOT
#include "TClass.h"
#include "TFunction.h"

// Standard
#include <string>


//- protected members --------------------------------------------------------
Bool_t PyROOT::TConstructorHolder::InitExecutor_( TExecutor*& executor )
{
// pick up special case new object executor
   executor = (gExecFactories[ "__init__" ])();
   return kTRUE;
}

//- constructors -------------------------------------------------------------
PyROOT::TConstructorHolder::TConstructorHolder( const TScopeAdapter& klass ) :
      TMethodHolder( klass, (TFunction*)0 )
{
}

//____________________________________________________________________________
PyROOT::TConstructorHolder::TConstructorHolder( const TScopeAdapter& klass, const TMemberAdapter& method ) :
      TMethodHolder( klass, method )
{
}

//- public members -----------------------------------------------------------
PyObject* PyROOT::TConstructorHolder::GetDocString()
{
// GetMethod() may return an empty function if this is just a special case place holder
   std::string clName = this->GetClass().Name();
   return PyROOT_PyUnicode_FromFormat( "%s::%s%s",
      clName.c_str(), clName.c_str(), this->GetMethod() ? this->GetSignatureString().c_str() : "()" );
}

//____________________________________________________________________________
PyObject* PyROOT::TConstructorHolder::operator()(
      ObjectProxy* self, PyObject* args, PyObject* kwds, Long_t user, Bool_t release_gil )
{
// preliminary check in case keywords are accidently used (they are ignored otherwise)
   if ( kwds != 0 && PyDict_Size( kwds ) ) {
      PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
      return 0;
   }

// do not allow instantiation of abstract classes
   if ( this->GetClass().IsAbstract() ) {
      PyErr_Format( PyExc_TypeError,
         "%s is abstract and can not be instantiated", this->GetClass().Name().c_str() );
      return 0;
   }

// setup as necessary
   if ( ! this->Initialize() )
      return 0;                              // important: 0, not Py_None

// fetch self, verify, and put the arguments in usable order
   if ( ! ( args = this->FilterArgs( self, args, kwds ) ) )
      return 0;

// translate the arguments
   if ( ! this->SetMethodArgs( args, user ) ) {
      Py_DECREF( args );
      return 0;
   }

   TClass* klass = (TClass*)this->GetClass().Id();

// perform the call, 0 makes the other side allocate the memory
   Long_t address = (Long_t)this->Execute( 0, release_gil );

// done with filtered args
   Py_DECREF( args );<commit_msg>see discussion on ROOT-5623 ... hopefully this makes both Marco and Philippe happy<commit_after>// @(#)root/pyroot:$Id$
// Author: <NAME>, Apr 2004

// Bindings
#include "PyROOT.h"
#include "TConstructorHolder.h"
#include "Adapters.h"
#include "Executors.h"
#include "ObjectProxy.h"
#include "TMemoryRegulator.h"

// ROOT
#include "TClass.h"
#include "TFunction.h"

// Standard
#include <string>


//- protected members --------------------------------------------------------
Bool_t PyROOT::TConstructorHolder::InitExecutor_( TExecutor*& executor )
{
// pick up special case new object executor
   executor = (gExecFactories[ "__init__" ])();
   return kTRUE;
}

//- constructors -------------------------------------------------------------
PyROOT::TConstructorHolder::TConstructorHolder( const TScopeAdapter& klass ) :
      TMethodHolder( klass, (TFunction*)0 )
{
}

//____________________________________________________________________________
PyROOT::TConstructorHolder::TConstructorHolder( const TScopeAdapter& klass, const TMemberAdapter& method ) :
      TMethodHolder( klass, method )
{
}

//- public members -----------------------------------------------------------
PyObject* PyROOT::TConstructorHolder::GetDocString()
{
// GetMethod() may return an empty function if this is just a special case place holder
   std::string clName = this->GetClass().Name();
   return PyROOT_PyUnicode_FromFormat( "%s::%s%s",
      clName.c_str(), clName.c_str(), this->GetMethod() ? this->GetSignatureString().c_str() : "()" );
}

//____________________________________________________________________________
PyObject* PyROOT::TConstructorHolder::operator()(
      ObjectProxy* self, PyObject* args, PyObject* kwds, Long_t user, Bool_t release_gil )
{
// preliminary check in case keywords are accidently used (they are ignored otherwise)
   if ( kwds != 0 && PyDict_Size( kwds ) ) {
      PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
      return 0;
   }

// do not allow instantiation of abstract classes
   if ( this->GetClass().IsAbstract() ) {
      PyErr_Format( PyExc_TypeError,
         "%s is abstract and can not be instantiated", this->GetClass().Name().c_str() );
      return 0;
   }

// setup as necessary
   if ( ! this->Initialize() )
      return 0;                              // important: 0, not Py_None

// fetch self, verify, and put the arguments in usable order
   if ( ! ( args = this->FilterArgs( self, args, kwds ) ) )
      return 0;

// translate the arguments
   if ( ! this->SetMethodArgs( args, user ) ) {
      Py_DECREF( args );
      return 0;
   }

   TClass* klass = (TClass*)this->GetClass().Id();

// perform the call, 0 makes the other side allocate the memory
   Long_t address = (Long_t)this->Execute( 0, release_gil );

// CLING WORKAROUND --
// Due to #100389, the constructor may not be a valid method. This happens if
// there is no (default) contructor, so just return a right-size bit of memory.
   if ( ! address ) {
      if ( PyErr_Occurred() ) PyErr_Print();
      // CLING WORKAROUND --
      // Theoretically, #100389 is fixed, but there are subtle ways that this
      // still fails. For whatever reason (TBD) simply calling the method again
      // has a high success rate
      address = (Long_t)this->Execute( 0, release_gil );
      // -- END (NESTED) CLING WORKAROUND
      if ( ! address ) {
         if ( PyErr_Occurred() ) PyErr_Print();
         address = (Long_t)klass->New();
      }
   }
// -- END CLING WORKAROUND
 
// done with filtered args
   Py_DECREF( args );
{'fraction_non_alphanumeric': 0.1744955863808323, 'fraction_numerical': 0.007093316519546027, 'mean_word_length': 2.803956834532374, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2546400', 'n_tokens_mistral': 1841, 'n_tokens_neox': 1798, 'n_words': 528}