diff options
Diffstat (limited to 'Objects/abstract.c')
| -rw-r--r-- | Objects/abstract.c | 335 | 
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;  | 
