Fix typos and nits reported by various correspondents,
add a few clarifications and new open issues. Only the easy stuff.
This commit is contained in:
parent
43d62602d0
commit
e432788d3f
75
pep-3119.txt
75
pep-3119.txt
|
@ -183,6 +183,11 @@ may have an implementation. This implementation can be called via the
|
||||||
useful as an end-point for a super-call in framework using a
|
useful as an end-point for a super-call in framework using a
|
||||||
cooperative multiple-inheritance [7]_, [8]_.
|
cooperative multiple-inheritance [7]_, [8]_.
|
||||||
|
|
||||||
|
**Open issues:** Should we also provide a standard way to declare
|
||||||
|
abstract data attributes? If so, how should these be spelled?
|
||||||
|
Perhaps place ``@abstractattribute`` decorators on properties? Or use
|
||||||
|
an ``@attributes(name1, name2, ...)`` class decorator?
|
||||||
|
|
||||||
|
|
||||||
Overloading ``isinstance()`` and ``issubclass()``
|
Overloading ``isinstance()`` and ``issubclass()``
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
@ -213,7 +218,7 @@ The solution proposed here is to allow overloading the built-in
|
||||||
functions ``isinstance()`` and ``issubclass()``. The overloading
|
functions ``isinstance()`` and ``issubclass()``. The overloading
|
||||||
works as follows: The call ``isinstance(x, C)`` first checks whether
|
works as follows: The call ``isinstance(x, C)`` first checks whether
|
||||||
``C.__instancecheck__`` exists, and if so, calls
|
``C.__instancecheck__`` exists, and if so, calls
|
||||||
``C.__subclasscheck__(x)`` instead of its normal implementation.
|
``C.__instancecheck__(x)`` instead of its normal implementation.
|
||||||
Similarly, the call ``issubclass(D, C)`` first checks whether
|
Similarly, the call ``issubclass(D, C)`` first checks whether
|
||||||
``C.__subclasscheck__`` exists, and if so, calls
|
``C.__subclasscheck__`` exists, and if so, calls
|
||||||
``C.__subclasscheck__(D)`` instead of its normal implementation.
|
``C.__subclasscheck__(D)`` instead of its normal implementation.
|
||||||
|
@ -272,11 +277,12 @@ example, the ``Iterator`` class has an ``__iter__`` method returning
|
||||||
itself, fulfilling an important invariant of iterators (which in
|
itself, fulfilling an important invariant of iterators (which in
|
||||||
Python 2 has to be implemented anew by each iterator class).
|
Python 2 has to be implemented anew by each iterator class).
|
||||||
|
|
||||||
No ABCs override ``__init__``, ``__new__``, ``__str__`` or
|
No ABCs defined in the PEP override ``__init__``, ``__new__``,
|
||||||
``__repr__``. Defining a standard constructor signature would
|
``__str__`` or ``__repr__``. Defining a standard constructor
|
||||||
unnecessarily constrain custom container types, for example Patricia
|
signature would unnecessarily constrain custom container types, for
|
||||||
trees or gdbm files. Defining a specific string representation for a
|
example Patricia trees or gdbm files. Defining a specific string
|
||||||
collection is similarly left up to individual implementations.
|
representation for a collection is similarly left up to individual
|
||||||
|
implementations.
|
||||||
|
|
||||||
|
|
||||||
Ordering ABCs
|
Ordering ABCs
|
||||||
|
@ -328,6 +334,8 @@ These abstract classes represent single methods like ``__iter__`` or
|
||||||
**Note:** being an instance of this class does not imply that an
|
**Note:** being an instance of this class does not imply that an
|
||||||
object is immutable; e.g. a tuple containing a list as a member is
|
object is immutable; e.g. a tuple containing a list as a member is
|
||||||
not immutable; its ``__hash__`` method raises ``TypeError``.
|
not immutable; its ``__hash__`` method raises ``TypeError``.
|
||||||
|
(This is because it recursively tries to compute the hash of each
|
||||||
|
member; if a member is unhashable it raises ``TypeError``.)
|
||||||
|
|
||||||
``Iterable``
|
``Iterable``
|
||||||
The base class for classes defining ``__iter__``. The
|
The base class for classes defining ``__iter__``. The
|
||||||
|
@ -357,18 +365,20 @@ These abstract classes represent single methods like ``__iter__`` or
|
||||||
``Iterable``, then ``(x in o for x in o)`` should be a generator
|
``Iterable``, then ``(x in o for x in o)`` should be a generator
|
||||||
yielding only True values for any instance ``o`` of ``C``.
|
yielding only True values for any instance ``o`` of ``C``.
|
||||||
|
|
||||||
**Note:** strictly speaking, there are three variants of this method's
|
**Open issues:** strictly speaking, there are three variants of
|
||||||
semantics. The first one is for sets and mappings, which is fast:
|
this method's semantics. The first one is for sets and mappings,
|
||||||
O(1) or O(log N). The second one is for membership checking on
|
which is fast: O(1) or O(log N). The second one is for membership
|
||||||
sequences, which is slow: O(N). The third one is for subsequence
|
checking on sequences, which is slow: O(N). The third one is for
|
||||||
checking on (character or byte) strings, which is also slow: O(N).
|
subsequence checking on (character or byte) strings, which is also
|
||||||
Would it make sense to distinguish these? The signature of the
|
slow: O(N). Would it make sense to distinguish these? The
|
||||||
third variant is different, since it takes a sequence (typically
|
signature of the third variant is different, since it takes a
|
||||||
of the same type as the method's target) intead of an element.
|
sequence (typically of the same type as the method's target)
|
||||||
For now, I'm using the same type for all three. This means that
|
intead of an element. For now, I'm using the same type for all
|
||||||
is is possible for ``x in o`` to be True even though ``x`` is
|
three. This means that is is possible for ``x in o`` to be True
|
||||||
never yielded by ``iter(o)``. A suggested name for the third form
|
even though ``x`` is never yielded by ``iter(o)``. A suggested
|
||||||
is ``Searchable``.
|
name for the third form is ``Searchable`` (though people have
|
||||||
|
objected against this name on the grounds that it has the wrong
|
||||||
|
association).
|
||||||
|
|
||||||
|
|
||||||
Sets
|
Sets
|
||||||
|
@ -489,9 +499,10 @@ out of the scope of a pragmatic proposal like this.
|
||||||
implementation raises ``NotImplementedError``.
|
implementation raises ``NotImplementedError``.
|
||||||
|
|
||||||
``.pop()``
|
``.pop()``
|
||||||
Concrete method that removes an arbitrary item. If the set is
|
Concrete method that removes and returns an arbitrary item.
|
||||||
empty, it raises ``KeyError``. The default implementation
|
If the set is empty, it raises ``KeyError``. The default
|
||||||
removes the first item returned by the set's iterator.
|
implementation removes the first item returned by the set's
|
||||||
|
iterator.
|
||||||
|
|
||||||
``.toggle(x)``
|
``.toggle(x)``
|
||||||
Concrete method returning a ``bool`` that adds x to the set if
|
Concrete method returning a ``bool`` that adds x to the set if
|
||||||
|
@ -543,7 +554,7 @@ The built-in type ``dict`` derives from ``MutableMapping``.
|
||||||
Concrete method returning ``self[key]`` if this does not raise
|
Concrete method returning ``self[key]`` if this does not raise
|
||||||
``KeyError``, and the ``default`` value if it does.
|
``KeyError``, and the ``default`` value if it does.
|
||||||
|
|
||||||
``.__contains__()``
|
``.__contains__(key)``
|
||||||
Concrete method returning ``True`` if ``self[key]`` does not
|
Concrete method returning ``True`` if ``self[key]`` does not
|
||||||
raise ``KeyError``, and ``False`` if it does.
|
raise ``KeyError``, and ``False`` if it does.
|
||||||
|
|
||||||
|
@ -553,42 +564,44 @@ The built-in type ``dict`` derives from ``MutableMapping``.
|
||||||
are also referred to as items. The items also form a set.
|
are also referred to as items. The items also form a set.
|
||||||
Methods:
|
Methods:
|
||||||
|
|
||||||
``__len__``
|
``.__len__()``
|
||||||
Abstract method returning the length of the key set.
|
Abstract method returning the length of the key set.
|
||||||
|
|
||||||
``__iter__``
|
``.__iter__()``
|
||||||
Abstract method returning each key in the key set exactly once.
|
Abstract method returning each key in the key set exactly once.
|
||||||
|
|
||||||
``__eq__``
|
``.__eq__(obj)``
|
||||||
Concrete method for comparing mappings. Two mappings, even
|
Concrete method for comparing mappings. Two mappings, even
|
||||||
with different implementations, can be compared for equality,
|
with different implementations, can be compared for equality,
|
||||||
and are considered equal if and only iff their item sets are
|
and are considered equal if and only if their item sets are
|
||||||
equal. **Open issues:** should we define comparison of
|
equal. **Open issues:** should we define comparison of
|
||||||
instances of different concrete mapping types this way?
|
instances of different concrete mapping types this way?
|
||||||
|
|
||||||
``keys``
|
``.keys()``
|
||||||
Concrete method returning the key set as a ``Set``. The
|
Concrete method returning the key set as a ``Set``. The
|
||||||
default concrete implementation returns a "view" on the key
|
default concrete implementation returns a "view" on the key
|
||||||
set (meaning if the underlying mapping is modified, the view's
|
set (meaning if the underlying mapping is modified, the view's
|
||||||
value changes correspondingly); subclasses are not required to
|
value changes correspondingly); subclasses are not required to
|
||||||
return a view but they should return a ``Set``.
|
return a view but they should return a ``Set``.
|
||||||
|
|
||||||
``items``
|
``.items()``
|
||||||
Concrete method returning the items as a ``Set``. The default
|
Concrete method returning the items as a ``Set``. The default
|
||||||
concrete implementation returns a "view" on the item set;
|
concrete implementation returns a "view" on the item set;
|
||||||
subclasses are not required to return a view but they should
|
subclasses are not required to return a view but they should
|
||||||
return a ``Set``.
|
return a ``Set``.
|
||||||
|
|
||||||
``values``
|
``.values()``
|
||||||
Concrete method returning the values as a sized, iterable
|
Concrete method returning the values as a sized, iterable
|
||||||
container (not a set!). The default concrete implementation
|
container (not a set!). The default concrete implementation
|
||||||
returns a "view" on the values of the mapping; subclasses are
|
returns a "view" on the values of the mapping; subclasses are
|
||||||
not required to return a view but they should return a sized,
|
not required to return a view but they should return a sized,
|
||||||
iterable container.
|
iterable container.
|
||||||
|
|
||||||
The following invariant should hold for any mapping ``m``::
|
The following invariants should hold for any mapping ``m``::
|
||||||
|
|
||||||
list(m.items()) == list(zip(m.keys(), m.values()))
|
len(m.values()) == len(m.keys()) == len(m.items()) == len(m)
|
||||||
|
[value for value in m.values()] == [m[key] for key in m.keys()]
|
||||||
|
[item for item in m.items()] == [(key, m[key]) for key in m.keys()]
|
||||||
|
|
||||||
i.e. iterating over the items, keys and values should return
|
i.e. iterating over the items, keys and values should return
|
||||||
results in the same order.
|
results in the same order.
|
||||||
|
|
Loading…
Reference in New Issue