From 7ef3df6097d776f65f5c05bbf925e36d41cda651 Mon Sep 17 00:00:00 2001 From: David Goodger Date: Tue, 1 May 2007 19:35:45 +0000 Subject: [PATCH] added PEP 3130, Access to Current Module/Class/Function, by Jim J. Jewett --- pep-0000.txt | 18 +++-- pep-3130.txt | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 8 deletions(-) create mode 100644 pep-3130.txt diff --git a/pep-0000.txt b/pep-0000.txt index 8e4bc5813..acbcd1fb3 100644 --- a/pep-0000.txt +++ b/pep-0000.txt @@ -78,7 +78,7 @@ Index by Category Accepted PEPs (accepted; may not be implemented yet) SA 358 The "bytes" Object Schemenauer, GvR - SA 3106 Revamping dict.keys(), .values() and .items() GvR + SA 3106 Revamping dict.keys(), .values() & .items() GvR SA 3109 Raising Exceptions in Python 3000 Winter SA 3110 Catching Exceptions in Python 3000 Winter SA 3111 Simple input built-in in Python 3000 Roberge @@ -128,6 +128,7 @@ Index by Category S 3127 Integer Literal Support and Syntax Maupin S 3128 BList: A Faster List-like Type Stutzbach S 3129 Class Decorators Winter + S 3130 Access to Current Module/Class/Function Jewett S 3141 A Type Hierarchy for Numbers Yasskin Finished PEPs (done, implemented in Subversion) @@ -193,7 +194,7 @@ Index by Category SF 3104 Access to Names in Outer Scopes Yee SF 3105 Make print a function Brandl SF 3107 Function Annotations Winter, Lownds - SF 3114 Renaming iterator.next() to iterator.__next__() Yee + SF 3114 Renaming iterator.next() to .__next__() Yee Empty PEPs (or containing only an abstract) @@ -234,7 +235,7 @@ Index by Category SW 274 Dict Comprehensions Warsaw SR 275 Switching on Multiple Values Lemburg SR 276 Simple Iterator for ints Althoff - SR 281 Loop Counter Iteration with range and xrange Hetland + SR 281 Loop Counter Iteration with range & xrange Hetland SR 284 Integer for-loops Eppstein, Ewing SW 288 Generators Attributes and Exceptions Hettinger SR 294 Type Names in the types Module Tirosh @@ -254,7 +255,7 @@ Index by Category SW 321 Date/Time Parsing and Formatting Kuchling SR 325 Resource-Release Support for Generators Pedroni SR 326 A Case for Top and Bottom Values Carlson, Reedy - SR 329 Treating Builtins as Constants in the Standard Library Hettinger + SR 329 Treating Builtins as Constants in the StdLib Hettinger SR 330 Python Bytecode Verification Pelletier SR 332 Byte vectors and String/Unicode Unification Montanaro SW 334 Simple Coroutines via SuspendIteration Evans @@ -377,7 +378,7 @@ Numerical Index SF 278 Universal Newline Support Jansen SF 279 The enumerate() built-in function Hettinger S 280 Optimizing access to globals GvR - SR 281 Loop Counter Iteration with range and xrange Hetland + SR 281 Loop Counter Iteration with range & xrange Hetland SF 282 A Logging System Sajip, Mick IF 283 Python 2.3 Release Schedule GvR SR 284 Integer for-loops Eppstein, Ewing @@ -424,7 +425,7 @@ Numerical Index SR 326 A Case for Top and Bottom Values Carlson, Reedy SF 327 Decimal Data Type Batista SF 328 Imports: Multi-Line and Absolute/Relative Aahz - SR 329 Treating Builtins as Constants in the Standard Library Hettinger + SR 329 Treating Builtins as Constants in the StdLib Hettinger SR 330 Python Bytecode Verification Pelletier S 331 Locale-Independent Float/String Conversions Reis SR 332 Byte vectors and String/Unicode Unification Montanaro @@ -474,7 +475,7 @@ Numerical Index SR 3103 A Switch/Case Statement GvR SF 3104 Access to Names in Outer Scopes Yee SF 3105 Make print a function Brandl - SA 3106 Revamping dict.keys(), .values() and .items() GvR + SA 3106 Revamping dict.keys(), .values() & .items() GvR SF 3107 Function Annotations Winter, Lownds S 3108 Standard Library Reorganization Cannon SA 3109 Raising Exceptions in Python 3000 Winter @@ -482,7 +483,7 @@ Numerical Index SA 3111 Simple input built-in in Python 3000 Roberge SA 3112 Bytes literals in Python 3000 Orendorff SA 3113 Removal of Tuple Parameter Unpacking Cannon - SF 3114 Renaming iterator.next() to iterator.__next__() Yee + SF 3114 Renaming iterator.next() to .__next__() Yee SA 3115 Metaclasses in Python 3000 Talin S 3116 New I/O Stutzbach, Verdone, GvR S 3117 Postfix Type Declarations Brandl @@ -498,6 +499,7 @@ Numerical Index S 3127 Integer Literal Support and Syntax Maupin S 3128 BList: A Faster List-like Type Stutzbach S 3129 Class Decorators Winter + S 3130 Access to Current Module/Class/Function Jewett S 3141 A Type Hierarchy for Numbers Yasskin diff --git a/pep-3130.txt b/pep-3130.txt new file mode 100644 index 000000000..7e02b6d42 --- /dev/null +++ b/pep-3130.txt @@ -0,0 +1,206 @@ +PEP: 3130 +Title: Access to Current Module/Class/Function +Version: $Revision$ +Last-Modified: $Date$ +Author: Jim J. Jewett +Status: Draft +Type: Standards Track +Content-Type: text/plain +Created: 22-Apr-2007 +Python-Version: 3.0 +Post-History: 22-Apr-2007 + + +Abstract + + It is common to need a reference to the current module, class, + or function, but there is currently no entirely correct way to + do this. This PEP proposes adding the keywords __module__, + __class__, and __function__. + + +Rationale for __module__ + + Many modules export various functions, classes, and other objects, + but will perform additional activities (such as running unit + tests) when run as a script. The current idiom is to test whether + the module's name has been set to magic value. + + if __name__ == "__main__": ... + + More complicated introspection requires a module to (attempt to) + import itself. If importing the expected name actually produces + a different module, there is no good workaround. + + # __import__ lets you use a variable, but... it gets more + # complicated if the module is in a package. + __import__(__name__) + + # So just go to sys modules... and hope that the module wasn't + # hidden/removed (perhaps for security), that __name__ wasn't + # changed, and definitely hope that no other module with the + # same name is now available. + class X(object): + pass + + import sys + mod = sys.modules[__name__] + mod = sys.modules[X.__class__.__module__] + + Proposal: Add a __module__ keyword which refers to the module + currently being defined (executed). (But see open issues.) + + # XXX sys.main is still changing as draft progresses. May + # really need sys.modules[sys.main] + if __module__ is sys.main: # assumes PEP (3122), Cannon + ... + + +Rationale for __class__ + + Class methods are passed the current instance; from this they can + determine self.__class__ (or cls, for class methods). + Unfortunately, this reference is to the object's actual class, + which may be a subclass of the defining class. The current + workaround is to repeat the name of the class, and assume that the + name will not be rebound. + + class C(B): + + def meth(self): + super(C, self).meth() # Hope C is never rebound. + + class D(C): + + def meth(self): + # ?!? issubclass(D,C), so it "works": + super(C, self).meth() + + Proposal: Add a __class__ keyword which refers to the class + currently being defined (executed). (But see open issues.) + + class C(B): + def meth(self): + super(__class__, self).meth() + + Note that super calls may be further simplified by the "New Super" + PEP (Spealman). The __class__ (or __this_class__) attribute came + up in attempts to simplify the explanation and/or implementation + of that PEP, but was separated out as an independent decision. + + Note that __class__ (or __this_class__) is not quite the same as + the __thisclass__ property on bound super objects. The existing + super.__thisclass__ property refers to the class from which the + Method Resolution Order search begins. In the above class D, it + would refer to (the current reference of name) C. + + +Rationale for __function__ + + Functions (including methods) often want access to themselves, + usually for a private storage location or true recursion. While + there are several workarounds, all have their drawbacks. + + def counter(_total=[0]): + # _total shouldn't really appear in the + # signature at all; the list wrapping and + # [0] unwrapping obscure the code + _total[0] += 1 + return _total[0] + + @annotate(total=0) + def counter(): + # Assume name counter is never rebound: + counter.total += 1 + return counter.total + + # class exists only to provide storage: + class _wrap(object): + + __total = 0 + + def f(self): + self.__total += 1 + return self.__total + + # set module attribute to a bound method: + accum = _wrap().f + + # This function calls "factorial", which should be itself -- + # but the same programming styles that use heavy recursion + # often have a greater willingness to rebind function names. + def factorial(n): + return (n * factorial(n-1) if n else 1) + + Proposal: Add a __function__ keyword which refers to the function + (or method) currently being defined (executed). (But see open + issues.) + + @annotate(total=0) + def counter(): + # Always refers to this function obj: + __function__.total += 1 + return __function__.total + + def factorial(n): + return (n * __function__(n-1) if n else 1) + + +Backwards Compatibility + + While a user could be using these names already, double-underscore + names ( __anything__ ) are explicitly reserved to the interpreter. + It is therefore acceptable to introduce special meaning to these + names within a single feature release. + + +Implementation + + Ideally, these names would be keywords treated specially by the + bytecode compiler. + + Guido has suggested [1] using a cell variable filled in by the + metaclass. + + Michele Simionato has provided a prototype using bytecode hacks + [2]. This does not require any new bytecode operators; it just + modifies the which specific sequence of existing operators gets + run. + + +Open Issues + + - Are __module__, __class__, and __function__ the right names? In + particular, should the names include the word "this", either as + __this_module__, __this_class__, and __this_function__, (format + discussed on the python-3000 and python-ideas lists) or as + __thismodule__, __thisclass__, and __thisfunction__ (inspired + by, but conflicting with, current usage of super.__thisclass__). + + - Are all three keywords needed, or should this enhancement be + limited to a subset of the objects? Should methods be treated + separately from other functions? + + +References + + [1] Fixing super anyone? Guido van Rossum + http://mail.python.org/pipermail/python-3000/2007-April/006671.html + + [2] Descriptor/Decorator challenge, Michele Simionato + http://groups.google.com/group/comp.lang.python/browse_frm/thread/a6010c7494871bb1/62a2da68961caeb6?lnk=gst&q=simionato+challenge&rnum=1&hl=en#62a2da68961caeb6 + + +Copyright + + This document has been placed in the public domain. + + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +sentence-end-double-space: t +fill-column: 70 +coding: utf-8 +End: