Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r90052:c4cfe1d12253
Date: 2017-02-11 18:22 +0100
http://bitbucket.org/pypy/pypy/changeset/c4cfe1d12253/

Log:    Try to expose in a new, pypy-only attribute '__defaults_count__' the
        length of the internal '__defaults__', which might be hidden on some
        built-in functions because it would contain interp-level Nones.

diff --git a/lib-python/3/inspect.py b/lib-python/3/inspect.py
--- a/lib-python/3/inspect.py
+++ b/lib-python/3/inspect.py
@@ -2085,6 +2085,16 @@
     return _signature_fromstr(cls, func, s, skip_bound_arg)
 
 
+class _NoValue:
+    """Class of a marker object for PyPy only, used as the defaults for
+    built-in functions when there is really no Python object that could
+    be used."""
+    __slots__ = ()
+    def __repr__(self):
+        return '<no value>'
+_no_value = _NoValue()
+
+
 def _signature_from_function(cls, func):
     """Private helper: constructs Signature for the given python function."""
 
@@ -2113,7 +2123,10 @@
     if defaults:
         pos_default_count = len(defaults)
     else:
-        pos_default_count = 0
+        # PyPy extension, for built-in functions that take optional
+        # arguments but without any Python object to use as default.
+        pos_default_count = getattr(func, '__defaults_count__', 0)
+        defaults = [_no_value] * pos_default_count
 
     parameters = []
 
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -367,6 +367,9 @@
             return space.w_None
         return space.newtuple(values_w)
 
+    def fget_defaults_count(self, space):
+        return space.newint(len(self.defs_w))
+
     def fset_func_defaults(self, space, w_defaults):
         if space.is_w(w_defaults, space.w_None):
             self.defs_w = []
diff --git a/pypy/interpreter/test/test_function.py 
b/pypy/interpreter/test/test_function.py
--- a/pypy/interpreter/test/test_function.py
+++ b/pypy/interpreter/test/test_function.py
@@ -816,3 +816,5 @@
         w_g = space.wrap(app_g)
         w_defs = space.getattr(w_g, space.wrap("__defaults__"))
         assert space.is_w(w_defs, space.w_None)
+        w_count = space.getattr(w_g, space.wrap("__defaults_count__"))
+        assert space.unwrap(w_count) == 1
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -701,6 +701,7 @@
     __qualname__ = getset_func_qualname,
     __dict__ = getset_func_dict,
     __defaults__ = getset_func_defaults,
+    __defaults_count__ = GetSetProperty(Function.fget_defaults_count),
     __kwdefaults__ = getset_func_kwdefaults,
     __annotations__ = getset_func_annotations,
     __globals__ = interp_attrproperty_w('w_func_globals', cls=Function),
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to