[Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.9,1.10

Guido van Rossum gvanrossum@users.sourceforge.net
2001年7月10日 13:46:26 -0700


Update of /cvsroot/python/python/nondist/peps
In directory usw-pr-cvs1:/tmp/cvs-serv17390
Modified Files:
	pep-0253.txt 
Log Message:
Just a little bit more cleanup. Added a TODO list.
Index: pep-0253.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** pep-0253.txt	2001年07月10日 20:01:52	1.9
--- pep-0253.txt	2001年07月10日 20:46:24	1.10
***************
*** 61,66 ****
 supported
 
- - there will be a standard type hierarchy (maybe)
- 
 This PEP builds on PEP 252, which adds standard introspection to
 types; for example, when a particular type object initializes the
--- 61,64 ----
***************
*** 341,351 ****
 
 The base type must do the following:
 
! - Add the flag value Py_TPFLAGS_BASETYPE to tp_flags.
! - Declare and use tp_new(), tp_alloc() and optional tp_init() slots.
! - Declare and use tp_dealloc() and tp_free().
! - Export its object structure declaration.
! - Export a subtyping-aware type-checking macro.
 
 The requirements and signatures for tp_new(), tp_alloc() and
 tp_init() have already been discussed above: tp_alloc() should
--- 339,354 ----
 
 The base type must do the following:
+ 
+ - Add the flag value Py_TPFLAGS_BASETYPE to tp_flags.
+ 
+ - Declare and use tp_new(), tp_alloc() and optional tp_init()
+ slots.
+ 
+ - Declare and use tp_dealloc() and tp_free().
 
! - Export its object structure declaration.
 
+ - Export a subtyping-aware type-checking macro.
+ 
 The requirements and signatures for tp_new(), tp_alloc() and
 tp_init() have already been discussed above: tp_alloc() should
***************
*** 435,458 ****
 zero, which is a signal that the base type slot must be copied
 into it. Some slots that must be initialized properly:
- 
- - The object header must be filled in as usual; the type should be
- &PyType_Type.
- 
- - The tp_basicsize slot must be set to the size of the subtype
- instance struct (in the above example: sizeof(spamlistobject)).
 
! - The tp_base slot must be set to the address of the base type's
! type object.
 
! - If the derived slot defines any pointer members, the tp_dealloc
! slot function requires special attention, see below; otherwise,
! it can be set to zero, to inherit the base type's deallocation
! function.
 
! - The tp_flags slot must be set to the usual Py_TPFLAGS_DEFAULT
! value.
 
! - The tp_name slot must be set; it is recommended to set tp_doc
! as well (these are not inherited).
 
 If the subtype defines no additional structure members (it only
--- 438,462 ----
 zero, which is a signal that the base type slot must be copied
 into it. Some slots that must be initialized properly:
 
! - The object header must be filled in as usual; the type should
! be &PyType_Type.
 
! - The tp_basicsize slot must be set to the size of the subtype
! instance struct (in the above example:
! sizeof(spamlistobject)).
! 
! - The tp_base slot must be set to the address of the base type's
! type object.
! 
! - If the derived slot defines any pointer members, the
! tp_dealloc slot function requires special attention, see
! below; otherwise, it can be set to zero, to inherit the base
! type's deallocation function.
 
! - The tp_flags slot must be set to the usual Py_TPFLAGS_DEFAULT
! value.
 
! - The tp_name slot must be set; it is recommended to set tp_doc
! as well (these are not inherited).
 
 If the subtype defines no additional structure members (it only
***************
*** 531,548 ****
 
 Assume B is a type object. Since type objects are objects, and
! every object has a type, B has a type. B's type is accessible via
! type(B) or B.__class__ (the latter notation is new for types; it
! is introduced in PEP 252). Let's say B's type is M (for
 Metatype). The class statement will create a new type, C. Since
 C will be a type object just like B, we view the creation of C as
 an instantiation of the metatype, M. The information that needs
! to be provided for the creation of C is: its name (in this example
! the string "C"); the list of base classes (a singleton tuple
! containing B); and the results of executing the class body, in the
! form of a dictionary (for example {"var1": 1, "method1": <function
! method1 at ...>, ...}).
 
! I propose to rig the class statement to make the following call:
 
 C = M("C", (B,), dict)
 
--- 535,557 ----
 
 Assume B is a type object. Since type objects are objects, and
! every object has a type, B has a type. Since B is itself a type,
! we also call its type its metatype. B's metatype is accessible
! via type(B) or B.__class__ (the latter notation is new for types;
! it is introduced in PEP 252). Let's say this metatype is M (for
 Metatype). The class statement will create a new type, C. Since
 C will be a type object just like B, we view the creation of C as
 an instantiation of the metatype, M. The information that needs
! to be provided for the creation of a subclass is:
 
! - its name (in this example the string "C");
 
+ - its bases (a singleton tuple containing B);
+ 
+ - the results of executing the class body, in the form of a
+ dictionary (for example {"var1": 1, "method1": <function
+ method1 at ...>, ...}).
+ 
+ The class statement will result in the following call:
+ 
 C = M("C", (B,), dict)
 
***************
*** 550,558 ****
 class body). In other words, the metatype (M) is called.
 
! Note that even though we currently require there to be exactly one
! base class, we still pass in a (singleton) sequence of base
! classes; this makes it possible to support multiple inheritance
! later (or for types with a different metaclass!) without changing
! this interface.
 
 In current Python, this is called the "Don Beaudry hook" after its
--- 559,565 ----
 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
! uniform with the multiple-inheritance case.
 
 In current Python, this is called the "Don Beaudry hook" after its
***************
*** 561,576 ****
 when no base class is specified), current Python calls
 PyClass_New(), the C level factory function for classes, directly.
