Пример #1
0
Файл: gcmodule.c Проект: d11/rts
/* Return true if object has a finalization method. */
static int
has_finalizer(PyObject *op)
{
    /* first, dynamic decision per object */
    traverseproc traverse;
    int collectable;
    traverse = Py_TYPE(op)->tp_traverse;
    collectable = -1;
    (void) traverse(op,
                    (visitproc)visit_has_finalizer,
                    (void *)&collectable);
    if (collectable >= 0)
        return collectable == 0;

    if ( PyType_Check(op)) {
        assert(delstr != NULL);
        return _PyType_Lookup(Py_TYPE(op), delstr) != NULL;
    }
    else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
        return op->ob_type->tp_del != NULL;
    else if (PyGen_CheckExact(op))
        return PyGen_NeedsFinalizing((PyGenObject *)op);
    else
        return op->ob_type->tp_del != NULL;
}
Пример #2
0
/* Coerce two numeric types to the "larger" one.
   Increment the reference count on each argument.
   Return value:
   -1 if an error occurred;
   0 if the coercion succeeded (and then the reference counts are increased);
   1 if no coercion is possible (and no error is raised).
*/
int
PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
{
	register PyObject *v = *pv;
	register PyObject *w = *pw;
	int res;

	/* Shortcut only for old-style types */
	if (v->ob_type == w->ob_type &&
	    !PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
	{
		Py_INCREF(v);
		Py_INCREF(w);
		return 0;
	}
	if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
		res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
		if (res <= 0)
			return res;
	}
	if (w->ob_type->tp_as_number && w->ob_type->tp_as_number->nb_coerce) {
		res = (*w->ob_type->tp_as_number->nb_coerce)(pw, pv);
		if (res <= 0)
			return res;
	}
	return 1;
}
Пример #3
0
static PyObject *Nuitka_Method_tp_getattro( struct Nuitka_MethodObject *method, PyObject *name )
{
    PyObject *descr = _PyType_Lookup( &Nuitka_Method_Type, name );

    if ( descr != NULL )
    {
        if (
#if PYTHON_VERSION < 300
            PyType_HasFeature( Py_TYPE( descr ), Py_TPFLAGS_HAVE_CLASS ) &&
#endif
            ( Py_TYPE( descr )->tp_descr_get != NULL )
           )
        {
            return Py_TYPE( descr )->tp_descr_get(
                descr,
                (PyObject *)method,
                (PyObject *)Py_TYPE( method )
            );
        }
        else
        {
            return INCREASE_REFCOUNT( descr );
        }
    }

    return PyObject_GetAttr( (PyObject *)method->m_function, name );
}
Пример #4
0
/* Taken from http://bugs.python.org/issue8212
 * A function to do the necessary adjustments if we find that code
 * run during a tp_dealloc or tp_free has resurrected an
 * object.  It adjusts the total reference count and adds a new
 * reference to the type.
 */
