static PyObject *Nuitka_Method_deepcopy( struct Nuitka_MethodObject *method, PyObject *memo ) { assert( Nuitka_Method_Check( (PyObject *)method )); static PyObject *module_copy = NULL; static PyObject *deepcopy_function = NULL; if ( module_copy == NULL ) { module_copy = PyImport_ImportModule( "copy" ); CHECK_OBJECT( module_copy ); deepcopy_function = PyObject_GetAttrString( module_copy, "deepcopy" ); CHECK_OBJECT( deepcopy_function ); } PyObject *object = PyObject_CallFunctionObjArgs( deepcopy_function, method->m_object, memo, NULL ); if (unlikely( object == NULL )) { return NULL; } return Nuitka_Method_New( method->m_function, object, method->m_class ); }
static PyObject *Nuitka_Method_tp_descr_get( struct Nuitka_MethodObject *method, PyObject *object, PyObject *klass ) { // Don't rebind already bound methods. if ( method->m_object != NULL ) { return INCREASE_REFCOUNT( (PyObject *)method ); } if ( method->m_class != NULL && klass != NULL ) { // Quick subclass test, bound methods remain the same if the class is a sub class int result = PyObject_IsSubclass( klass, method->m_class ); if (unlikely( result < 0 )) { return NULL; } else if ( result == 0 ) { return INCREASE_REFCOUNT( (PyObject *)method ); } } return Nuitka_Method_New( method->m_function, object, klass ); }
// tp_descr_get slot, bind a function to an object. static PyObject *Nuitka_Function_descr_get( PyObject *function, PyObject *object, PyObject *klass ) { assert( Nuitka_Function_Check( function ) ); #if PYTHON_VERSION >= 300 if ( object == NULL || object == Py_None ) { return INCREASE_REFCOUNT( function ); } #endif return Nuitka_Method_New( (Nuitka_FunctionObject *)function, object == Py_None ? NULL : object, klass ); }
static PyObject *Nuitka_Method_tp_new( PyTypeObject* type, PyObject* args, PyObject *kw ) { PyObject *func; PyObject *self; PyObject *klass = NULL; if ( !_PyArg_NoKeywords( "instancemethod", kw ) ) { return NULL; } else if ( !PyArg_UnpackTuple( args, "compiled_method", 2, 3, &func, &self, &klass ) ) { return NULL; } else if ( !PyCallable_Check( func ) ) { PyErr_Format( PyExc_TypeError, "first argument must be callable" ); return NULL; } else { if ( self == Py_None ) { self = NULL; } if ( self == NULL && klass == NULL ) { PyErr_Format( PyExc_TypeError, "unbound methods must have non-NULL im_class" ); return NULL; } } assert( Nuitka_Function_Check( func ) ); return Nuitka_Method_New( (struct Nuitka_FunctionObject *)func, self, klass ); }