[Python-checkins] cpython: Issue #20381: Fix sanity checking on default arguments when c_default is

zach.ware python-checkins at python.org
Sat Jan 25 05:52:47 CET 2014


http://hg.python.org/cpython/rev/93afa651e074
changeset:   88680:93afa651e074
user:        Zachary Ware <zachary.ware at gmail.com>
date:        Fri Jan 24 22:52:30 2014 -0600
summary:
  Issue #20381: Fix sanity checking on default arguments when c_default is
also specified.

files:
  Misc/NEWS              |   5 +++++
  Tools/clinic/clinic.py |  14 +++++++++++---
  2 files changed, 16 insertions(+), 3 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -141,6 +141,11 @@
 
 Tools/Demos
 -----------
+
+- Issue #20381: Argument Clinic now sanity checks the default argument when
+  c_default is also specified, providing a nice failure message for
+  disallowed values.
+
 - Issue #20189: Argument Clinic now ensures that parser functions for
   __new__ are always of type newfunc, the type of the tp_new slot.
   Similarly, parser functions for __init__ are now always of type initproc,
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -3279,11 +3279,11 @@
                 fail("You can't specify py_default without specifying a default value!")
         else:
             default = default.strip()
+            bad = False
             ast_input = "x = {}".format(default)
             try:
                 module = ast.parse(ast_input)
 
-                bad = False
                 if 'c_default' not in kwargs:
                     # we can only represent very simple data values in C.
                     # detect whether default is okay, via a blacklist
@@ -3317,8 +3317,16 @@
                     bad = blacklist.bad
                 else:
                     # if they specify a c_default, we can be more lenient about the default value.
-                    # but at least ensure that we can turn it into text and reconstitute it correctly.
-                    bad = default != repr(eval(default))
+                    # but at least make an attempt at ensuring it's a valid expression.
+                    try:
+                        value = eval(default)
+                        if value == unspecified:
+                            fail("'unspecified' is not a legal default value!")
+                    except NameError:
+                        pass # probably a named constant
+                    except Exception as e:
+                        fail("Malformed expression given as default value\n"
+                             "{!r} caused {!r}".format(default, e))
                 if bad:
                     fail("Unsupported expression as default value: " + repr(default))
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list