static void
resurrect_object(PyObject *self)
{
    /* The object lives again. We must now undo the _Py_ForgetReference
     * done in _Py_Dealloc in object.c.
     */
    Py_ssize_t refcnt = Py_REFCNT(self);
    ASSERT(Py_REFCNT(self) != 0);
    _Py_NewReference(self);
    Py_REFCNT(self) = refcnt;
    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
     * we need to undo that. */
    _Py_DEC_REFTOTAL;
    /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
     * chain, so no more to do there.
     * If COUNT_ALLOCS, the original decref bumped tp_frees, and
     * _Py_NewReference bumped tp_allocs:  both of those need to be
     * undone.
     */
#ifdef COUNT_ALLOCS
    --Py_TYPE(self)->tp_frees;
    --Py_TYPE(self)->tp_allocs;
#endif

     /* When called from a heap type's dealloc (subtype_dealloc avove), the type will be
      * decref'ed on return.  This counteracts that.  There is no way to otherwise
      * let subtype_dealloc know that calling a parent class' tp_dealloc slot caused
      * the instance to be resurrected.
      */
    if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
        Py_INCREF(Py_TYPE(self));
    return;
}
Пример #5
0
Py_ssize_t
PyBuffer_GetMemory(PyObject* buffer, const char** pp)
{
    PyBufferProcs* procs = buffer->ob_type->tp_as_buffer;

    if (!procs || !PyType_HasFeature(buffer->ob_type, Py_TPFLAGS_HAVE_GETCHARBUFFER))
    {
        // Can't access the memory directly because the buffer object doesn't support it.
        return -1;
    }

    if (procs->bf_getsegcount(buffer, 0) != 1)
    {
        // Can't access the memory directly because there is more than one segment.
        return -1;
    }

#if PY_VERSION_HEX >= 0x02050000
    char* pT = 0;
#else
    const char* pT = 0;
#endif
    Py_ssize_t cb = procs->bf_getcharbuffer(buffer, 0, &pT);

    if (pp)
        *pp = pT;

    return cb;
}
Пример #6
0
/*
  This function should be as fast as possible, so we don't call PyType_stgdict
  above but inline the code, and avoid the PyType_Check().
*/
StgDictObject *
PyObject_stgdict(PyObject *self)
{
	PyTypeObject *type = self->ob_type;
	if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
		return NULL;
	if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
		return NULL;
	return (StgDictObject *)type->tp_dict;
}
Пример #7
0
static int
wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
{
    PyObject *wrapped;
    PyObject *descriptor;
    const char *name_as_string;
    int res = -1;

#if PY_MAJOR_VERSION < 3 && defined(Py_USING_UNICODE)
    /* The Unicode to string conversion is done here because the
       existing tp_setattro slots expect a string object as name
       (except under Python 3) and we wouldn't want to break those. */

    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return -1;
    }
    else
#endif

    if (!IS_STRING(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return -1;
    }
    else
        Py_INCREF(name);

    descriptor = WrapperType_Lookup(self->ob_type, name);

    if (descriptor != NULL
#if PY_MAJOR_VERSION < 3 // This is always true in Python 3 (I think)
        && PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
#endif
        && descriptor->ob_type->tp_descr_set != NULL)
      {
        res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
        goto finally;
      }

    name_as_string = MAKE_STRING(name);

    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to set attribute '%s'",
            name_as_string);
        goto finally;
    }
    res = PyObject_SetAttr(wrapped, name, value);

finally:
    Py_DECREF(name);
    return res;
}
Пример #8
0
static PyObject *entity_setstate(PyObject *self, PyObject *state)
{
  PyObject *dict, *public_id, *system_id, *unparsed_entities, *children, *temp;
  Py_ssize_t i, n;

  if (!PyArg_UnpackTuple(state, NULL, 5, 5,
                         &dict, &public_id, &system_id, &unparsed_entities,
                         &children))
    return NULL;

  if (!convert_arg(0, &PyDict_Type, &dict))
    return NULL;
  if (!convert_arg(3, &PyDict_Type, &unparsed_entities))
    return NULL;
  if (!convert_arg(4, &PyTuple_Type, &children))
    return NULL;

  if (dict) {
    if (PyType_HasFeature(self->ob_type, Py_TPFLAGS_HEAPTYPE)) {
      temp = PyObject_GetAttrString(self, "__dict__");
      if (temp == NULL)
        return NULL;
      if (PyDict_Update(temp, dict) < 0) {
        Py_DECREF(temp);
        return NULL;
      }
      Py_DECREF(temp);
    }
  }
  temp = Entity_GET_PUBLIC_ID(self);
  Entity_SET_PUBLIC_ID(self, public_id);
  Py_INCREF(public_id);
  Py_DECREF(temp);

  temp = Entity_GET_SYSTEM_ID(self);
  Entity_SET_SYSTEM_ID(self, system_id);
  Py_INCREF(system_id);
  Py_DECREF(temp);

  if (unparsed_entities) {
    temp = Entity_GET_UNPARSED_ENTITIES(self);
    PyDict_Clear(temp);
    if (PyDict_Update(temp, unparsed_entities) < 0)
      return NULL;
  }
  if (children) {
    for (i = 0, n = PyTuple_GET_SIZE(children); i < n; i++) {
      NodeObject *node = (NodeObject *)PyTuple_GET_ITEM(children, i);
      if (Container_Append((NodeObject *)self, node) < 0)
        return NULL;
    }
  }
  Py_RETURN_NONE;
}
Пример #9
0
/* Return true if object has a finalization method.
 * CAUTION:  An instance of an old-style class has to be checked for a
 *__del__ method, and earlier versions of this used to call PyObject_HasAttr,
 * which in turn could call the class's __getattr__ hook (if any).  That
 * could invoke arbitrary Python code, mutating the object graph in arbitrary
 * ways, and that was the source of some excruciatingly subtle bugs.
 */
