Beispiel #1
0
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 );
}
Beispiel #2
0
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
    );
}
Beispiel #4
0
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 );
}