[Python-checkins] peps: PEP 510

victor.stinner python-checkins at python.org
Mon Jan 11 18:16:25 EST 2016


https://hg.python.org/peps/rev/849525efbf8a
changeset:   6167:849525efbf8a
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Mon Jan 11 23:55:32 2016 +0100
summary:
  PEP 510

* make new methods private
* make Guard type private and rename it to PyFuncGuard
* elaborate potential changes on the Python semantics
* explain than other implementations of Python are free to not implement new
  methods, or implement them as no-op

files:
  pep-0510.txt |  86 ++++++++++++++++++++++++++++-----------
  1 files changed, 62 insertions(+), 24 deletions(-)


diff --git a/pep-0510.txt b/pep-0510.txt
--- a/pep-0510.txt
+++ b/pep-0510.txt
@@ -13,8 +13,8 @@
 Abstract
 ========
 
-Add an API to add specialized functions with guards to functions, to
-support static optimizers respecting the Python semantics.
+Add a private API to CPython to add specialized functions with guards to
+functions, to support static optimizers respecting the Python semantics.
 
 
 Rationale
@@ -29,10 +29,15 @@
 semantics requires to detect when "something changes", we will call these
 checks "guards".
 
-This PEP proposes to add a ``specialize()`` method to functions to add a
-specialized functions with guards. When the function is called, the
-specialized function is used if nothing changed, otherwise use the
-original bytecode.
+This PEP proposes to add an API to add specialized functions with guards
+to a function. When the function is called, the specialized function is
+used if nothing changed, otherwise use the original bytecode.
+
+Even if guards help to respect most parts of the Python semantics, it's
+really hard to optimize Python without making subtle changes on the
+exact behaviour. CPython has a long history and many applications rely
+on implementation details. A compromise must be found between
+"everything is mutable" and performance.
 
 Writing an optimizer is out of the scope of this PEP.
 
@@ -112,18 +117,18 @@
     def fast_func():
         return "A"
 
-    func.specialize(fast_func.__code__, [myoptimizer.GuardBuiltins("chr")])
+    func._specialize(fast_func.__code__, [myoptimizer.GuardBuiltins("chr")])
     del fast_func
 
     print("func(): %s" % func())
-    print("#specialized: %s" % len(func.get_specialized()))
+    print("#specialized: %s" % len(func._get_specialized()))
     print()
 
     import builtins
     builtins.chr = lambda obj: "mock"
 
     print("func(): %s" % func())
-    print("#specialized: %s" % len(func.get_specialized()))
+    print("#specialized: %s" % len(func._get_specialized()))
 
 Output::
 
@@ -157,10 +162,10 @@
     def func(arg):
         return chr(arg)
 
-    func.specialize(chr, [myoptimizer.GuardBuiltins("chr")])
+    func._specialize(chr, [myoptimizer.GuardBuiltins("chr")])
 
     print("func(65): %s" % func(65))
-    print("#specialized: %s" % len(func.get_specialized()))
+    print("#specialized: %s" % len(func._get_specialized()))
     print()
 
     import builtins
@@ -222,24 +227,43 @@
 Changes
 =======
 
-* Add two new methods to functions:
+* Add two new private methods to functions:
 
-  - ``specialize(code, guards: list)``: add specialized
+  * ``_specialize(code, guards: list)``: add specialized
     function with guard. `code` is a code object (ex:
-    ``func2.__code__``) or any callable object (ex: ``len``).
-    The specialization can be ignored if a guard already fails.
-  - ``get_specialized()``: get the list of specialized functions with
-    guards
+    ``func2.__code__``) or any callable object (ex: the builtin
+    ``len()`` function).  The specialization can be ignored if a guard
+    already fails or for other reasons (ex: the implementation of Python
+    does not implement this feature). Return ``False`` is the
+    specialized function was ignored, return ``True`` otherwise.
 
-* Base ``Guard`` type which can be used as parent type to implement
-  guards. It requires to implement a ``check()`` function, with an
-  optional ``first_check()`` function. API:
+  * ``_get_specialized()``: get the list of specialized functions with
+    guards. Return a list of ``(func, guards)`` tuples where func is the
+    specialized function and guards is a list of guards. Return an empty
+    list if the function was never specialized.
 
-  * ``int first_check(PyObject *guard, PyObject *func)``: return 0 on
-    success, -1 if the guard will always fail
+* Add a private ``PyFuncGuard`` Python type. It requires to implement a
+  C ``check()`` function, with an optional C ``init()`` function. API:
+
+  * ``int init(PyObject *guard, PyObject *func)``: initialize a guard,
+    *func* is the function to which the specialized function will be
+    attached. Result:
+
+    * return ``1`` on success
+    * return ``0`` if the guard will always fail (the specialization must be
+      ignored)
+    * raise an exception and return ``-1`` on error
+
   * ``int check(PyObject *guard, PyObject **stack, int na, int nk)``:
-    return 1 on success, 0 if the guard failed temporarely, -1 if the
-    guard will always fail
+    check the guard. Result:
+
+    * return 2 on success
+    * return 1 if the guard failed temporarely
+    * return 0 if the guard will always fail
+    * raise an exception and return -1 on error
+
+  * A guard can be called in Python with parameters, it returns the
+    result of the guard check.
 
 Microbenchmark on ``python3.6 -m timeit -s 'def f(): pass' 'f()'`` (best
 of 3 runs):
@@ -263,6 +287,20 @@
 when a module is loaded.
 
 
+Other implementations of Python
+===============================
+
+This PEP is designed to be implemented in C for CPython.
+
+Other implementations of Python are free to not implement added private
+function methods.
+
+Or they can implement a ``_specialize()`` method which always ignores
+the specialized function (in short, do nothing and always return
+``False``) and a ``_get_specialized()`` method which always returns an
+empty list.
+
+
 Discussion
 ==========
 

-- 
Repository URL: https://hg.python.org/peps


More information about the Python-checkins mailing list