static int
has_finalizer(PyObject *op)
{
	if (PyInstance_Check(op)) {
		assert(delstr != NULL);
		return _PyInstance_Lookup(op, delstr) != NULL;
	}
	else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
		return op->ob_type->tp_del != NULL;
	else
		return 0;
}
Пример #10
0
static PyObject *node_getstate(PyObject *self, PyObject *args)
{
  PyObject *deep=Py_True;

  if (!PyArg_ParseTuple(args, "|O:__getstate__", &deep))
    return NULL;

  if (PyType_HasFeature(self->ob_type, Py_TPFLAGS_HEAPTYPE))
    return PyObject_GetAttrString(self, "__dict__");

  Py_RETURN_NONE;
}
static int
wrap_setattro(PyObject *self, PyObject *name, PyObject *value)
{
    PyObject *wrapped;
    PyObject *descriptor;
    int res = -1;

#ifdef Py_USING_UNICODE
    /* The Unicode to string conversion is done here because the
       existing tp_setattro slots expect a string object as name
       and we wouldn't want to break those. */
    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return -1;
    }
    else
#endif
    if (!PyString_Check(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return -1;
    }
    else
        Py_INCREF(name);

    descriptor = WrapperType_Lookup(self->ob_type, name);
    if (descriptor != NULL) {
        if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS) &&
            descriptor->ob_type->tp_descr_set != NULL) {
            res = descriptor->ob_type->tp_descr_set(descriptor, self, value);
        } else {
            PyErr_Format(PyExc_TypeError,
                "Tried to set attribute '%s' on wrapper, but it is not"
                " a data descriptor", PyString_AS_STRING(name));
        }
        goto finally;
    }

    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to set attribute '%s'",
            PyString_AS_STRING(name));
        goto finally;
    }
    res = PyObject_SetAttr(wrapped, name, value);

