Author: Ronan Lamy <[email protected]>
Branch: py3.6-asyncgen
Changeset: r97713:647cc06b34f4
Date: 2019-10-02 20:51 +0100
http://bitbucket.org/pypy/pypy/changeset/647cc06b34f4/
Log: Make asyncgen_hooks thread-local
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -23,8 +23,9 @@
# XXX [fijal] but they're not. is_being_profiled is guarded a bit all
# over the place as well as w_tracefunc
- _immutable_fields_ = ['profilefunc?', 'w_tracefunc?',
- 'w_coroutine_wrapper_fn?']
+ _immutable_fields_ = [
+ 'profilefunc?', 'w_tracefunc?', 'w_coroutine_wrapper_fn?',
+ 'w_asyncgen_firstiter_fn?', 'w_asyncgen_finalizer_fn?']
def __init__(self, space):
self.space = space
@@ -41,6 +42,8 @@
self.thread_disappeared = False # might be set to True after
os.fork()
self.w_coroutine_wrapper_fn = None
self.in_coroutine_wrapper = False
+ self.w_asyncgen_firstiter_fn = None
+ self.w_asyncgen_finalizer_fn = None
@staticmethod
def _mark_thread_disappeared(space):
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -594,15 +594,12 @@
if self.hooks_inited:
return
self.hooks_inited = True
-
- self.w_finalizer = self.space.appexec([], '''():
- import sys
- hooks = sys.get_asyncgen_hooks()
- return hooks.finalizer''')
+ ec = self.space.getexecutioncontext()
+ self.w_finalizer = ec.w_asyncgen_firstiter_fn
def _finalize_(self):
if self.frame is not None and self.frame.lastblock is not None:
- if self.w_finalizer is not self.space.w_None:
+ if self.w_finalizer is not None:
# XXX: this is a hack to resurrect the weakref that was cleared
# before running _finalize_()
if self.space.config.translation.rweakref:
diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py
--- a/pypy/module/sys/app.py
+++ b/pypy/module/sys/app.py
@@ -75,7 +75,7 @@
If it is another kind of object, it will be printed and the system
exit status will be one (i.e., failure)."""
# note that we cannot simply use SystemExit(exitcode) here.
- # in the default branch, we use "raise SystemExit, exitcode",
+ # in the default branch, we use "raise SystemExit, exitcode",
# which leads to an extra de-tupelizing
# in normalize_exception, which is exactly like CPython's.
if isinstance(exitcode, tuple):
@@ -109,7 +109,6 @@
# This is tested in test_app_main.py
class sysflags(metaclass=structseqtype):
-
name = "sys.flags"
debug = structseqfield(0)
@@ -130,29 +129,6 @@
null__xoptions = {}
-class asyncgen_hooks(metaclass=structseqtype):
- name = "asyncgen_hooks"
-
- firstiter = structseqfield(0)
- finalizer = structseqfield(1)
-
-# FIXME: make this thread-local
-_current_asyncgen_hooks = asyncgen_hooks((None, None))
-
-def get_asyncgen_hooks():
- return _current_asyncgen_hooks
-
-_default_arg = object()
-
-def set_asyncgen_hooks(firstiter=_default_arg, finalizer=_default_arg):
- global _current_asyncgen_hooks
- if firstiter is _default_arg:
- firstiter = _current_asyncgen_hooks.firstiter
- if finalizer is _default_arg:
- finalizer = _current_asyncgen_hooks.finalizer
- _current_asyncgen_hooks = asyncgen_hooks((firstiter, finalizer))
-
-
implementation = SimpleNamespace(
name='pypy',
version=sys.version_info,
diff --git a/pypy/module/sys/moduledef.py b/pypy/module/sys/moduledef.py
--- a/pypy/module/sys/moduledef.py
+++ b/pypy/module/sys/moduledef.py
@@ -95,6 +95,8 @@
'get_coroutine_wrapper' : 'vm.get_coroutine_wrapper',
'set_coroutine_wrapper' : 'vm.set_coroutine_wrapper',
+ 'get_asyncgen_hooks' : 'vm.get_asyncgen_hooks',
+ 'set_asyncgen_hooks' : 'vm.set_asyncgen_hooks',
'is_finalizing' : 'vm.is_finalizing',
}
@@ -115,8 +117,6 @@
'flags' : 'app.null_sysflags',
'_xoptions' : 'app.null__xoptions',
'implementation' : 'app.implementation',
- 'get_asyncgen_hooks' : 'app.get_asyncgen_hooks',
- 'set_asyncgen_hooks' : 'app.set_asyncgen_hooks',
# these six attributes are here only during tests;
# they are removed before translation
@@ -184,7 +184,7 @@
if w_file is w_stdout:
e.write_unraisable(space, '', w_file)
ret = -1
- return ret
+ return ret
def _file_is_closed(self, space, w_file):
try:
diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py
--- a/pypy/module/sys/vm.py
+++ b/pypy/module/sys/vm.py
@@ -7,7 +7,7 @@
from pypy.interpreter import gateway
from pypy.interpreter.error import oefmt
-from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
# ____________________________________________________________
@@ -240,6 +240,14 @@
suite_mask = structseqfield(12, "Bit mask identifying available product
suites")
product_type = structseqfield(13, "System product type")
platform_version = structseqfield(14, "Diagnostic version number")
+
+
+class asyncgen_hooks(metaclass=structseqtype):
+ name = "asyncgen_hooks"
+
+ firstiter = structseqfield(0)
+ finalizer = structseqfield(1)
+
''')
@@ -286,7 +294,7 @@
getsizeof_missing = """getsizeof(...)
getsizeof(object, default) -> int
-
+
Return the size of object in bytes.
sys.getsizeof(object, default) will always return default on PyPy, and
@@ -351,5 +359,45 @@
else:
raise oefmt(space.w_TypeError, "callable expected, got %T", w_wrapper)
+def get_asyncgen_hooks(space):
+ """get_asyncgen_hooks()
+
+Return a namedtuple of installed asynchronous generators hooks (firstiter,
finalizer)."""
+ ec = space.getexecutioncontext()
+ w_firstiter = ec.w_asyncgen_firstiter_fn
+ if w_firstiter is None:
+ w_firstiter = space.w_None
+ w_finalizer = ec.w_asyncgen_finalizer_fn
+ if w_finalizer is None:
+ w_finalizer = space.w_None
+ w_asyncgen_hooks = app.wget(space, "asyncgen_hooks")
+ return space.call_function(
+ w_asyncgen_hooks,
+ space.newtuple([w_firstiter, w_finalizer]))
+
+# Note: the docstring is wrong on CPython
+def set_asyncgen_hooks(space, w_firstiter=None, w_finalizer=None):
+ """set_asyncgen_hooks(firstiter=None, finalizer=None)
+
+Set a finalizer for async generators objects."""
+ ec = space.getexecutioncontext()
+ if space.is_w(w_finalizer, space.w_None):
+ ec.w_asyncgen_finalizer_fn = None
+ elif w_finalizer is not None:
+ if space.callable_w(w_finalizer):
+ ec.w_asyncgen_finalizer_fn = w_finalizer
+ else:
+ raise oefmt(space.w_TypeError,
+ "callable finalizer expected, got %T", w_finalizer)
+ if space.is_w(w_firstiter, space.w_None):
+ ec.w_asyncgen_firstiter_fn = None
+ elif w_firstiter is not None:
+ if space.callable_w(w_firstiter):
+ ec.w_asyncgen_firstiter_fn = w_firstiter
+ else:
+ raise oefmt(space.w_TypeError,
+ "callable firstiter expected, got %T", w_firstiter)
+
+
def is_finalizing(space):
return space.newbool(space.sys.finalizing)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit