[Python-checkins] r53744 - peps/trunk/pep-0000.txt peps/trunk/pep-0363.txt

david.goodger python-checkins at python.org
Mon Feb 12 00:50:58 CET 2007


Author: david.goodger
Date: Mon Feb 12 00:50:57 2007
New Revision: 53744

Added:
   peps/trunk/pep-0363.txt   (contents, props changed)
Modified:
   peps/trunk/pep-0000.txt
Log:
added PEP 363 "Syntax For Dynamic Attribute Access" by Ben North

Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Mon Feb 12 00:50:57 2007
@@ -98,6 +98,7 @@
  S   355  Path - Object oriented filesystem paths      Lindqvist
  S   358  The "bytes" Object                           Schemenauer
  S   362  Function Signature Object                    Cannon, Seo
+ S   363  Syntax For Dynamic Attribute Access          North
  S   754  IEEE 754 Floating Point Special Values       Warnes
  S  3101  Advanced String Formatting                   Talin
  S  3102  Keyword-Only Arguments                       Talin
@@ -434,6 +435,7 @@
  I   360  Externally Maintained Packages               Cannon
  I   361  Python 2.6 Release Schedule                  Norwitz, et al
  S   362  Function Signature Object                    Cannon, Seo
+ S   363  Syntax For Dynamic Attribute Access          North
  SR  666  Reject Foolish Indentation                   Creighton
  S   754  IEEE 754 Floating Point Special Values       Warnes
  P  3000  Python 3000                                  GvR
@@ -530,6 +532,7 @@
     Meyer, Mike              mwm at mired.org
     Montanaro, Skip          skip at pobox.com
     Moore, Paul              gustav at morpheus.demon.co.uk
+    North, Ben               ben at redfrontdoor.org
     Norwitz, Neal            nnorwitz at gmail.com
     Oliphant, Travis         oliphant at ee.byu.edu
     Pedroni, Samuele         pedronis at python.org

Added: peps/trunk/pep-0363.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-0363.txt	Mon Feb 12 00:50:57 2007
@@ -0,0 +1,272 @@
+PEP: 363
+Title: Syntax For Dynamic Attribute Access
+Version: $Revision$
+Last-Modified: $Date$
+Author: Ben North <ben at redfrontdoor.org>
+Status: Draft
+Type: Standards Track
+Content-Type: text/plain
+Created: 29-Jan-2007
+Post-History:
+
+
+Abstract
+
+    Dynamic attribute access is currently possible using the "getattr"
+    and "setattr" builtins.  The present PEP suggests a new syntax to
+    make such access easier, allowing the coder for example to write
+
+        x.('foo_%d' % n) += 1
+
+        z = y.('foo_%d' % n).('bar_%s' % s)
+
+    instead of
+
+        attr_name = 'foo_%d' % n
+        setattr(x, attr_name, getattr(x, attr_name) + 1)
+
+        z = getattr(getattr(y, 'foo_%d' % n), 'bar_%s' % s)
+
+
+Note
+
+    I wrote this patch mostly to advance my own understanding of and
+    experiment with the python language, but I've written it up in the
+    style of a PEP in case it might be a useful idea.
+
+
+Rationale
+
+    Dictionary access and indexing both have a friendly invocation
+    syntax: instead of x.__getitem__(12) the coder can write x[12].
+    This also allows the use of subscripted elements in an augmented
+    assignment, as in "x[12] += 1".  The present proposal brings this
+    ease-of-use to dynamic attribute access too.
+
+    Attribute access is currently possible in two ways:
+
+    * When the attribute name is known at code-writing time, the
+      ".NAME" trailer can be used, as in
+
+          x.foo = 42
+          y.bar += 100
+
+    * When the attribute name is computed dynamically at run-time, the
+      "getattr" and "setattr" builtins must be used:
+
+          x = getattr(y, 'foo_%d' % n)
+          setattr(z, 'bar_%s' % s, 99)
+
+      The "getattr" builtin also allows the coder to specify a default
+      value to be returned in the event that the object does not have
+      an attribute of the given name:
+
+          x = getattr(y, 'foo_%d' % n, 0)
+
+    This PEP describes a new syntax for dynamic attribute access ---
+    "x.(expr)" --- with examples given in the Abstract above.  The new
+    syntax also allows the provision of a default value in the "get"
+    case, as in:
+
+        x = y.('foo_%d' % n, None)
+
+    This 2-argument form of dynamic attribute access is not permitted as
+    the target of an (augmented or normal) assignment.  Also, this part
+    of the new syntax was not as well received [6] in initial
+    discussions on python-ideas, and I agree that it does not fit so
+    cleanly.  I'm happy to prepare a revised PEP/patch without the
+    2-argument form if the consensus is that this would be preferred.
+
+    Finally, the new syntax can be used with the "del" statement, as in
+
+        del x.(attr_name)
+
+
+Impact On Existing Code
+
+    The proposed new syntax is not currently valid, so no existing
+    well-formed programs have their meaning altered by this proposal.
+
+    Across all "*.py" files in the 2.5 distribution, there are around
+    600 uses of "getattr", "setattr" or "delattr".  They break down as
+    follows (figures have some room for error because they were
+    arrived at by partially-manual inspection):
+
+        c.300 uses of plain "getattr(x, attr_name)", which could be
+              replaced with the new syntax;
+
+        c.150 uses of the 3-argument form, i.e., with the default
+              value; these could be replaced with the 2-argument form
+              of the new syntax (the cases break down into c.125 cases
+              where the attribute name is a literal string, and c.25
+              where it's only known at run-time);
+
+        c.5   uses of the 2-argument form with a literal string
+              attribute name, which I think could be replaced with the
+              standard "x.attribute" syntax;
+
+        c.120 uses of setattr, of which 15 use getattr to find the
+              new value; all could be replaced with the new syntax,
+              the 15 where getattr is also involved would show a
+              particular increase in clarity;
+
+        c.5   uses which would have to stay as "getattr" because they
+              are calls of a variable named "getattr" whose default
+              value is the builtin "getattr";
+
+        c.5   uses of the 2-argument form, inside a try/except block
+              which catches AttributeError and uses a default value
+              instead; these could use 2-argument form of the new
+              syntax;
+
+        c.10  uses of "delattr", which could use the new syntax.
+
+    As examples, the line
+
+        setattr(self, attr, change_root(self.root, getattr(self, attr)))
+
+    from Lib/distutils/command/install.py could be rewritten
+
+        self.(attr) = change_root(self.root, self.(attr))
+
+    and the line
+
+        setattr(self, method_name, getattr(self.metadata, method_name))
+
+    from Lib/distutils/dist.py could be rewritten
+
+        self.(method_name) = self.metadata.(method_name)
+
+
+Performance Impact
+
+    Initial pystone measurements are inconclusive, but suggest there may
+    be a performance penalty of around 1% in the pystones score with the
+    patched version.  One suggestion is that this is because the longer
+    main loop in ceval.c hurts the cache behaviour, but this has not
+    been confirmed.  (Maybe a tool like valgrind [2] could help here?)
+
+    On the other hand, measurements suggest a speed-up of around 40--45%
+    for dynamic attribute access.
+
+
+Discussion To Date
+
+    Initial posting of this PEP in draft form was to python-ideas on
+    20070209 [4], and the response was generally positive:
+
+        I've thought of the same syntax. I think you should submit this
+        to the PEP editor and argue on Python-dev for its inclusion in
+        Python 2.6 -- there's no benefit that I see of waiting until
+        3.0.  --- Guido van Rossum [5]
+
+        Wow!  I have to say this is a compelling idea.  The syntax is a
+        bit foreign looking, but [...] I feel like I could learn to like
+        it anyway. --- Greg Falcon [6]
+
+        I look forward to seeing this in Python 2.6.  --- Josiah
+        Carlson, further down the thread [8]
+
+    with Greg Falcon expressing the reservations about the 2-argument
+    form already noted above, and Josiah Carlson raising a query about
+    performance:
+
+        My only concern with your propsed change is your draft
+        implementation. [...]  Specifically, your changes [...] may
+        negatively affect general Python performance.  --- Josiah
+        Carlson [7]
+
+    Some initial measurements (see above) suggest the performance
+    penalty is small, and Josiah Carlson said of such cost that it
+    "isn't really substantial". [8]
+
+
+Questions To Be Resolved
+
+    * Whether to allow the 2-argument form for default arguments.
+
+    * Whether the performance impact is real; whether it is acceptable;
+      whether alternative implementations might improve this aspect.
+
+
+Alternative Syntax For The New Feature
+
+    Other syntaxes could be used, for example braces are currently
+    invalid in a "trailer", so could be used here, giving
+
+        x{'foo_%d' % n} += 1
+
+    My personal preference is for the
+
+        x.('foo_%d' % n) += 1
+
+    syntax though: the presence of the dot shows there is attribute
+    access going on; the parentheses have an analogous meaning to the
+    mathematical "work this out first" meaning.  This is also the
+    syntax used in the language Matlab [1] for dynamic "field" access
+    (where "field" is the Matlab term analogous to Python's
+    "attribute").
+
+    Discussions on python-ideas (see above) made no comment on the brace
+    alternative, and the .() notation was well-enough received, so the
+    brace alternative should be considered rejected, I think.
+
+
+Error Cases
+
+    Only strings are permitted as attribute names, so for instance the
+    following error is produced:
+
+      >>> x.(99) = 8
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+        TypeError: attribute name must be string, not 'int'
+
+    This is handled by the existing PyObject_GetAttr function.
+
+
+Draft Implementation
+
+    A draft implementation adds a new alternative to the "trailer"
+    clause in Grammar/Grammar; a new AST type, "DynamicAttribute" in
+    Python.asdl, with accompanying changes to symtable.c, ast.c, and
+    compile.c, and three new opcodes (load/store/del) with
+    accompanying changes to opcode.h and ceval.c.  The patch consists
+    of c.180 additional lines in the core code, and c.100 additional
+    lines of tests.  It is available as sourceforge patch #1657573 [3].
+
+
+References
+
+    [1] Using Dynamic Field Names :: Data Types (MATLAB Programming)
+        http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f2-41859.html
+
+    [2] Valgrind: "suite of tools for debugging and profiling Linux programs"
+        http://www.valgrind.org/
+
+    [3] Sourceforge patch #1657573
+        http://sourceforge.net/tracker/index.php?func=detail&aid=1657573&group_id=5470&atid=305470
+
+    [4] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html
+
+    [5] http://mail.python.org/pipermail/python-ideas/2007-February/000211.html
+
+    [6] http://mail.python.org/pipermail/python-ideas/2007-February/000212.html
+
+    [7] http://mail.python.org/pipermail/python-ideas/2007-February/000213.html
+
+    [8] http://mail.python.org/pipermail/python-ideas/2007-February/000227.html
+
+
+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:


More information about the Python-checkins mailing list