finally:
    Py_DECREF(name);
    return res;
}
Пример #12
0
/* May return NULL, but does not set an exception! */
StgDictObject *
PyType_stgdict(PyObject *obj)
{
	PyTypeObject *type;

	if (!PyType_Check(obj))
		return NULL;
	type = (PyTypeObject *)obj;
	if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
		return NULL;
	if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict))
		return NULL;
	return (StgDictObject *)type->tp_dict;
}
Пример #13
0
static PyObject *node_setstate(PyObject *self, PyObject *state)
{
  PyObject *dict;

  if (PyType_HasFeature(self->ob_type, Py_TPFLAGS_HEAPTYPE)) {
    dict = PyObject_GetAttrString(self, "__dict__");
    if (dict == NULL)
      return NULL;
    if (PyDict_Update(dict, state) < 0) {
      Py_DECREF(dict);
      return NULL;
    }
    Py_DECREF(dict);
  } else if (state != Py_None)
    return PyErr_Format(PyExc_NotImplementedError,
                        "subclass '%s' must override __setstate__()",
                        self->ob_type->tp_name);
  Py_RETURN_NONE;
}
Пример #14
0
static PyObject *entity_getstate(PyObject *self, PyObject *args)
{
  PyObject *deep=Py_True, *dict, *unparsed_entities, *children;
  Py_ssize_t i;

  if (!PyArg_ParseTuple(args, "|O:__getstate__", &deep))
    return NULL;

  if (PyType_HasFeature(self->ob_type, Py_TPFLAGS_HEAPTYPE)) {
    dict = PyObject_GetAttrString(self, "__dict__");
    if (dict == NULL)
      return NULL;
  } else {
    dict = Py_None;
    Py_INCREF(Py_None);
  }
  /* save the child nodes in a tuple */
  switch (PyObject_IsTrue(deep)) {
    case 0:
      unparsed_entities = Py_None;
      children = Py_None;
      Py_INCREF(children);
      break;
    case 1:
      unparsed_entities = Entity_GET_UNPARSED_ENTITIES(self);
      children = PyTuple_New(Container_GET_COUNT(self));
      if (children != NULL) {
        for (i = 0; i < Container_GET_COUNT(self); i++) {
          PyObject *item = (PyObject *)Container_GET_CHILD(self, i);
          PyTuple_SET_ITEM(children, i, item);
          Py_INCREF(item);
        }
        break;
      }
      /* error; fall through */
    default:
      Py_DECREF(dict);
      return NULL;
  }
  return Py_BuildValue("NOOON", dict, Entity_GET_PUBLIC_ID(self),
                       Entity_GET_SYSTEM_ID(self), unparsed_entities,
                       children);
}
Пример #15
0
DEFINEFN
vinfo_t* PsycoSequence_Contains(PsycoObject* po, vinfo_t* seq, vinfo_t* ob)
{
	PyTypeObject* tp = Psyco_NeedType(po, seq);
	if (tp == NULL)
		return false;

	if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
		PySequenceMethods *sqm = tp->tp_as_sequence;
	        if (sqm != NULL && sqm->sq_contains != NULL)
			return Psyco_META2(po, sqm->sq_contains,
					   CfReturnNormal|CfPyErrIfNeg,
					   "vv", seq, ob);
	}

	/* XXX implement me */
	return psyco_generic_call(po, _PySequence_IterSearch,
				  CfReturnNormal|CfPyErrIfNeg,
				  "vvl", seq, ob, PY_ITERSEARCH_CONTAINS);
}
Пример #16
0
int
PySequence_Contains(PyObject *w, PyObject *v) /* v in w */
{
	int i, cmp;
	PyObject *x;
	PySequenceMethods *sq;

	if(PyType_HasFeature(w->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
		sq = w->ob_type->tp_as_sequence;
	        if(sq != NULL && sq->sq_contains != NULL)
			return (*sq->sq_contains)(w, v);
	}
	
	/* If there is no better way to check whether an item is is contained,
	   do it the hard way */
	sq = w->ob_type->tp_as_sequence;
	if (sq == NULL || sq->sq_item == NULL) {
		PyErr_SetString(PyExc_TypeError,
			"'in' or 'not in' needs sequence right argument");
		return -1;
	}

	for (i = 0; ; i++) {
		x = (*sq->sq_item)(w, i);
		if (x == NULL) {
			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
				PyErr_Clear();
				break;
			}
			return -1;
		}
		cmp = PyObject_Compare(v, x);
		Py_XDECREF(x);
		if (cmp == 0)
			return 1;
		if (PyErr_Occurred())
			return -1;
	}

	return 0;
}
Пример #17
0
static void
iobase_dealloc(iobase *self)
{
    /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
       are still available here for close() to use.
       However, if the derived class declares a __slots__, those slots are
       already gone.
    */
    if (_PyIOBase_finalize((PyObject *) self) < 0) {
        /* When called from a heap type's dealloc, the type will be
           decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
        if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
            Py_INCREF(Py_TYPE(self));
        return;
    }
    _PyObject_GC_UNTRACK(self);
    if (self->weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    Py_CLEAR(self->dict);
    Py_TYPE(self)->tp_free((PyObject *) self);
}
Пример #18
0
DEFINEFN
vinfo_t* PsycoObject_GetIter(PsycoObject* po, vinfo_t* vi)
{
	getiterfunc f;
	PyTypeObject* t = Psyco_NeedType(po, vi);
	if (t == NULL)
		return NULL;
	if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
		f = t->tp_iter;
	else
		f = NULL;
	if (f == NULL) {
		if (PsycoSequence_Check(t))
			return PsycoSeqIter_New(po, vi);
		PycException_SetString(po, PyExc_TypeError,
				       "iteration over non-sequence");
		return NULL;
	}
	else {
		return Psyco_META1(po, f, CfReturnRef|CfPyErrIfNull,
                                   "v", vi);
	}
}
static PyObject *
wrap_getattro(PyObject *self, PyObject *name)
{
    PyObject *wrapped;
    PyObject *descriptor;
    PyObject *res = NULL;
    char *name_as_string;
    int maybe_special_name;

#ifdef Py_USING_UNICODE
    /* The Unicode to string conversion is done here because the
       existing tp_getattro slots expect a string object as name
       and we wouldn't want to break those. */
    if (PyUnicode_Check(name)) {
        name = PyUnicode_AsEncodedString(name, NULL, NULL);
        if (name == NULL)
            return NULL;
    }
    else
#endif
    if (!PyString_Check(name)){
        PyErr_SetString(PyExc_TypeError, "attribute name must be string");
        return NULL;
    }
    else
        Py_INCREF(name);

    name_as_string = PyString_AS_STRING(name);
    wrapped = Proxy_GET_OBJECT(self);
    if (wrapped == NULL) {
        PyErr_Format(PyExc_RuntimeError,
            "object is NULL; requested to get attribute '%s'",
            name_as_string);
        goto finally;
    }

    maybe_special_name = name_as_string[0] == '_' && name_as_string[1] == '_';

    if (!(maybe_special_name && strcmp(name_as_string, "__class__") == 0)) {

        descriptor = WrapperType_Lookup(self->ob_type, name);

        if (descriptor != NULL) {
            if (PyType_HasFeature(descriptor->ob_type, Py_TPFLAGS_HAVE_CLASS)
                && descriptor->ob_type->tp_descr_get != NULL) {
                res = descriptor->ob_type->tp_descr_get(
                        descriptor,
                        self,
                        (PyObject *)self->ob_type);
            } else {
                Py_INCREF(descriptor);
                res = descriptor;
            }
            goto finally;
        }
    }
    res = PyObject_GetAttr(wrapped, name);

finally:
    Py_DECREF(name);
    return res;
}
Пример #20
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;
    }
}
Пример #21
0
PyObject *LOOKUP_ATTRIBUTE_CLASS_SLOT(PyObject *source) {
    CHECK_OBJECT(source);

    PyTypeObject *type = Py_TYPE(source);

    if (type->tp_getattro == PyObject_GenericGetAttr) {
        if (unlikely(type->tp_dict == NULL)) {
            if (unlikely(PyType_Ready(type) < 0)) {
                return NULL;
            }
        }

        PyObject *descr = _PyType_Lookup(type, const_str_plain___class__);
        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, const_str_plain___class__);

            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;
        }

        PyErr_Format(PyExc_AttributeError, "'%s' object has no attribute '__class__'", type->tp_name);
        return NULL;
    }
