Author: Armin Rigo <ar...@tunes.org> Branch: py3k-kwonly-builtin Changeset: r86334:2c59ae270f5a Date: 2016-08-20 08:44 +0200 http://bitbucket.org/pypy/pypy/changeset/2c59ae270f5a/
Log: Backed out changeset b130c20feba7 Not so easy: it wouldn't support ``f.__kwdefaults__['a']=5`` or logic like ``f.__kwdefaults__=d={}; d['a']=5``. diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -153,7 +153,7 @@ @jit.unroll_safe def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None, - kw_defs_w=None, blindargs=0): + w_kw_defs=None, blindargs=0): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. """ @@ -281,18 +281,19 @@ else: missing_positional.append(signature.argnames[i]) - # finally, fill kwonly arguments with kw_defs_w (if needed) - for i in range(co_kwonlyargcount): - j = co_argcount + i - if scope_w[j] is not None: + # finally, fill kwonly arguments with w_kw_defs (if needed) + for i in range(co_argcount, co_argcount + co_kwonlyargcount): + if scope_w[i] is not None: continue - try: - w_def = signature.get_kwonly_default(i, kw_defs_w) - except KeyError: - name = signature.kwonlyargnames[i] + name = signature.kwonlyargnames[i - co_argcount] + if w_kw_defs is None: missing_kwonly.append(name) + continue + w_def = self.space.finditem_str(w_kw_defs, name) + if w_def is not None: + scope_w[i] = w_def else: - scope_w[j] = w_def + missing_kwonly.append(name) if missing_positional: raise ArgErrMissing(missing_positional, True) @@ -302,7 +303,7 @@ def parse_into_scope(self, w_firstarg, scope_w, fnname, signature, defaults_w=None, - kw_defs_w=None): + w_kw_defs=None): """Parse args and kwargs to initialize a frame according to the signature of code object. Store the argumentvalues into scope_w. @@ -311,30 +312,30 @@ try: self._match_signature(w_firstarg, scope_w, signature, defaults_w, - kw_defs_w, 0) + w_kw_defs, 0) except ArgErr as e: raise oefmt(self.space.w_TypeError, "%s() %8", fnname, e.getmsg()) return signature.scope_length() - def _parse(self, w_firstarg, signature, defaults_w, kw_defs_w, blindargs=0): + def _parse(self, w_firstarg, signature, defaults_w, w_kw_defs, blindargs=0): """Parse args and kwargs according to the signature of a code object, or raise an ArgErr in case of failure. """ scopelen = signature.scope_length() scope_w = [None] * scopelen self._match_signature(w_firstarg, scope_w, signature, defaults_w, - kw_defs_w, blindargs) + w_kw_defs, blindargs) return scope_w def parse_obj(self, w_firstarg, - fnname, signature, defaults_w=None, kw_defs_w=None, + fnname, signature, defaults_w=None, w_kw_defs=None, blindargs=0): """Parse args and kwargs to initialize a frame according to the signature of code object. """ try: - return self._parse(w_firstarg, signature, defaults_w, kw_defs_w, + return self._parse(w_firstarg, signature, defaults_w, w_kw_defs, blindargs) except ArgErr as e: raise oefmt(self.space.w_TypeError, "%s() %8", fnname, e.getmsg()) diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py --- a/pypy/interpreter/function.py +++ b/pypy/interpreter/function.py @@ -36,9 +36,9 @@ 'closure?[*]', 'defs_w?[*]', 'name?', - 'kw_defs_w?'] + 'w_kw_defs?'] - def __init__(self, space, code, w_globals=None, defs_w=[], kw_defs_w=None, + def __init__(self, space, code, w_globals=None, defs_w=[], w_kw_defs=None, closure=None, w_ann=None, forcename=None, qualname=None): self.space = space self.name = forcename or code.co_name @@ -48,7 +48,7 @@ self.w_func_globals = w_globals # the globals dictionary self.closure = closure # normally, list of Cell instances or None self.defs_w = defs_w - self.kw_defs_w = kw_defs_w + self.w_kw_defs = w_kw_defs self.w_func_dict = None # filled out below if needed self.w_module = None self.w_ann = w_ann @@ -373,35 +373,19 @@ self.defs_w = [] def fget_func_kwdefaults(self, space): - if self.kw_defs_w is None: + if self.w_kw_defs is None: return space.w_None - w_result = space.newdict(strdict=True) - for key, w_value in self.kw_defs_w.items(): - space.setitem_str(w_result, key, w_value) - return w_result - - @staticmethod - def add_kwdefaults(space, kw_defs_w, w_key, w_value): - key = space.unicode_w(w_key).encode('utf-8') - kw_defs_w[key] = w_value + return self.w_kw_defs def fset_func_kwdefaults(self, space, w_new): if space.is_w(w_new, space.w_None): - self.kw_defs_w = None + w_new = None elif not space.isinstance_w(w_new, space.w_dict): raise oefmt(space.w_TypeError, "__kwdefaults__ must be a dict") - else: - # must assign a new dictionary to 'kw_defs_w', never mutate - # the existing dictionary: this is because - # Signature.get_kwonly_default() is an elidable function. - new_w = {} - for w_key in space.unpackiterable(w_new): - w_value = space.getitem(w_new, w_key) - self.add_kwdefaults(space, new_w, w_key, w_value) - self.kw_defs_w = new_w + self.w_kw_defs = w_new def fdel_func_kwdefaults(self, space): - self.kw_defs_w = None + self.w_kw_defs = None def fget_func_doc(self, space): if self.w_doc is None: @@ -679,7 +663,7 @@ def __init__(self, func): assert isinstance(func, Function) Function.__init__(self, func.space, func.code, func.w_func_globals, - func.defs_w, func.kw_defs_w, func.closure, + func.defs_w, func.w_kw_defs, func.closure, None, func.name) self.w_doc = func.w_doc self.w_func_dict = func.w_func_dict diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -723,7 +723,7 @@ space = func.space activation = self.activation scope_w = args.parse_obj(w_obj, func.name, self.sig, - func.defs_w, func.kw_defs_w, self.minargs) + func.defs_w, func.w_kw_defs, self.minargs) try: w_result = activation._run(space, scope_w) except DescrMismatch: diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py --- a/pypy/interpreter/pycode.py +++ b/pypy/interpreter/pycode.py @@ -262,7 +262,7 @@ fresh_frame = jit.hint(frame, access_directly=True, fresh_virtualizable=True) args.parse_into_scope(None, fresh_frame.locals_cells_stack_w, func.name, - sig, func.defs_w, func.kw_defs_w) + sig, func.defs_w, func.w_kw_defs) fresh_frame.init_cells() return frame.run() @@ -274,7 +274,7 @@ fresh_frame = jit.hint(frame, access_directly=True, fresh_virtualizable=True) args.parse_into_scope(w_obj, fresh_frame.locals_cells_stack_w, func.name, - sig, func.defs_w, func.kw_defs_w) + sig, func.defs_w, func.w_kw_defs) fresh_frame.init_cells() return frame.run() diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -1235,16 +1235,15 @@ for i in range(len(names_w) - 1, -1, -1): space.setitem(w_ann, names_w[i], self.popvalue()) defaultarguments = self.popvalues(posdefaults) - kw_defs_w = None + w_kw_defs = None if kwdefaults: - kw_defs_w = {} - for i in range(kwdefaults): - w_defvalue = self.popvalue() - w_defname = self.popvalue() - function.Function.add_kwdefaults(space, kw_defs_w, - w_defname, w_defvalue) + w_kw_defs = space.newdict(strdict=True) + for i in range(kwdefaults - 1, -1, -1): + w_name = self.popvalue() + w_def = self.popvalue() + space.setitem(w_kw_defs, w_def, w_name) fn = function.Function(space, codeobj, self.get_w_globals(), defaultarguments, - kw_defs_w, freevars, w_ann, qualname=qualname) + w_kw_defs, freevars, w_ann, qualname=qualname) self.pushvalue(space.wrap(fn)) def MAKE_FUNCTION(self, oparg, next_instr): diff --git a/pypy/interpreter/signature.py b/pypy/interpreter/signature.py --- a/pypy/interpreter/signature.py +++ b/pypy/interpreter/signature.py @@ -25,13 +25,6 @@ pass return -1 - @jit.elidable - def get_kwonly_default(self, i, kw_defs_w): - if kw_defs_w is None: - raise KeyError - name = self.kwonlyargnames[i] - return kw_defs_w[name] - def num_argnames(self): return len(self.argnames) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit