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