#if PYTHON_VERSION < 300
    else if (type->tp_getattro == PyInstance_Type.tp_getattro) {
        PyInstanceObject *source_instance = (PyInstanceObject *)source;
        PyObject *result = (PyObject *)source_instance->in_class;

        Py_INCREF(result);
        return result;
    }
#endif
    else if (type->tp_getattro != NULL) {
        PyObject *result = (*type->tp_getattro)(source, const_str_plain___class__);

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

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

        return NULL;
    }
}
Пример #22
0
PyObject *
Base_getattro(PyObject *obj, PyObject *name)
{
  /* This is a modified copy of PyObject_GenericGetAttr.
     See the change note below. */

	PyTypeObject *tp = obj->ob_type;
	PyObject *descr = NULL;
	PyObject *res = NULL;
	descrgetfunc f;
	long dictoffset;
	PyObject **dictptr;

	if (!PyString_Check(name)){
#ifdef Py_USING_UNICODE
		/* The Unicode to string conversion is done here because the
		   existing tp_setattro slots expect a string object as name
		   and we wouldn't want to break those. */
		if (PyUnicode_Check(name)) {
			name = PyUnicode_AsEncodedString(name, NULL, NULL);
			if (name == NULL)
				return NULL;
		}
		else
#endif
		{
			PyErr_SetString(PyExc_TypeError,
					"attribute name must be string");
			return NULL;
		}
	}
	else
		Py_INCREF(name);

	if (tp->tp_dict == NULL) {
		if (PyType_Ready(tp) < 0)
			goto done;
	}

#if !defined(Py_TPFLAGS_HAVE_VERSION_TAG)
	/* Inline _PyType_Lookup */
	/* this is not quite _PyType_Lookup anymore */
	{
		int i, n;
		PyObject *mro, *base, *dict;

		/* Look in tp_dict of types in MRO */
		mro = tp->tp_mro;
		assert(mro != NULL);
		assert(PyTuple_Check(mro));
		n = PyTuple_GET_SIZE(mro);
		for (i = 0; i < n; i++) {
			base = PyTuple_GET_ITEM(mro, i);
			if (PyClass_Check(base))
				dict = ((PyClassObject *)base)->cl_dict;
			else {
				assert(PyType_Check(base));
				dict = ((PyTypeObject *)base)->tp_dict;
			}
			assert(dict && PyDict_Check(dict));
			descr = PyDict_GetItem(dict, name);
			if (descr != NULL)
				break;
		}
	}
#else
    descr = _PyType_Lookup(tp, name);
#endif

    Py_XINCREF(descr);

	f = NULL;
	if (descr != NULL &&
	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
		f = descr->ob_type->tp_descr_get;
		if (f != NULL && PyDescr_IsData(descr)) {
			res = f(descr, obj, (PyObject *)obj->ob_type);
            Py_DECREF(descr);
			goto done;
		}
	}

	/* Inline _PyObject_GetDictPtr */
	dictoffset = tp->tp_dictoffset;
	if (dictoffset != 0) {
		PyObject *dict;
		if (dictoffset < 0) {
			int tsize;
			size_t size;

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

			dictoffset += (long)size;
			assert(dictoffset > 0);
			assert(dictoffset % SIZEOF_VOID_P == 0);
		}
		dictptr = (PyObject **) ((char *)obj + dictoffset);
		dict = *dictptr;
		if (dict != NULL) {
			Py_INCREF(dict);
			res = PyDict_GetItem(dict, name);
			if (res != NULL) {
				Py_INCREF(res);
				Py_XDECREF(descr);
				Py_DECREF(dict);

                          /* CHANGED!
                             If the tp_descr_get of res is of_get, 
                             then call it. */
                          if ((strcmp(PyString_AsString(name), "__parent__") != 0) &&
                              PyObject_TypeCheck(res->ob_type,
                                                 &ExtensionClassType)
                              && res->ob_type->tp_descr_get != NULL) {
                            PyObject *tres;
                            tres = res->ob_type->tp_descr_get(
                                                 res, obj, 
                                                 OBJECT(obj->ob_type));
                            Py_DECREF(res);
                            res = tres;
                          }
                          goto done;
			}
			Py_DECREF(dict);
		}
	}

	if (f != NULL) {
		res = f(descr, obj, (PyObject *)obj->ob_type);
		Py_DECREF(descr);
		goto done;
	}

	if (descr != NULL) {
		res = descr;
        /* descr was already increfed above */
		goto done;
	}

        /* CHANGED: Just use the name. Don't format. */
        PyErr_SetObject(PyExc_AttributeError, name);
  done:
	Py_DECREF(name);
	return res;
}
Пример #23
0
static int
get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
    enum buffer_t buffer_type)
{
    if (self->b_base == NULL) {
        assert (ptr != NULL);
        *ptr = self->b_ptr;
        *size = self->b_size;
    }
    else {
        Py_ssize_t count, offset;
        readbufferproc proc = 0;
        PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
        if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
            PyErr_SetString(PyExc_TypeError,
                "single-segment buffer object expected");
            return 0;
        }
        if ((buffer_type == READ_BUFFER) ||
            ((buffer_type == ANY_BUFFER) && self->b_readonly))
            proc = bp->bf_getreadbuffer;
        else if ((buffer_type == WRITE_BUFFER) ||
            (buffer_type == ANY_BUFFER))
            proc = (readbufferproc)bp->bf_getwritebuffer;
        else if (buffer_type == CHAR_BUFFER) {
            if (!PyType_HasFeature(self->ob_type,
                        Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
            PyErr_SetString(PyExc_TypeError,
                "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
            return 0;
            }
            proc = (readbufferproc)bp->bf_getcharbuffer;
        }
        if (!proc) {
            char *buffer_type_name;
            switch (buffer_type) {
            case READ_BUFFER:
                buffer_type_name = "read";
                break;
            case WRITE_BUFFER:
                buffer_type_name = "write";
                break;
            case CHAR_BUFFER:
                buffer_type_name = "char";
                break;
            default:
                buffer_type_name = "no";
                break;
            }
            PyErr_Format(PyExc_TypeError,
                "%s buffer type not available",
                buffer_type_name);
            return 0;
        }
        if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
            return 0;
        /* apply constraints to the start/end */
        if (self->b_offset > count)
            offset = count;
        else
            offset = self->b_offset;
        *(char **)ptr = *(char **)ptr + offset;
        if (self->b_size == Py_END_OF_BUFFER)
            *size = count;
        else
            *size = self->b_size;
        if (offset + *size > count)
            *size = count - offset;
    }
    return 1;
}
Пример #24
0
PyObject *
PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
{
	PyTypeObject *tp = obj->ob_type;
	PyObject *descr = NULL;
	PyObject *res = NULL;
	descrgetfunc f;
	Py_ssize_t dictoffset;
	PyObject **dictptr;

	if (!PyString_Check(name)){
#ifdef Py_USING_UNICODE
		/* The Unicode to string conversion is done here because the
		   existing tp_setattro slots expect a string object as name
		   and we wouldn't want to break those. */
		if (PyUnicode_Check(name)) {
			name = PyUnicode_AsEncodedString(name, NULL, NULL);
			if (name == NULL)
				return NULL;
		}
		else
#endif
		{
			PyErr_Format(PyExc_TypeError,
				     "attribute name must be string, not '%.200s'",
				     name->ob_type->tp_name);
			return NULL;
		}
	}
	else
		Py_INCREF(name);

	if (tp->tp_dict == NULL) {
		if (PyType_Ready(tp) < 0)
			goto done;
	}

	/* Inline _PyType_Lookup */
	{
		Py_ssize_t i, n;
		PyObject *mro, *base, *dict;

		/* Look in tp_dict of types in MRO */
		mro = tp->tp_mro;
		assert(mro != NULL);
		assert(PyTuple_Check(mro));
		n = PyTuple_GET_SIZE(mro);
		for (i = 0; i < n; i++) {
			base = PyTuple_GET_ITEM(mro, i);
			if (PyClass_Check(base))
				dict = ((PyClassObject *)base)->cl_dict;
			else {
				assert(PyType_Check(base));
				dict = ((PyTypeObject *)base)->tp_dict;
			}
			assert(dict && PyDict_Check(dict));
			descr = PyDict_GetItem(dict, name);
			if (descr != NULL)
				break;
		}
	}

	Py_XINCREF(descr);

	f = NULL;
	if (descr != NULL &&
	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
		f = descr->ob_type->tp_descr_get;
		if (f != NULL && PyDescr_IsData(descr)) {
			res = f(descr, obj, (PyObject *)obj->ob_type);
			Py_DECREF(descr);
			goto done;
		}
	}

	/* Inline _PyObject_GetDictPtr */
	dictoffset = tp->tp_dictoffset;
	if (dictoffset != 0) {
		PyObject *dict;
		if (dictoffset < 0) {
			Py_ssize_t tsize;
			size_t size;

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

			dictoffset += (long)size;
			assert(dictoffset > 0);
			assert(dictoffset % SIZEOF_VOID_P == 0);
		}
		dictptr = (PyObject **) ((char *)obj + dictoffset);
		dict = *dictptr;
		if (dict != NULL) {
			res = PyDict_GetItem(dict, name);
			if (res != NULL) {
				Py_INCREF(res);
				Py_XDECREF(descr);
				goto done;
			}
		}
	}

	if (f != NULL) {
		res = f(descr, obj, (PyObject *)obj->ob_type);
		Py_DECREF(descr);
		goto done;
	}

	if (descr != NULL) {
		res = descr;
		/* descr was already increfed above */
		goto done;
	}

	PyErr_Format(PyExc_AttributeError,
		     "'%.50s' object has no attribute '%.400s'",
		     tp->tp_name, PyString_AS_STRING(name));
  done:
	Py_DECREF(name);
	return res;
}
Пример #25
0
int
PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
{
	PyTypeObject *tp = obj->ob_type;
	PyObject *descr;
	descrsetfunc f;
	PyObject **dictptr;
	int res = -1;

	if (!PyString_Check(name)){
#ifdef Py_USING_UNICODE
		/* The Unicode to string conversion is done here because the
		   existing tp_setattro slots expect a string object as name
		   and we wouldn't want to break those. */
		if (PyUnicode_Check(name)) {
			name = PyUnicode_AsEncodedString(name, NULL, NULL);
			if (name == NULL)
				return -1;
		}
		else
#endif
		{
			PyErr_Format(PyExc_TypeError,
				     "attribute name must be string, not '%.200s'",
				     name->ob_type->tp_name);
			return -1;
		}
	}
	else
		Py_INCREF(name);

	if (tp->tp_dict == NULL) {
		if (PyType_Ready(tp) < 0)
			goto done;
	}

	descr = _PyType_Lookup(tp, name);
	f = NULL;
	if (descr != NULL &&
	    PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
		f = descr->ob_type->tp_descr_set;
		if (f != NULL && PyDescr_IsData(descr)) {
			res = f(descr, obj, value);
			goto done;
		}
	}

	dictptr = _PyObject_GetDictPtr(obj);
	if (dictptr != NULL) {
		PyObject *dict = *dictptr;
		if (dict == NULL && value != NULL) {
			dict = PyDict_New();
			if (dict == NULL)
				goto done;
			*dictptr = dict;
		}
		if (dict != NULL) {
			if (value == NULL)
				res = PyDict_DelItem(dict, name);
			else
				res = PyDict_SetItem(dict, name, value);
			if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
				PyErr_SetObject(PyExc_AttributeError, name);
			goto done;
		}
	}

	if (f != NULL) {
		res = f(descr, obj, value);
		goto done;
	}

	if (descr == NULL) {
		PyErr_Format(PyExc_AttributeError,
			     "'%.100s' object has no attribute '%.200s'",
			     tp->tp_name, PyString_AS_STRING(name));
		goto done;
	}

	PyErr_Format(PyExc_AttributeError,
		     "'%.50s' object attribute '%.400s' is read-only",
		     tp->tp_name, PyString_AS_STRING(name));
  done:
	Py_DECREF(name);
	return res;
}