diff options
Diffstat (limited to 'Objects/abstract.c')
| -rw-r--r-- | Objects/abstract.c | 33 | 
1 files changed, 19 insertions, 14 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 0d6aa4a..1ac4ac9 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -85,8 +85,8 @@ PyObject_Length(PyObject *o)  /* The length hint function returns a non-negative value from o.__len__()     or o.__length_hint__().  If those methods aren't found or return a negative -   value, then the defaultvalue is returned.  This function never fails.  -   Accordingly, it will mask exceptions raised in either method. +   value, then the defaultvalue is returned.  If one of the calls fails, +   this function returns -1.  */  Py_ssize_t @@ -100,29 +100,32 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)  	rv = PyObject_Size(o);  	if (rv >= 0)  		return rv; -	if (PyErr_Occurred()) +	if (PyErr_Occurred()) { +		if (!PyErr_ExceptionMatches(PyExc_TypeError) && +			!PyErr_ExceptionMatches(PyExc_AttributeError)) +				return -1;  		PyErr_Clear(); +	}  	/* cache a hashed version of the attribute string */  	if (hintstrobj == NULL) {  		hintstrobj = PyString_InternFromString("__length_hint__");  		if (hintstrobj == NULL) -			goto defaultcase; +			return -1;  	}  	/* try o.__length_hint__() */  	ro = PyObject_CallMethodObjArgs(o, hintstrobj, NULL); -	if (ro == NULL) -		goto defaultcase; +	if (ro == NULL) { +		if (!PyErr_ExceptionMatches(PyExc_TypeError) && +			!PyErr_ExceptionMatches(PyExc_AttributeError)) +				return -1; +		PyErr_Clear(); +		return defaultvalue; +	}  	rv = PyInt_AsLong(ro);  	Py_DECREF(ro); -	if (rv >= 0) -		return rv; - -defaultcase: -	if (PyErr_Occurred()) -		PyErr_Clear(); -	return defaultvalue; +	return rv;  }  PyObject * @@ -2128,7 +2131,7 @@ PySequence_Tuple(PyObject *v)  {  	PyObject *it;  /* iter(v) */  	Py_ssize_t n;         /* guess for result tuple size */ -	PyObject *result; +	PyObject *result = NULL;  	Py_ssize_t j;  	if (v == NULL) @@ -2153,6 +2156,8 @@ PySequence_Tuple(PyObject *v)  	/* Guess result size and allocate space. */  	n = _PyObject_LengthHint(v, 10); +	if (n == -1) +		goto Fail;  	result = PyTuple_New(n);  	if (result == NULL)  		goto Fail;  | 
