[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