[pypy-commit] pypy py3k-kwonly-builtin: Backed out changeset b130c20feba7

arigo pypy.commits at gmail.com
Sat Aug 20 02:45:09 EDT 2016


Author: Armin Rigo <arigo at 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)
 


More information about the pypy-commit mailing list