[Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.17,1.18
Guido van Rossum
gvanrossum@users.sourceforge.net
Sat, 08 Sep 2001 05:42:50 -0700
Update of /cvsroot/python/python/nondist/peps
In directory usw-pr-cvs1:/tmp/cvs-serv868
Modified Files:
pep-0252.txt
Log Message:
Quick merge of Barry's feedback of four weeks ago. ;-(
Index: pep-0252.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** pep-0252.txt 2001/08/07 15:44:15 1.17
--- pep-0252.txt 2001/09/08 12:42:48 1.18
***************
*** 94,98 ****
attributes).
! Some caution must be exercised: some objects don't list theire
"intrinsic" attributes (like __dict__ and __doc__) in __members__,
while others do; sometimes attribute names occur both in
--- 94,98 ----
attributes).
! Some caution must be exercised: some objects don't list their
"intrinsic" attributes (like __dict__ and __doc__) in __members__,
while others do; sometimes attribute names occur both in
***************
*** 137,141 ****
"static" attributes may actually behave quite dynamically, and
because they have nothing to do with static class members in C++
! or Java.)
Examples of dynamic attributes are instance variables of class
--- 137,144 ----
"static" attributes may actually behave quite dynamically, and
because they have nothing to do with static class members in C++
! or Java. Barry suggests to use immutable and mutable instead, but
! those words already have precise and different meanings in
! slightly different contexts, so I think that would still be
! confusing.)
Examples of dynamic attributes are instance variables of class
***************
*** 207,211 ****
special case of an attribute descriptor.
! Becase a meta-object is also a regular object, the items in a
meta-object's __dict__ correspond to attributes of the
meta-object; however, some transformation may be applied, and
--- 210,214 ----
special case of an attribute descriptor.
! Because a meta-object is also a regular object, the items in a
meta-object's __dict__ correspond to attributes of the
meta-object; however, some transformation may be applied, and
***************
*** 224,232 ****
relationship between meta-objects defined by __bases__
attributes; in other words, the __bases__ attributes define an
! directed acyclic graph. (It is not necessarily a tree, since
! multiple classes can have the same base class.) The __dict__
! attributes of the meta-objects in the inheritance graph supply
! attribute descriptors for the regular object whose __class__ is
! at the top of the inheritance graph.
5. Precedence rules
--- 227,242 ----
relationship between meta-objects defined by __bases__
attributes; in other words, the __bases__ attributes define an
! directed acyclic graph, with arcs pointing from derived
! meta-objects to their base meta-objects. (It is not
! necessarily a tree, since multiple classes can have the same
! base class.) The __dict__ attributes of a meta-object in the
! inheritance graph supply attribute descriptors for the regular
! object whose __class__ attribute points to the root of the
! inheritance tree (which is not the same as the root of the
! inheritance hierarchy -- rather more the opposite, at the
! bottom given how inheritance trees are typically drawn).
! Descriptors are first searched in the dictionary of the root
! meta-object, then in its bases, according to a precedence rule
! (see the next paragraph).
5. Precedence rules
***************
*** 234,241 ****
When two meta-objects in the inheritance graph for a given
regular object both define an attribute descriptor with the
! same name, the left-to-right depth-first rule applies. (This
! is the classic Python attribute lookup rule. Note that PEP 253
! will propose to change the attribute lookup order, and if
! accepted, this PEP will follow suit.)
When a dynamic attribute (one defined in a regular object's
--- 244,253 ----
When two meta-objects in the inheritance graph for a given
regular object both define an attribute descriptor with the
! same name, the search order is up to the meta-object. This
! allows different meta-objects to define different search
! orders. In particular, classic classes use the old
! left-to-right depth-first rule, while new-style classes use a
! more advanced rule (see the section on method resolution order
! in PEP 253).
When a dynamic attribute (one defined in a regular object's
***************
*** 245,249 ****
is a descriptor that defines a __set__ method (see below);
otherwise (if there is no __set__ method) the dynamic attribute
! has precedence.
Rationale: we can't have a simple rule like "static overrides
--- 257,264 ----
is a descriptor that defines a __set__ method (see below);
otherwise (if there is no __set__ method) the dynamic attribute
! has precedence. In other words, for data attributes (those
! with a __set__ method), the static definition overrides the
! dynamic definition, but for other attributes, dynamic overrides
! static.
Rationale: we can't have a simple rule like "static overrides
***************
*** 326,350 ****
- __get__(): a function callable with one or two arguments that
! retrieves the attribute value from an object. With one
! argument, X, this either (for data attributes) retrieves the
! attribute value from X or (for method attributes) binds the
! attribute to X (returning some form of "bound" object that
! receives an implied first argument of X when called). With two
! arguments, X and T, T must be a meta-object that restricts the
! type of X. X must either be an instance of T (in which the
! effect is the same as when T is omitted), or None. When X is
! None, this should be a method descriptor, and the result is an
! *unbound* method restricted to objects whose type is (a
! descendent of) T. Such an unbound method is a descriptor
! itself. For methods, this is called a "binding" operation, even
! if X==None. Exactly what is returned by the binding operation
! depends on the semantics of the descriptor; for example, static
! methods and class methods (see below) ignore the instance and
! bind to the type instead.
- __set__(): a function of two arguments that sets the attribute
value on the object. If the attribute is read-only, this method
! raises a TypeError exception. (Not an AttributeError!)
! Example: C.ivar.set(x, y) ~~ x.ivar = y.
--- 341,363 ----
- __get__(): a function callable with one or two arguments that
! retrieves the attribute value from an object. This is also
! referred to as a "binding" operation, because it may return a
! "bound method" object in the case of method descriptors. The
! first argument, X, is the object from which the attribute must
! be retrieved or to which it must be bound. When X is None, the
! optional second argument, T, should be meta-object and the
! binding operation may return an *unbound* method restricted to
! instances of T. When both X and T are specified, X should be an
! instance of T. Exactly what is returned by the binding
! operation depends on the semantics of the descriptor; for
! example, static methods and class methods (see below) ignore the
! instance and bind to the type instead.
- __set__(): a function of two arguments that sets the attribute
value on the object. If the attribute is read-only, this method
! may raise a TypeError or AttributeError exception (both are
! allowed, because both are historically found for undefined or
! unsettable attributes). Example:
! C.ivar.set(x, y) ~~ x.ivar = y.
***************
*** 378,381 ****
--- 391,399 ----
'c.foo' and an unbound method object for 'C.foo'.
+ (XXX Barry suggests to use "sharedmethod" instead of
+ "staticmethod", because the word statis is being overloaded in so
+ many ways already. But I'm not sure if shared conveys the right
+ meaning.)
+
Class methods use a similar pattern to declare methods that
receive an implicit first argument that is the *class* for which
***************
*** 432,439 ****
as its first argument, not class E. This is to be expected, since
the call specifies the class C. But it stresses the difference
! between these class methods and methods defined in metaclasses
! (where an upcall to a metamethod would pass the target class as an
! explicit first argument). If you don't understand this, don't
! worry, you're not alone.
--- 450,462 ----
as its first argument, not class E. This is to be expected, since
the call specifies the class C. But it stresses the difference
! between these class methods and methods defined in metaclasses,
! where an upcall to a metamethod would pass the target class as an
! explicit first argument. (If you don't understand this, don't
! worry, you're not alone.) Note that calling cls.foo(y) would be a
! mistake -- it would cause infinite recursion. Also note that you
! can't specify an explicit 'cls' argument to a class method. If
! you want this (e.g. the __new__ method in PEP 253 requires this),
! use a static method with a class as its explicit first argument
! instead.
***************
*** 568,574 ****
nondata descriptors. The current implementation quite sensibly
classifies member and getset descriptors as data (even if they
! are read-only!) and member descriptors as nondata.
Non-descriptors (like function pointers or plain values) are
! also classified as non-data.
- This scheme has one drawback: in what I assume to be the most
--- 591,597 ----
nondata descriptors. The current implementation quite sensibly
classifies member and getset descriptors as data (even if they
! are read-only!) and method descriptors as nondata.
Non-descriptors (like function pointers or plain values) are
! also classified as non-data (!).
- This scheme has one drawback: in what I assume to be the most
***************
*** 605,609 ****
['append', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
! >>>
Under the new proposal, the __methods__ attribute no longer exists:
--- 628,632 ----
['append', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
! >>>
Under the new proposal, the __methods__ attribute no longer exists: