예제 #1
0
 // tp_repr slot, decide how a function shall be output
static PyObject *Nuitka_Method_tp_repr( Nuitka_MethodObject *method )
{
    if ( method->m_object == NULL )
    {
#if PYTHON_VERSION < 300
        return PyString_FromFormat(
            "<unbound compiled_method %s.%s>",
            GET_CLASS_NAME( method->m_class ),
            Nuitka_String_AsString( method->m_function->m_name )
        );
#else
        return PyUnicode_FromFormat(
            "<compiled function %s at %p>",
            Nuitka_String_AsString( method->m_function->m_name ),
            method->m_function
        );
#endif
    }
    else
    {
        // Note: CPython uses repr ob the object, although a comment despises
        // it, we do it for compatibility.
        PyObject *object_repr = PyObject_Repr( method->m_object );

        if ( object_repr == NULL )
        {
            return NULL;
        }
#if PYTHON_VERSION < 300
        else if ( !PyString_Check( object_repr ) )
        {
            Py_DECREF( object_repr );
            return NULL;
        }
#else
        else if ( !PyUnicode_Check( object_repr ) )
        {
            Py_DECREF( object_repr );
            return NULL;
        }
#endif

#if PYTHON_VERSION < 300
        PyObject *result = PyString_FromFormat(
#else
        PyObject *result = PyUnicode_FromFormat(
#endif
            "<bound compiled_method %s.%s of %s>",
            GET_CLASS_NAME( method->m_class ),
            Nuitka_String_AsString( method->m_function->m_name ),
            Nuitka_String_AsString_Unchecked( object_repr )
        );

        Py_DECREF( object_repr );

        return result;
    }
}
예제 #2
0
bool SET_ATTRIBUTE(PyObject *target, PyObject *attr_name, PyObject *value) {
    CHECK_OBJECT(target);
    CHECK_OBJECT(attr_name);
    CHECK_OBJECT(value);

#if PYTHON_VERSION < 300
    if (PyInstance_Check(target)) {
        return SET_INSTANCE(target, attr_name, value);
    } else
#endif
    {
        PyTypeObject *type = Py_TYPE(target);

        if (type->tp_setattro != NULL) {
            int status = (*type->tp_setattro)(target, attr_name, value);

            if (unlikely(status == -1)) {
                return false;
            }
        } else if (type->tp_setattr != NULL) {
            int status = (*type->tp_setattr)(target, (char *)Nuitka_String_AsString_Unchecked(attr_name), value);

            if (unlikely(status == -1)) {
                return false;
            }
        } else if (type->tp_getattr == NULL && type->tp_getattro == NULL) {
            PyErr_Format(PyExc_TypeError, "'%s' object has no attributes (assign to %s)", type->tp_name,
                         Nuitka_String_AsString_Unchecked(attr_name));

            return false;
        } else {
            PyErr_Format(PyExc_TypeError, "'%s' object has only read-only attributes (assign to %s)", type->tp_name,
                         Nuitka_String_AsString_Unchecked(attr_name));

            return false;
        }
    }

    return true;
}
예제 #3
0
PyObject *LOOKUP_ATTRIBUTE(PyObject *source, PyObject *attr_name) {
    /* Note: There are 2 specializations of this function, that need to be
     * updated in line with this: LOOKUP_ATTRIBUTE_[DICT|CLASS]_SLOT
     */

    CHECK_OBJECT(source);
    CHECK_OBJECT(attr_name);

    PyTypeObject *type = Py_TYPE(source);

    if (type->tp_getattro == PyObject_GenericGetAttr) {
        // Unfortunately this is required, although of cause rarely necessary.
        if (unlikely(type->tp_dict == NULL)) {
            if (unlikely(PyType_Ready(type) < 0)) {
                return NULL;
            }
        }

        PyObject *descr = _PyType_Lookup(type, attr_name);
        descrgetfunc func = NULL;

        if (descr != NULL) {
            Py_INCREF(descr);

#if PYTHON_VERSION < 300
            if (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS)) {
#endif
                func = Py_TYPE(descr)->tp_descr_get;

                if (func != NULL && PyDescr_IsData(descr)) {
                    PyObject *result = func(descr, source, (PyObject *)type);
                    Py_DECREF(descr);

                    return result;
                }
#if PYTHON_VERSION < 300
            }
#endif
        }

        Py_ssize_t dictoffset = type->tp_dictoffset;
        PyObject *dict = NULL;

        if (dictoffset != 0) {
            // Negative dictionary offsets have special meaning.
            if (dictoffset < 0) {
                Py_ssize_t tsize;
                size_t size;

                tsize = ((PyVarObject *)source)->ob_size;
                if (tsize < 0)
                    tsize = -tsize;
                size = _PyObject_VAR_SIZE(type, tsize);

                dictoffset += (long)size;
            }

            PyObject **dictptr = (PyObject **)((char *)source + dictoffset);
            dict = *dictptr;
        }

        if (dict != NULL) {
            CHECK_OBJECT(dict);

            Py_INCREF(dict);

            PyObject *result = PyDict_GetItem(dict, attr_name);

            if (result != NULL) {
                Py_INCREF(result);
                Py_XDECREF(descr);
                Py_DECREF(dict);

                CHECK_OBJECT(result);
                return result;
            }

            Py_DECREF(dict);
        }

        if (func != NULL) {
            PyObject *result = func(descr, source, (PyObject *)type);
            Py_DECREF(descr);

            CHECK_OBJECT(result);
            return result;
        }

        if (descr != NULL) {
            CHECK_OBJECT(descr);
            return descr;
        }

#if PYTHON_VERSION < 300
        PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type->tp_name,
                     PyString_AS_STRING(attr_name));
#else
        PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%U'", type->tp_name, attr_name);
#endif
        return NULL;
    }
