Update PEP-0424 with respect to feedback received.

This commit is contained in:
Alex Gaynor 2012-07-16 20:00:55 -07:00
parent b01cd39186
commit aec429dfa9
1 changed files with 37 additions and 6 deletions

View File

@ -15,7 +15,7 @@ Abstract
CPython currently defines an ``__length_hint__`` method on several types, such CPython currently defines an ``__length_hint__`` method on several types, such
as various iterators. This method is then used by various other functions (such as various iterators. This method is then used by various other functions (such
as ``map``) to presize lists based on the estimated returned by as ``list``) to presize lists based on the estimated returned by
``__length_hint__``. Types can then define ``__length_hint__`` which are not ``__length_hint__``. Types can then define ``__length_hint__`` which are not
sized, and thus should not define ``__len__``, but can estimate or compute a sized, and thus should not define ``__len__``, but can estimate or compute a
size (such as many iterators). size (such as many iterators).
@ -26,11 +26,42 @@ Proposal
This PEP proposes formally documenting ``__length_hint__`` for other This PEP proposes formally documenting ``__length_hint__`` for other
interpreter and non-standard library Python to implement. interpreter and non-standard library Python to implement.
``__length_hint__`` must return an integer (else a TypeError is raised), and is ``__length_hint__`` must return an integer (else a TypeError is raised) or
not required to be accurate. It may return a value that is either larger or ``NotImplemented, and is not required to be accurate. It may return a value
smaller than the actual size ofthe container. It may raise a ``TypeError`` if a that is either larger or smaller than the actual size ofthe container. A return value of ``NotImplemented`` indicates that there is no finite length estimate.
specific instance cannot have its length estimated. It may not return a It may not return a negative value (else a ValueError is raised).
negative value (else a ValueError is raised).
In addition, a new function ``operator.length`` hint is added, having the
follow semantics (which define how ``__length_hint__`` should be used::
def length_hint(obj, default):
"""
Return an estimate of the number of items in obj. This is
useful for presizing containers when building from an iterable.
If the object supports len(), the result will be exact. Otherwise, it
may over or underestimate by an arbitrary amount. The result will be an
integer >= 0.
"""
try:
return len(obj)
except TypeError:
try:
get_hint = obj.__length_hint__
except AttributeError:
return default
hint = get_hint()
if hint is NotImplemented:
return default
if not isinstance(hint, int):
raise TypeError("Length hint must be an integer, not %r" % type(hint))
if hint < 0:
raise ValueError("Length hint (%r) must be >= 0" % hint)
return hint
Callers are required to provide a default value, because there is no sane
return value for objects which do not provide a length or length hint.
Rationale Rationale
========= =========