Fixed a number of typos, and made some semantic updates in a few areas I

was sure about.
This commit is contained in:
Tim Peters 2001-09-21 07:56:16 +00:00
parent 0bc40d7a97
commit a307f83a41
1 changed files with 47 additions and 52 deletions

View File

@ -107,7 +107,7 @@ About metatypes
<type 'type'>
>>> type(type(type(a)))
<type 'type'>
>>>
>>>
In this example, type(a) is a "regular" type, and type(type(a)) is
a metatype. While as distributed all types have the same metatype
@ -146,7 +146,7 @@ About metatypes
example, Python code will never be allowed to allocate raw memory
and initialize it at will.)
Metatypes determine various *policies* for types,such as what
Metatypes determine various *policies* for types, such as what
happens when a type is called, how dynamic types are (whether a
type's __dict__ can be modified after it is created), what the
method resolution order is, how instance attributes are looked
@ -223,13 +223,13 @@ Making a type a factory for its instances
reference to an existing object is fine too. The return value
should always be a new reference, owned by the caller.
One the tp_new slot has returned an object, further initialization
Once the tp_new slot has returned an object, further initialization
is attempted by calling the tp_init() slot of the resulting
object's type, if not NULL. This has the following signature:
PyObject *tp_init(PyObject *self,
PyObject *args,
PyObject *kwds)
int tp_init(PyObject *self,
PyObject *args,
PyObject *kwds)
It corresponds more closely to the __init__() method of classic
classes, and in fact is mapped to that by the slot/special-method
@ -237,7 +237,7 @@ Making a type a factory for its instances
the tp_new() slot and the tp_init() slot lies in the invariants
they ensure. The tp_new() slot should ensure only the most
essential invariants, without which the C code that implements the
object's would break. The tp_init() slot should be used for
objects would break. The tp_init() slot should be used for
overridable user-specific initializations. Take for example the
dictionary type. The implementation has an internal pointer to a
hash table which should never be NULL. This invariant is taken
@ -272,6 +272,10 @@ Making a type a factory for its instances
object; in this case tp_new() should always return a new object
(or raise an exception).
Both tp_new() and tp_init() should receive exactly the same 'args'
and 'kwds' arguments, and both should check that the arguments are
acceptable, because they may be called independently.
There's a third slot related to object creation: tp_alloc(). Its
responsibility is to allocate the memory for the object,
initialize the reference count (ob_refcnt) and the type pointer
@ -291,7 +295,7 @@ Making a type a factory for its instances
type->tp_basicsize + nitems * type->tp_itemsize
This slot is only used for subclassable types. The tp_new()
The tp_alloc slot is only used for subclassable types. The tp_new()
function of the base class must call the tp_alloc() slot of the
type passed in as its first argument. It is the tp_new()
function's responsibility to calculate the number of items. The
@ -303,13 +307,6 @@ Making a type a factory for its instances
counters for the number of allocations and deallocations. These
are renamed to tp_allocs and tp_deallocs.)
XXX The keyword arguments are currently not passed to tp_new();
its kwds argument is always NULL. This is a relic from a previous
revision and should probably be fixed. Both tp_new() and
tp_init() should receive exactly the same arguments, and both
should check that the arguments are acceptable, because they may
be called independently.
Standard implementations for tp_alloc() and tp_new() are
available. PyType_GenericAlloc() allocates an object from the
standard heap and initializes it properly. It uses the above
@ -332,7 +329,7 @@ Preparing a type for subtyping
structure (but must leave the names, order and type of the members
of the base structure unchanged) and can override certain slots in
the type object, leaving others the same. (Unlike C++ vtables,
all Python type objects have the same memory lay-out.)
all Python type objects have the same memory layout.)
The base type must do the following:
@ -357,7 +354,7 @@ Preparing a type for subtyping
It should come as no surprise that there are similar conventions
at the end of an object's lifetime. The slots involved are
tp_dealloc() (familiar to all who have ever implemented a Python
extension type) and tp_free(), the new kid on he block. (The
extension type) and tp_free(), the new kid on the block. (The
names aren't quite symmetric; tp_free() corresponds to tp_alloc(),
which is fine, but tp_dealloc() corresponds to tp_new(). Maybe
the tp_dealloc slot should be renamed?)
@ -398,7 +395,12 @@ Preparing a type for subtyping
functions that require an instance of the base type may be invoked
with instances of the derived type. Before enabling subtyping of
a particular type, its code should be checked to make sure that
this won't break anything.
this won't break anything. It has proved useful in the prototype
to add another type-checking macro for the built-in Python object
types, to check for exact type match too (for example,
PyDict_Check(x) is true if x is an instance of dictionary or of a
dictionary subclass, while PyDict_CheckExact(x) is true only if x
is a dictionary).
Creating a subtype of a built-in type in C
@ -427,7 +429,7 @@ Creating a subtype of a built-in type in C
be the first member of the structure; any following members are
additions. Also note that the base type is not referenced via a
pointer; the actual contents of its structure must be included!
(The goal is for the memory lay out of the beginning of the
(The goal is for the memory layout of the beginning of the
subtype instance to be the same as that of the base type
instance.)
@ -553,8 +555,8 @@ Subtyping in Python
C = M("C", (B,), dict)
(where dict is the dictionary resulting from execution of the
class body). In other words, the metatype (M) is called.
where dict is the dictionary resulting from execution of the
class body. In other words, the metatype (M) is called.
Note that even though the example has only one base, we still pass
in a (singleton) sequence of bases; this makes the interface
@ -577,11 +579,11 @@ Subtyping in Python
There are two further refinements here. First, a useful feature
is to be able to specify a metatype directly. If the class
statement defines a variable __metaclass__, that is the metatype
suite defines a variable __metaclass__, that is the metatype
to call. (Note that setting __metaclass__ at the module level
only affects class statements without a base class and without an
explicit __metaclass__ declaration; but setting __metaclass__ in a
class statement overrides the default metatype unconditionally.)
class suite overrides the default metatype unconditionally.)
Second, with multiple bases, not all bases need to have the same
metatype. This is called a metaclass conflict [1]. Some
@ -590,8 +592,8 @@ Subtyping in Python
metatypes. If such a metatype cannot be found, an exception is
raised and the class statement fails.
This conflict resultion can be implemented in the metatypes
itself: the class statement just calls the metatype of the first
This conflict resolution can be implemented by the metatype
constructors: the class statement just calls the metatype of the first
base (or that specified by the __metaclass__ variable), and this
metatype's constructor looks for the most derived metatype. If
that is itself, it proceeds; otherwise, it calls that metatype's
@ -621,17 +623,16 @@ Subtyping in Python
turned out to be unnecessary.)
In any case, the work for creating C is done by M's tp_new() slot.
It allocates space for an "extended" type structure, which
contains space for: the type object; the auxiliary structures
(as_sequence etc.); the string object containing the type name (to
ensure that this object isn't deallocated while the type object is
still referencing it); and some more auxiliary storage (to be
described later). It initializes this storage to zeros except for
a few crucial slots (for example, tp_name is set to point to the
type name) and then sets the tp_base slot to point to B. Then
PyType_InitDict() is called to inherit B's slots. Finally, C's
tp_dict slot is updated with the contents of the namespace
dictionary (the third argument to the call to M).
It allocates space for an "extended" type structure, containing:
the type object; the auxiliary structures (as_sequence etc.); the
string object containing the type name (to ensure that this object
isn't deallocated while the type object is still referencing it); and
some auxiliary storage (to be described later). It initializes this
storage to zeros except for a few crucial slots (for example, tp_name
is set to point to the type name) and then sets the tp_base slot to
point to B. Then PyType_InitDict() is called to inherit B's slots.
Finally, C's tp_dict slot is updated with the contents of the
namespace dictionary (the third argument to the call to M).
Multiple inheritance
@ -672,9 +673,9 @@ Multiple inheritance
(Here, 'dictionary' is the type of built-in dictionary objects,
a.k.a. type({}) or {}.__class__ or types.DictType.) If we look at
the structure lay-out, we find that an A instance has the lay-out
the structure layout, we find that an A instance has the layout
of a dictionary followed by the __dict__ pointer, and a B instance
has the same lay-out; since there are no structure member lay-out
has the same layout; since there are no structure member layout
conflicts, this is okay.
Here's another example:
@ -688,7 +689,7 @@ Multiple inheritance
class Z(X, Y): pass
(Here, 'object' is the base for all built-in types; its structure
lay-out only contains the ob_refcnt and ob_type members.) This
layout only contains the ob_refcnt and ob_type members.) This
example is more complicated, because the __dict__ pointer for X
instances has a different offset than that for Y instances. Where
is the __dict__ pointer for Z instances? The answer is that the
@ -700,7 +701,7 @@ Multiple inheritance
is 4 bytes. Then an X structure is 12 bytes (an object structure
followed by a __dict__ pointer), and a Y structure is 64 bytes (a
dictionary structure followed by a __dict__ pointer). The Z
structure has the same lay-out as the Y structure in this example.
structure has the same layout as the Y structure in this example.
Each type object (X, Y and Z) has a "__dict__ offset" which is
used to find the __dict__ pointer. Thus, the recipe for looking
up an instance variable is:
@ -722,7 +723,7 @@ Multiple inheritance
below.
Method resolution order (the lookup rule)
MRO: Method resolution order (the lookup rule)
With multiple inheritance comes the question of method resolution
order: the order in which a class or type and its bases are
@ -776,7 +777,7 @@ Method resolution order (the lookup rule)
are rarely found in classic Python class hierarchies. Most class
hierarchies use single inheritance, and multiple inheritance is
usually confined to mix-in classes. In fact, the problem shown
here is probably the reason why multiple inheritance is impopular
here is probably the reason why multiple inheritance is unpopular
in classic Python.
Why will this be a problem in the new system? The 'object' type
@ -917,7 +918,7 @@ XXX To be done
- should we return to the old __getattr__ semantics, and
introduce a new name (__getallattr__?) for the new semantics?
or introduce a new name (__getattrhook__?)for the old
or introduce a new name (__getattrhook__?) for the old
semantics?
- whether __dynamic__ should be default
@ -937,15 +938,9 @@ XXX To be done
Implementation
A prototype implementation of this PEP (and for PEP 252) is
available from CVS as a branch named "descr-branch". To
experiment with this implementation, proceed to check out Python
from CVS according to the instructions at
http://sourceforge.net/cvs/?group_id=5470 but add the arguments
"-r descr-branch" to the cvs checkout command. (You can also
start with an existing checkout and do "cvs update -r
descr-branch".) For some examples of the features described here,
see the file Lib/test/test_descr.py and the extension module
Modules/xxsubtype.c.
available from CVS, and in the series of Python 2.2 alpha releases.
For some examples of the features described here, see the file
Lib/test/test_descr.py and the extension module Modules/xxsubtype.c.
References