#if PYTHON_VERSION < 300
    else if (type->tp_getattro == PyInstance_Type.tp_getattro) {
        PyObject *result = LOOKUP_INSTANCE(source, attr_name);
        return result;
    }
#endif
    else if (type->tp_getattro != NULL) {
        PyObject *result = (*type->tp_getattro)(source, attr_name);

        if (unlikely(result == NULL)) {
            return NULL;
        }

        CHECK_OBJECT(result);
        return result;
    } else if (type->tp_getattr != NULL) {
        PyObject *result = (*type->tp_getattr)(source, (char *)Nuitka_String_AsString_Unchecked(attr_name));
        return result;
    } else {
        PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '%s'", type->tp_name,
                     Nuitka_String_AsString_Unchecked(attr_name));

        return NULL;
    }
}
예제 #4
0
NUITKA_MAY_BE_UNUSED static PyObject *TO_UNICODE3( PyObject *value, PyObject *encoding, PyObject *errors )
{
    CHECK_OBJECT( value );
    if ( encoding ) CHECK_OBJECT( encoding );
    if ( errors ) CHECK_OBJECT( errors );

    char *encoding_str;

    if ( encoding == NULL )
    {
        encoding_str = NULL;
    }
    else if ( Nuitka_String_Check( encoding ) )
    {
        encoding_str = Nuitka_String_AsString_Unchecked( encoding );
    }
#if PYTHON_VERSION < 300
    else if ( PyUnicode_Check( encoding ) )
    {
        PyObject *uarg2 = _PyUnicode_AsDefaultEncodedString( encoding, NULL );
        CHECK_OBJECT( uarg2 );

        encoding_str = Nuitka_String_AsString_Unchecked( uarg2 );
    }
#endif
    else
    {
        PyErr_Format( PyExc_TypeError, "unicode() argument 2 must be string, not %s", Py_TYPE( encoding )->tp_name );
        return NULL;
    }

    char *errors_str;

    if ( errors == NULL )
    {
        errors_str = NULL;
    }
    else if ( Nuitka_String_Check( errors ) )
    {
        errors_str = Nuitka_String_AsString_Unchecked( errors );
    }
#if PYTHON_VERSION < 300
    else if ( PyUnicode_Check( errors ) )
    {
        PyObject *uarg3 = _PyUnicode_AsDefaultEncodedString( errors, NULL );
        CHECK_OBJECT( uarg3 );

        errors_str = Nuitka_String_AsString_Unchecked( uarg3 );
    }
#endif
    else
    {
        PyErr_Format( PyExc_TypeError, "unicode() argument 3 must be string, not %s", Py_TYPE( errors )->tp_name );
        return NULL;
    }

    PyObject *result = PyUnicode_FromEncodedObject( value, encoding_str, errors_str );

    if (unlikely( result == NULL ))
    {
        return NULL;
    }

    assert( PyUnicode_Check( result ) );

    return result;
}