! I propose to change this so that Python *always* determines a
! metaclass and calls it as given above. When one or more bases are
! given, the type of the first base is used as the metatype; 
! when no base class is given, a default metaclass is chosen. By
! setting the default metaclass to PyClass_Type, the metatype of
 "classic" classes, the classic behavior of the class statement is
! retained.
 
 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
! to call.
 
 Second, with multiple bases, not all bases need to have the same
--- 568,588 ----
 when no base class is specified), current Python calls
 PyClass_New(), the C level factory function for classes, directly.
! 
! Under the new system this is changed so that Python *always*
! determines a metatype and calls it as given above. When one or
! more bases are given, the type of the first base is used as the
! metatype; when no base is given, a default metatype is chosen. By
! setting the default metatype to PyClass_Type, the metatype of
 "classic" classes, the classic behavior of the class statement is
! retained. This default can be changed per module by setting the
! global variable __metaclass__.
 
 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
! 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.)
 
 Second, with multiple bases, not all bases need to have the same
***************
*** 583,612 ****
 This conflict resultion can be implemented in the metatypes
 itself: the class statement just calls the metatype of the first
! base, and this metatype's constructor looks for the most derived
! metatype. If that is itself, it proceeds; otherwise, it calls
! that metatype's constructor. (Ultimate flexibility: another
! metatype might choose to require that all bases have the same
! metatype, or that there's only one base class, or whatever.)
! 
! (Theoretically, it might be possible to automatically derive a new
! metatype that is a subtype of all given metatypes; but since it is
! questionable how conflicting method definitions of the various
! metatypes should be merged, I don't think this is useful or
! feasible. Should the need arise, the user can derive such a
! metatype and specify it using the __metaclass__ variable. It is
! also possible to have a new metatype that does this.)
! 
! HIRO
 
 Note that calling M requires that M itself has a type: the
! meta-metatype. In the current implementation, I have introduced a
! new type object for this purpose, named turtle because of my
! fondness of the phrase "turtles all the way down". However I now
! believe that it would be better if M were its own metatype, just
! like before. This can be accomplished by making M's tp_call slot
! slightly more flexible.
 
! In any case, the work for creating C is done by M's tp_construct
! 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
--- 595,628 ----
 This conflict resultion can be implemented in the metatypes
 itself: 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
! constructor. (Ultimate flexibility: another metatype might choose
! to require that all bases have the same metatype, or that there's
! only one base class, or whatever.)
! 
! (In [1], a new metaclass is automatically derived that is a
! subclass of all given metaclasses. But since it is questionable
! in Python how conflicting method definitions of the various
! metaclasses should be merged, I don't think this is feasible.
! Should the need arise, the user can derive such a metaclass
! manually and specify it using the __metaclass__ variable. It is
! also possible to have a new metaclass that does this.)
 
 Note that calling M requires that M itself has a type: the
! meta-metatype. And the meta-metatype has a type, the
! meta-meta-metatype. And so on. This is normally cut short at
! some level by making a metatype be its own metatype. This is
! indeed what happens in Python: the ob_type reference in
! PyType_Type is set to &PyType_Type. In the absence of third party
! metatypes, PyType_Type is the only metatype in the Python
! interpreter.
! 
! (In a previous version of this PEP, there was one additional
! meta-level, and there was a meta-metatype called "turtle". This
! 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
***************
*** 621,640 ****
 
 
! Implementation
 
! A prototype implementation of this PEP 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/spam.c.
 
! Note: the code in this branch is for PEP 252, PEP 253, and
! pep-254.
 
 
 References
 
--- 637,674 ----
 
 
! XXX To be done
 
! Additional topics to be discussed in this PEP:
 
! - class methods and static methods
 
+ - mapping between type object slots (tp_foo) and special methods
+ (__foo__)
 
+ - built-in names for built-in types (object, int, str, list etc.)
+ 
+ - multiple inheritance restrictions
+ 
+ - __slots__
+ 
+ - the HEAPTYPE and DYNAMICTYPE flag bits
+ 
+ - API docs for all the new functions
+ 
+ 
+ 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.
+ 
+ 
 References
 
***************
*** 647,697 ****
 
 This document has been placed in the public domain.
- 
- 
- Junk text (to be reused somewhere above)
- 
- The deallocation mechanism chosen should match the allocation
- mechanism: an allocation policy should prescribe both the
- allocation and deallocation mechanism. And again, planning ahead
- for subtyping would be nice. But the available mechanisms are
- different. The deallocation function has always been part of the
- type structure, as tp_dealloc, which combines the
- "uninitialization" with deallocation. This was good enough for
- the traditional situation, where it matched the combined
- allocation and initialization of the creation function. But now
- imagine a type whose creation function uses a special free list
- for allocation. It's deallocation function puts the object's
- memory back on the same free list. But when allocation and
- creation are separate, the object may have been allocated from the
- regular heap, and it would be wrong (in some cases disastrous) if
- it were placed on the free list by the deallocation function.
- 
- A solution would be for the tp_construct function to somehow mark
- whether the object was allocated from the special free list, so
- that the tp_dealloc function can choose the right deallocation
- method (assuming that the only two alternatives are a special free
- list or the regular heap). A variant that doesn't require space
- for an allocation flag bit would be to have two type objects,
- identical in the contents of all their slots except for their
- deallocation slot. But this requires that all type-checking code
- (like PyDict_Check()) recognizes both types. We'll come back to
- this solution in the context of subtyping. Another alternative is
- to require the metatype's tp_call to leave the allocation to the
- tp_construct method, by passing in a NULL pointer. But this
- doesn't work once we allow subtyping.
- 
- Eventually, when we add any form of subtyping, we'll have to
- separate deallocation from uninitialization. The way to do this
- is to add a separate slot to the type object that does the
- uninitialization without the deallocation. Fortunately, there is
- already such a slot: tp_clear, currently used by the garbage
- collection subsystem. A simple rule makes this slot reusable as
- an uninitialization: for types that support separate allocation
- and initialization, tp_clear must be defined (even if the object
- doesn't support garbage collection) and it must DECREF all
- contained objects and FREE all other memory areas the object owns.
- It must also be reentrant: it must be possible to clear an already
- cleared object. The easiest way to do this is to replace all
- pointers DECREFed or FREEd with NULL pointers.
 
 
--- 681,684 ----

AltStyle によって変換されたページ (->オリジナル) /