Issue #16148: Small improvements and cleanup. Added version information

to docs.
This commit is contained in:
Armin Ronacher 2012-10-07 10:29:32 +02:00
parent 96e936712f
commit 74b38b190f
6 changed files with 24 additions and 9 deletions

View File

@ -349,6 +349,8 @@ is considered sufficient for this determination.
returning the default value. On error ``-1`` is returned. This is the returning the default value. On error ``-1`` is returned. This is the
equivalent to the Python expression ``operator.length_hint(o, default)``. equivalent to the Python expression ``operator.length_hint(o, default)``.
.. versionadded:: 3.4
.. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) .. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key)
Return element of *o* corresponding to the object *key* or *NULL* on failure. Return element of *o* corresponding to the object *key* or *NULL* on failure.

View File

@ -241,6 +241,8 @@ their character equivalents.
actual length, then an estimate using ``__length_hint__``, and finally actual length, then an estimate using ``__length_hint__``, and finally
returning the default value. returning the default value.
.. versionadded:: 3.4
The :mod:`operator` module also defines tools for generalized attribute and item The :mod:`operator` module also defines tools for generalized attribute and item
lookups. These are useful for making fast field extractors as arguments for lookups. These are useful for making fast field extractors as arguments for
:func:`map`, :func:`sorted`, :meth:`itertools.groupby`, or other functions that :func:`map`, :func:`sorted`, :meth:`itertools.groupby`, or other functions that

View File

@ -1805,6 +1805,15 @@ through the container; for mappings, :meth:`__iter__` should be the same as
considered to be false in a Boolean context. considered to be false in a Boolean context.
.. method:: object.__length_hint__(self)
Called to implement ``operator.length_hint``. Should return an estimated
length for the object (which may be greater or less than the actual length).
The length must be an integer ``>=`` 0. This method is purely an
optimization and is never required for correctness.
.. versionadded:: 3.4
.. note:: .. note::
Slicing is done exclusively with the following three methods. A call like :: Slicing is done exclusively with the following three methods. A call like ::

View File

@ -403,7 +403,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o);
#define PyObject_Length PyObject_Size #define PyObject_Length PyObject_Size
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); #ifndef Py_LIMITED_API
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
#endif
PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t);
/* /*

View File

@ -170,7 +170,6 @@ class TestReversed(unittest.TestCase, PickleTest):
self.assertEqual(type(reversed(x)), type(iter(x))) self.assertEqual(type(reversed(x)), type(iter(x)))
def test_len(self): def test_len(self):
# This is an implementation detail, not an interface requirement
for s in ('hello', tuple('hello'), list('hello'), range(5)): for s in ('hello', tuple('hello'), list('hello'), range(5)):
self.assertEqual(operator.length_hint(reversed(s)), len(s)) self.assertEqual(operator.length_hint(reversed(s)), len(s))
r = reversed(s) r = reversed(s)

View File

@ -71,8 +71,9 @@ _PyObject_HasLen(PyObject *o) {
} }
/* The length hint function returns a non-negative value from o.__len__() /* The length hint function returns a non-negative value from o.__len__()
or o.__length_hint__(). If those methods aren't found. If one of the calls or o.__length_hint__(). If those methods aren't found the defaultvalue is
fails this function returns -1. returned. If one of the calls fails with an exception other than TypeError
this function returns -1.
*/ */
Py_ssize_t Py_ssize_t
@ -112,21 +113,21 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
return defaultvalue; return defaultvalue;
} }
if (!PyLong_Check(result)) { if (!PyLong_Check(result)) {
PyErr_Format(PyExc_TypeError, "Length hint must be an integer, not %s", PyErr_Format(PyExc_TypeError, "__length_hint__ must be an integer, not %.100s",
Py_TYPE(result)->tp_name); Py_TYPE(result)->tp_name);
Py_DECREF(result); Py_DECREF(result);
return -1; return -1;
} }
defaultvalue = PyLong_AsSsize_t(result); res = PyLong_AsSsize_t(result);
Py_DECREF(result); Py_DECREF(result);
if (defaultvalue < 0 && PyErr_Occurred()) { if (res < 0 && PyErr_Occurred()) {
return -1; return -1;
} }
if (defaultvalue < 0) { if (res < 0) {
PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0"); PyErr_Format(PyExc_ValueError, "__length_hint__() should return >= 0");
return -1; return -1;
} }
return defaultvalue; return res;
} }
PyObject * PyObject *