summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2007-12-08 15:33:56 (GMT)
committerChristian Heimes <christian@cheimes.de>2007-12-08 15:33:56 (GMT)
commit255f53bdb54a64b93035374ca4484ba0cc1b41e1 (patch)
treefdbd2aca3415d4f14435e402157e24b96c6de884 /Objects
parent226679ae095b70eb03505a817912097b8e816fb0 (diff)
downloadcpython-255f53bdb54a64b93035374ca4484ba0cc1b41e1.zip
cpython-255f53bdb54a64b93035374ca4484ba0cc1b41e1.tar.gz
cpython-255f53bdb54a64b93035374ca4484ba0cc1b41e1.tar.bz2
Merged revisions 59376-59406 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r59377 | georg.brandl | 2007-12-06 01:24:23 +0100 (Thu, 06 Dec 2007) | 2 lines Add another GHOP student to ACKS. ........ r59378 | raymond.hettinger | 2007-12-06 01:56:53 +0100 (Thu, 06 Dec 2007) | 5 lines Fix Issue 1045. Factor-out common calling code by simplifying the length_hint API. Speed-up the function by caching the PyObject_String for the attribute lookup. ........ r59380 | georg.brandl | 2007-12-06 02:52:24 +0100 (Thu, 06 Dec 2007) | 2 lines Diverse markup fixes. ........ r59383 | georg.brandl | 2007-12-06 10:45:39 +0100 (Thu, 06 Dec 2007) | 2 lines Better re.split examples. ........ r59386 | christian.heimes | 2007-12-06 14:15:13 +0100 (Thu, 06 Dec 2007) | 2 lines Fixed get_config_h_filename for Windows. Without the patch it can't find the pyconfig.h file inside a build tree. Added several small unit tests for sysconfig. ........ r59387 | christian.heimes | 2007-12-06 14:30:11 +0100 (Thu, 06 Dec 2007) | 1 line Silence more warnings, _CRT_NONSTDC_NO_DEPRECATE is already defined in pyconfig.h but several projects don't include it. ........ r59389 | christian.heimes | 2007-12-06 14:55:01 +0100 (Thu, 06 Dec 2007) | 1 line Disabled one test that is failing on Unix ........ r59399 | christian.heimes | 2007-12-06 22:13:06 +0100 (Thu, 06 Dec 2007) | 8 lines Several Windows related cleanups: * Removed a #define from pyconfig.h. The macro was already defined a few lines higher. * Fixed path to tix in the build_tkinter.py script * Changed make_buildinfo.c to use versions of unlink and strcat which are considered safe by Windows (as suggested by MvL). * Removed two defines from pyproject.vsprops that are no longer required. Both are defined in pyconfig.h and make_buildinfo.c doesn't use the unsafe versions any more (as suggested by MvL). * Added some more information about PGO and the property files to PCbuild9/readme.txt. Are you fine with the changes, Martin? ........ r59400 | raymond.hettinger | 2007-12-07 02:53:01 +0100 (Fri, 07 Dec 2007) | 4 lines Don't have the docs berate themselves. Keep a professional tone. If a todo is needed, put it in the tracker. ........ r59402 | georg.brandl | 2007-12-07 10:07:10 +0100 (Fri, 07 Dec 2007) | 3 lines Increase unit test coverage of SimpleXMLRPCServer. Written for GHOP by Turkay Eren. ........ r59406 | georg.brandl | 2007-12-07 16:16:57 +0100 (Fri, 07 Dec 2007) | 2 lines Update to windows doc from Robert. ........
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c68
-rw-r--r--Objects/bytesobject.c15
-rw-r--r--Objects/listobject.c12
3 files changed, 41 insertions, 54 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index df5da5f..8b3006a 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -80,29 +80,47 @@ PyObject_Length(PyObject *o)
}
#define PyObject_Length PyObject_Size
+
+/* 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.
+*/
+
Py_ssize_t
-_PyObject_LengthHint(PyObject *o)
+_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
{
- Py_ssize_t rv = PyObject_Size(o);
- if (rv != -1)
+ static PyObject *hintstrobj = NULL;
+ PyObject *ro;
+ Py_ssize_t rv;
+
+ /* try o.__len__() */
+ rv = PyObject_Size(o);
+ if (rv >= 0)
return rv;
- if (PyErr_ExceptionMatches(PyExc_TypeError) ||
- PyErr_ExceptionMatches(PyExc_AttributeError)) {
- PyObject *err_type, *err_value, *err_tb, *ro;
-
- PyErr_Fetch(&err_type, &err_value, &err_tb);
- ro = PyObject_CallMethod(o, "__length_hint__", NULL);
- if (ro != NULL) {
- rv = PyLong_AsLong(ro);
- Py_DECREF(ro);
- Py_XDECREF(err_type);
- Py_XDECREF(err_value);
- Py_XDECREF(err_tb);
- return rv;
- }
- PyErr_Restore(err_type, err_value, err_tb);
+ if (PyErr_Occurred())
+ PyErr_Clear();
+
+ /* cache a hashed version of the attribute string */
+ if (hintstrobj == NULL) {
+ hintstrobj = PyUnicode_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;
+ rv = PyLong_AsSsize_t(ro);
+ Py_DECREF(ro);
+ if (rv >= 0)
+ return rv;
+
+defaultcase:
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return defaultvalue;
}
PyObject *
@@ -1655,17 +1673,7 @@ PySequence_Tuple(PyObject *v)
return NULL;
/* Guess result size and allocate space. */
- n = _PyObject_LengthHint(v);
- if (n < 0) {
- if (PyErr_Occurred()
- && !PyErr_ExceptionMatches(PyExc_TypeError)
- && !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- Py_DECREF(it);
- return NULL;
- }
- PyErr_Clear();
- n = 10; /* arbitrary */
- }
+ n = _PyObject_LengthHint(v, 10);
result = PyTuple_New(n);
if (result == NULL)
goto Fail;
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index c0f4e81..9e16b3b 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2598,19 +2598,8 @@ bytes_extend(PyBytesObject *self, PyObject *arg)
if (it == NULL)
return NULL;
- /* Try to determine the length of the argument. */
- buf_size = _PyObject_LengthHint(arg);
- /* The length of the argument is unknown or invalid. */
- if (buf_size < 0) {
- if (PyErr_Occurred()
- && !PyErr_ExceptionMatches(PyExc_TypeError)
- && !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- Py_DECREF(it);
- return NULL;
- }
- PyErr_Clear();
- buf_size = 32; /* arbitrary */
- }
+ /* Try to determine the length of the argument. 32 is abitrary. */
+ buf_size = _PyObject_LengthHint(arg, 32);
buf = (char *)PyMem_Malloc(buf_size * sizeof(char));
if (buf == NULL)
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 18d3b90..efcedc7 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -758,17 +758,7 @@ listextend(PyListObject *self, PyObject *b)
iternext = *it->ob_type->tp_iternext;
/* Guess a result list size. */
- n = _PyObject_LengthHint(b);
- if (n < 0) {
- if (PyErr_Occurred()
- && !PyErr_ExceptionMatches(PyExc_TypeError)
- && !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- Py_DECREF(it);
- return NULL;
- }
- PyErr_Clear();
- n = 8; /* arbitrary */
- }
+ n = _PyObject_LengthHint(b, 8);
m = Py_Size(self);
mn = m + n;
if (mn >= m) {