diff --git a/pep-0252.txt b/pep-0252.txt index 462c36099..e277ebe1c 100644 --- a/pep-0252.txt +++ b/pep-0252.txt @@ -24,6 +24,7 @@ Abstract describe a method, a typed field in the object structure, or a generalized attribute represented by getter and setter functions. + Introduction One of Python's oldest language warts is the difference between @@ -39,6 +40,7 @@ Introduction more like types, and subclassing from built-in types; these topics are not on the table for this PEP. + Introspection APIs Introspection concerns itself with finding out what attributes an @@ -115,6 +117,7 @@ Introspection APIs this is a C extension module, the source-scanning approach to docstring extraction isn't feasible in this case.) + Specification of the class-based introspection API Objects may have two kinds of attributes: static and dynamic. The @@ -273,8 +276,99 @@ Specification of the class-based introspection API currently instances support assignment to __class__ and __dict__, and classes support assignment to __bases__ and __dict__.) + Specification of the attribute descriptor API + Attribute descriptors have the following attributes. In the + examples, x is an object, C is x.__class__, x.meth() is a method, + and x.ivar is a data attribute or instance variable. + + - name: the original attribute name. Note that because of + aliasing and renaming, the attribute may be known under a + different name, but this is the name under which it was born. + Example: C.meth.name == 'meth'. + + - doc: the attribute's documentation string. + + - objclass: the class that declared this attribute. The + descriptor only applies to objects that are instances of this + class (this includes instances of its subclasses). Example: + C.meth.objclass is C. + + - kind: either "method" or "data". This distinguishes between + methods and data attributes. The primary operation on a method + attribute is to call it. The primary operations on a data + attribute are to get and to set it. Example: C.meth.kind == + 'method'; C.ivar.kind == 'data'. + + - default: for optional data attributes, this gives a default or + initial value. XXX Python has two kinds of semantics for + referencing "absent" attributes: this may raise an + AttributeError, or it may produce a default value stored + somewhere in the class. There could be a flag that + distinguishes between these two cases. Also, there could be a + flag that tells whether it's OK to delete an attribute (and what + happens then -- a default value takes its place, or it's truly + gone). + + - attrclass: for data attributes, this can be the class of the + attribute value, or None. If this is not None, the attribute + value is restricted to being an instance of this class (or of a + subclass thereof). If this is None, the attribute value is not + constrained. For method attributes, this should normally be + None (a class is not sufficient information to describe a method + signature). If and when optional static typing is added to + Python, this the meaning of this attribute may change to + describe the type of the attribute. + + - signature: for methods, an object that describes the signature + of the method. Signature objects will be described further + below. + + - readonly: Boolean indicating whether assignment to this + attribute is disallowed. This is usually true for methods. + Example: C.meth.readonly == 1; C.ivar.kind == 0. + + - get(): a function of one argument that retrieves the attribute + value from an object. Examples: C.ivar.get(x) ~~ x.ivar; + C.meth.get(x) ~~ x.meth. + + - set(): a function of two arguments that sets the attribute value + on the object. If readonly is set, this method raises a + TypeError exception. Example: C.ivar.set(x, y) ~~ x.ivar = y. + + - call(): for method descriptors, this is a function of at least + one argument that calls the method. The first argument is the + object whose method is called; the remaining arguments + (including keyword arguments) are passed on to the method. + Example: C.meth.call(x, 1, 2) ~~ x.meth(1, 2). + + - bind(): for method descriptiors, this is a function of one + argument that returns a "bound method object". This in turn can + be called exactly like the method should be called (in fact this + is what is returned for a bound method). This is the same as + get(). Example: C.meth.bind(x) ~~ x.meth. + + For convenience, __name__ and __doc__ are defined as aliases for + name and doc. Also for convenience, calling the descriptor can do + one of three things: + + - Calling a method descriptor is the same as calling its call() + method. Example: C.meth(x, 1, 2) ~~ x.meth(1, 2). + + - Calling a data descriptor with one argument is the same as + calling its get() method. Example: C.ivar(x) ~~ x.ivar. + + - Calling a data descriptor with two arguments is the same as + calling its set() method. Example: C.ivar(x, y) ~~ x.ivar = y. + + Note that this specification does not define how to create + specific attribute descriptors. This is up to the individual + attribute descriptor implementations, of which there may be many. + + +Specification of the signature object API + XXX Discussion