From c6f0f7a2a990707657b85ed35447a8ad515c3bdb Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Wed, 9 Oct 2019 15:40:35 -0500 Subject: [PATCH 1/3] Fix CI --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 2bb1034e..8d7ffb88 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -57,7 +57,7 @@ install: # compiled extensions and are not provided as pre-built wheel packages, # pip will build them from source using the MSVC compiler matching the # target Python version and architecture - - "%CMD_IN_ENV% pip install pytest==4.2.0 pythonnet six cefpython3==66.0" + - "%CMD_IN_ENV% pip install \"pytest>=4.3.0\" pythonnet six cefpython3==66.0" test_script: From 2532d98fa0c5aabf9abb416f2fa5446b3b9bd2c8 Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Wed, 9 Oct 2019 14:57:07 -0500 Subject: [PATCH 2/3] Replace use of Thread with ThreadPoolExecutor Also log any error while evaluating callbacks, not just if thread creation fails. --- webview/util.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/webview/util.py b/webview/util.py index 5b3ab4ef..0f5d1829 100644 --- a/webview/util.py +++ b/webview/util.py @@ -12,6 +12,7 @@ import os import re import sys +from concurrent.futures.thread import ThreadPoolExecutor from platform import architecture from threading import Thread from uuid import uuid4 @@ -24,6 +25,8 @@ logger = logging.getLogger('pywebview') +executor = ThreadPoolExecutor() + class WebViewException(Exception): pass @@ -84,23 +87,20 @@ def generate_func(): def js_bridge_call(window, func_name, param): - def _call(): - result = json.dumps(func(func_params)).replace('\\', '\\\\').replace('\'', '\\\'') - code = 'window.pywebview._returnValues["{0}"] = {{ isSet: true, value: \'{1}\'}}'.format(func_name, result) - window.evaluate_js(code) - func = getattr(window.js_api, func_name, None) + if func is None: + logger.error('Function {}() does not exist'.format(func_name)) + return - if func is not None: + def done_callback(future): try: - func_params = param if not param else json.loads(param) - t = Thread(target=_call) - t.start() + result = json.dumps(future.result()).replace('\\', '\\\\').replace('\'', '\\\'') + code = 'window.pywebview._returnValues["{0}"] = {{ isSet: true, value: \'{1}\'}}'.format(func_name, result) + window.evaluate_js(code) except Exception: logger.exception('Error occurred while evaluating function {0}'.format(func_name)) - else: - logger.error('Function {}() does not exist'.format(func_name)) + executor.submit(func, param and json.loads(param)).add_done_callback(done_callback) def escape_string(string): return string\ From 143100f4274caea07019fb408075c8abb5f3a268 Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Wed, 9 Oct 2019 16:39:20 -0500 Subject: [PATCH 3/3] Add backport of futures for legacy python compatibility --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 47dab62c..7688ffed 100644 --- a/setup.py +++ b/setup.py @@ -11,6 +11,7 @@ 'pythonnet ; sys_platform == "win32"', 'pyobjc ; sys_platform == "darwin"', 'PyQt5 ; sys_platform == "openbsd6"', + 'futures; python_version < "3.2"', ]