summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c335
1 files changed, 158 insertions, 177 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 7705d05..a2737dd 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -74,7 +74,7 @@ PyObject_Length(PyObject *o)
Py_ssize_t
_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
{
- static PyObject *hintstrobj = NULL;
+ _Py_IDENTIFIER(__length_hint__);
PyObject *ro, *hintmeth;
Py_ssize_t rv;
@@ -89,7 +89,7 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
}
/* try o.__length_hint__() */
- hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
+ hintmeth = _PyObject_LookupSpecial(o, &PyId___length_hint__);
if (hintmeth == NULL) {
if (PyErr_Occurred())
return -1;
@@ -237,7 +237,8 @@ PyObject_AsCharBuffer(PyObject *obj,
pb = obj->ob_type->tp_as_buffer;
if (pb == NULL || pb->bf_getbuffer == NULL) {
PyErr_SetString(PyExc_TypeError,
- "expected an object with the buffer interface");
+ "expected bytes, bytearray "
+ "or buffer compatible object");
return -1;
}
if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1;
@@ -331,7 +332,7 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
{
if (!PyObject_CheckBuffer(obj)) {
PyErr_Format(PyExc_TypeError,
- "'%100s' does not support the buffer interface",
+ "'%.100s' does not support the buffer interface",
Py_TYPE(obj)->tp_name);
return -1;
}
@@ -339,7 +340,7 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
}
static int
-_IsFortranContiguous(Py_buffer *view)
+_IsFortranContiguous(const Py_buffer *view)
{
Py_ssize_t sd, dim;
int i;
@@ -360,7 +361,7 @@ _IsFortranContiguous(Py_buffer *view)
}
static int
-_IsCContiguous(Py_buffer *view)
+_IsCContiguous(const Py_buffer *view)
{
Py_ssize_t sd, dim;
int i;
@@ -381,16 +382,16 @@ _IsCContiguous(Py_buffer *view)
}
int
-PyBuffer_IsContiguous(Py_buffer *view, char fort)
+PyBuffer_IsContiguous(const Py_buffer *view, char order)
{
if (view->suboffsets != NULL) return 0;
- if (fort == 'C')
+ if (order == 'C')
return _IsCContiguous(view);
- else if (fort == 'F')
+ else if (order == 'F')
return _IsFortranContiguous(view);
- else if (fort == 'A')
+ else if (order == 'A')
return (_IsCContiguous(view) || _IsFortranContiguous(view));
return 0;
}
@@ -444,62 +445,6 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
}
}
- /* view is not checked for consistency in either of these. It is
- assumed that the size of the buffer is view->len in
- view->len / view->itemsize elements.
- */
-
-int
-PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
-{
- int k;
- void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
- Py_ssize_t *indices, elements;
- char *dest, *ptr;
-
- if (len > view->len) {
- len = view->len;
- }
-
- if (PyBuffer_IsContiguous(view, fort)) {
- /* simplest copy is all that is needed */
- memcpy(buf, view->buf, len);
- return 0;
- }
-
- /* Otherwise a more elaborate scheme is needed */
-
- /* XXX(nnorwitz): need to check for overflow! */
- indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim));
- if (indices == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- for (k=0; k<view->ndim;k++) {
- indices[k] = 0;
- }
-
- if (fort == 'F') {
- addone = _Py_add_one_to_index_F;
- }
- else {
- addone = _Py_add_one_to_index_C;
- }
- dest = buf;
- /* XXX : This is not going to be the fastest code in the world
- several optimizations are possible.
- */
- elements = len / view->itemsize;
- while (elements--) {
- addone(view->ndim, indices, view->shape);
- ptr = PyBuffer_GetPointer(view, indices);
- memcpy(dest, ptr, view->itemsize);
- dest += view->itemsize;
- }
- PyMem_Free(indices);
- return 0;
-}
-
int
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
{
@@ -648,9 +593,9 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
int
PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
- int readonly, int flags)
+ int readonly, int flags)
{
- if (view == NULL) return 0;
+ if (view == NULL) return 0; /* XXX why not -1? */
if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
(readonly == 1)) {
PyErr_SetString(PyExc_BufferError,
@@ -696,16 +641,16 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
PyObject *meth;
PyObject *empty = NULL;
PyObject *result = NULL;
- static PyObject *format_cache = NULL;
+ _Py_IDENTIFIER(__format__);
/* If no format_spec is provided, use an empty string */
if (format_spec == NULL) {
- empty = PyUnicode_FromUnicode(NULL, 0);
+ empty = PyUnicode_New(0, 0);
format_spec = empty;
}
/* Find the (unbound!) __format__ method (a borrowed reference) */
- meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache);
+ meth = _PyObject_LookupSpecial(obj, &PyId___format__);
if (meth == NULL) {
if (!PyErr_Occurred())
PyErr_Format(PyExc_TypeError,
@@ -792,8 +737,7 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
return x;
Py_DECREF(x); /* can't do it */
}
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ Py_RETURN_NOTIMPLEMENTED;
}
static PyObject *
@@ -1268,37 +1212,31 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err)
}
-PyObject *
-_PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format)
-{
- static PyObject *int_name = NULL;
- if (int_name == NULL) {
- int_name = PyUnicode_InternFromString("__int__");
- if (int_name == NULL)
- return NULL;
- }
-
- if (integral && !PyLong_Check(integral)) {
- /* Don't go through tp_as_number->nb_int to avoid
- hitting the classic class fallback to __trunc__. */
- PyObject *int_func = PyObject_GetAttr(integral, int_name);
- if (int_func == NULL) {
- PyErr_Clear(); /* Raise a different error. */
- goto non_integral_error;
- }
- Py_DECREF(integral);
- integral = PyEval_CallObject(int_func, NULL);
- Py_DECREF(int_func);
- if (integral && !PyLong_Check(integral)) {
- goto non_integral_error;
+/*
+ Returns the Integral instance converted to an int. The instance is expected
+ to be an int or have an __int__ method. Steals integral's
+ reference. error_format will be used to create the TypeError if integral
+ isn't actually an Integral instance. error_format should be a format string
+ that can accept a char* naming integral's type.
+*/
+static PyObject *
+convert_integral_to_int(PyObject *integral, const char *error_format)
+{
+ PyNumberMethods *nb;
+ if (PyLong_Check(integral))
+ return integral;
+ nb = Py_TYPE(integral)->tp_as_number;
+ if (nb->nb_int) {
+ PyObject *as_int = nb->nb_int(integral);
+ if (!as_int || PyLong_Check(as_int)) {
+ Py_DECREF(integral);
+ return as_int;
}
+ Py_DECREF(as_int);
}
- return integral;
-
-non_integral_error:
PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name);
Py_DECREF(integral);
- return NULL;
+ return NULL;
}
@@ -1325,16 +1263,10 @@ PyObject *
PyNumber_Long(PyObject *o)
{
PyNumberMethods *m;
- static PyObject *trunc_name = NULL;
PyObject *trunc_func;
const char *buffer;
Py_ssize_t buffer_len;
-
- if (trunc_name == NULL) {
- trunc_name = PyUnicode_InternFromString("__trunc__");
- if (trunc_name == NULL)
- return NULL;
- }
+ _Py_IDENTIFIER(__trunc__);
if (o == NULL)
return null_error();
@@ -1356,32 +1288,30 @@ PyNumber_Long(PyObject *o)
}
if (PyLong_Check(o)) /* An int subclass without nb_int */
return _PyLong_Copy((PyLongObject *)o);
- trunc_func = PyObject_GetAttr(o, trunc_name);
+ trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__);
if (trunc_func) {
PyObject *truncated = PyEval_CallObject(trunc_func, NULL);
PyObject *int_instance;
Py_DECREF(trunc_func);
/* __trunc__ is specified to return an Integral type,
- but long() needs to return a long. */
- int_instance = _PyNumber_ConvertIntegralToInt(
- truncated,
+ but int() needs to return a int. */
+ int_instance = convert_integral_to_int(truncated,
"__trunc__ returned non-Integral (type %.200s)");
return int_instance;
}
- PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */
+ if (PyErr_Occurred())
+ return NULL;
if (PyBytes_Check(o))
/* need to do extra error checking that PyLong_FromString()
- * doesn't do. In particular long('9.5') must raise an
+ * doesn't do. In particular int('9.5') must raise an
* exception, not truncate the float.
*/
return long_from_string(PyBytes_AS_STRING(o),
PyBytes_GET_SIZE(o));
if (PyUnicode_Check(o))
/* The above check is done in PyLong_FromUnicode(). */
- return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
- PyUnicode_GET_SIZE(o),
- 10);
+ return PyLong_FromUnicodeObject(o, 10);
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return long_from_string(buffer, buffer_len);
@@ -1986,7 +1916,7 @@ PySequence_Index(PyObject *s, PyObject *o)
int
PyMapping_Check(PyObject *o)
{
- return o && o->ob_type->tp_as_mapping &&
+ return o && o->ob_type->tp_as_mapping &&
o->ob_type->tp_as_mapping->mp_subscript;
}
@@ -2084,10 +2014,11 @@ PyMapping_Keys(PyObject *o)
{
PyObject *keys;
PyObject *fast;
+ _Py_IDENTIFIER(keys);
if (PyDict_CheckExact(o))
return PyDict_Keys(o);
- keys = PyObject_CallMethod(o, "keys", NULL);
+ keys = _PyObject_CallMethodId(o, &PyId_keys, NULL);
if (keys == NULL)
return NULL;
fast = PySequence_Fast(keys, "o.keys() are not iterable");
@@ -2100,10 +2031,11 @@ PyMapping_Items(PyObject *o)
{
PyObject *items;
PyObject *fast;
+ _Py_IDENTIFIER(items);
if (PyDict_CheckExact(o))
return PyDict_Items(o);
- items = PyObject_CallMethod(o, "items", NULL);
+ items = _PyObject_CallMethodId(o, &PyId_items, NULL);
if (items == NULL)
return NULL;
fast = PySequence_Fast(items, "o.items() are not iterable");
@@ -2116,10 +2048,11 @@ PyMapping_Values(PyObject *o)
{
PyObject *values;
PyObject *fast;
+ _Py_IDENTIFIER(values);
if (PyDict_CheckExact(o))
return PyDict_Values(o);
- values = PyObject_CallMethod(o, "values", NULL);
+ values = _PyObject_CallMethodId(o, &PyId_values, NULL);
if (values == NULL)
return NULL;
fast = PySequence_Fast(values, "o.values() are not iterable");
@@ -2225,22 +2158,11 @@ _PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
return call_function_tail(callable, args);
}
-PyObject *
-PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+static PyObject*
+callmethod(PyObject* func, char *format, va_list va, int is_size_t)
{
- va_list va;
- PyObject *args;
- PyObject *func = NULL;
PyObject *retval = NULL;
-
- if (o == NULL || name == NULL)
- return null_error();
-
- func = PyObject_GetAttrString(o, name);
- if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
- return 0;
- }
+ PyObject *args;
if (!PyCallable_Check(func)) {
type_error("attribute of type '%.200s' is not callable", func);
@@ -2248,9 +2170,10 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
}
if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
+ if (is_size_t)
+ args = _Py_VaBuildValue_SizeT(format, va);
+ else
+ args = Py_VaBuildValue(format, va);
}
else
args = PyTuple_New(0);
@@ -2265,10 +2188,9 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
}
PyObject *
-_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
{
va_list va;
- PyObject *args;
PyObject *func = NULL;
PyObject *retval = NULL;
@@ -2277,32 +2199,75 @@ _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
func = PyObject_GetAttrString(o, name);
if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
- if (!PyCallable_Check(func)) {
- type_error("attribute of type '%.200s' is not callable", func);
- goto exit;
- }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 0);
+ va_end(va);
+ return retval;
+}
- if (format && *format) {
- va_start(va, format);
- args = _Py_VaBuildValue_SizeT(format, va);
- va_end(va);
+PyObject *
+_PyObject_CallMethodId(PyObject *o, _Py_Identifier *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = _PyObject_GetAttrId(o, name);
+ if (func == NULL) {
+ return 0;
}
- else
- args = PyTuple_New(0);
- retval = call_function_tail(func, args);
+ va_start(va, format);
+ retval = callmethod(func, format, va, 0);
+ va_end(va);
+ return retval;
+}
- exit:
- /* args gets consumed in call_function_tail */
- Py_XDECREF(func);
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval;
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ return 0;
+ }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 1);
+ va_end(va);
return retval;
}
+PyObject *
+_PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = _PyObject_GetAttrId(o, name);
+ if (func == NULL) {
+ return NULL;
+ }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 1);
+ va_end(va);
+ return retval;
+}
static PyObject *
objargs_mktuple(va_list va)
@@ -2355,6 +2320,35 @@ PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
}
PyObject *
+_PyObject_CallMethodObjIdArgs(PyObject *callable,
+ struct _Py_Identifier *name, ...)
+{
+ PyObject *args, *tmp;
+ va_list vargs;
+
+ if (callable == NULL || name == NULL)
+ return null_error();
+
+ callable = _PyObject_GetAttrId(callable, name);
+ if (callable == NULL)
+ return NULL;
+
+ /* count the args */
+ va_start(vargs, name);
+ args = objargs_mktuple(vargs);
+ va_end(vargs);
+ if (args == NULL) {
+ Py_DECREF(callable);
+ return NULL;
+ }
+ tmp = PyObject_Call(callable, args, NULL);
+ Py_DECREF(args);
+ Py_DECREF(callable);
+
+ return tmp;
+}
+
+PyObject *
PyObject_CallFunctionObjArgs(PyObject *callable, ...)
{
PyObject *args, *tmp;
@@ -2378,10 +2372,8 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...)
/* isinstance(), issubclass() */
-/* abstract_get_bases() has logically 4 return states, with a sort of 0th
- * state that will almost never happen.
+/* abstract_get_bases() has logically 4 return states:
*
- * 0. creating the __bases__ static string could get a MemoryError
* 1. getattr(cls, '__bases__') could raise an AttributeError
* 2. getattr(cls, '__bases__') could raise some other exception
* 3. getattr(cls, '__bases__') could return a tuple
@@ -2407,16 +2399,11 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...)
static PyObject *
abstract_get_bases(PyObject *cls)
{
- static PyObject *__bases__ = NULL;
+ _Py_IDENTIFIER(__bases__);
PyObject *bases;
- if (__bases__ == NULL) {
- __bases__ = PyUnicode_InternFromString("__bases__");
- if (__bases__ == NULL)
- return NULL;
- }
Py_ALLOW_RECURSION
- bases = PyObject_GetAttr(cls, __bases__);
+ bases = _PyObject_GetAttrId(cls, &PyId___bases__);
Py_END_ALLOW_RECURSION
if (bases == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError))
@@ -2486,19 +2473,13 @@ static int
recursive_isinstance(PyObject *inst, PyObject *cls)
{
PyObject *icls;
- static PyObject *__class__ = NULL;
int retval = 0;
-
- if (__class__ == NULL) {
- __class__ = PyUnicode_InternFromString("__class__");
- if (__class__ == NULL)
- return -1;
- }
+ _Py_IDENTIFIER(__class__);
if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
if (retval == 0) {
- PyObject *c = PyObject_GetAttr(inst, __class__);
+ PyObject *c = _PyObject_GetAttrId(inst, &PyId___class__);
if (c == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError))
PyErr_Clear();
@@ -2519,7 +2500,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
if (!check_class(cls,
"isinstance() arg 2 must be a type or tuple of types"))
return -1;
- icls = PyObject_GetAttr(inst, __class__);
+ icls = _PyObject_GetAttrId(inst, &PyId___class__);
if (icls == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError))
PyErr_Clear();
@@ -2538,7 +2519,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
- static PyObject *name = NULL;
+ _Py_IDENTIFIER(__instancecheck__);
PyObject *checker;
/* Quick test for an exact match */
@@ -2564,7 +2545,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
return r;
}
- checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
+ checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
if (checker != NULL) {
PyObject *res;
int ok = -1;
@@ -2607,7 +2588,7 @@ recursive_issubclass(PyObject *derived, PyObject *cls)
int
PyObject_IsSubclass(PyObject *derived, PyObject *cls)
{
- static PyObject *name = NULL;
+ _Py_IDENTIFIER(__subclasscheck__);
PyObject *checker;
if (PyTuple_Check(cls)) {
@@ -2629,7 +2610,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
return r;
}
- checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
+ checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__);
if (checker != NULL) {
PyObject *res;
int ok = -1;