Skip to content

Commit

Permalink
Merge pull request #2055 from freakboy3742/test-handlers
Browse files Browse the repository at this point in the history
Test coverage for handlers
  • Loading branch information
mhsmith authored Jul 31, 2023
2 parents c6f00ca + 07cc6ef commit e07153a
Show file tree
Hide file tree
Showing 7 changed files with 581 additions and 36 deletions.
1 change: 1 addition & 0 deletions changes/2055.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Full test coverage for handlers was added.
6 changes: 1 addition & 5 deletions core/src/toga/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,7 @@ def _package_version(file, name):
# If it *is* in the environment, but the code isn't a git checkout (e.g.,
# it's been pip installed non-editable) the call to get_version() will fail.
# If either of these occurs, read version from the installer metadata.
try:
from importlib import metadata as importlib_metadata
except ImportError:
# Backwards compatibility - importlib.metadata was added in Python 3.8
import importlib_metadata
from importlib import metadata as importlib_metadata

# The Toga package names as defined in setup.cfg all use dashes.
package = "toga-core" if name == "toga" else name.replace("_", "-")
Expand Down
7 changes: 1 addition & 6 deletions core/src/toga/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from builtins import id as identifier
from collections.abc import MutableSet
from email.message import Message
from importlib import metadata as importlib_metadata
from typing import Any, Iterable, Protocol

from toga.command import CommandSet
Expand All @@ -17,12 +18,6 @@
from toga.widgets.base import Widget, WidgetRegistry
from toga.window import Window

try:
from importlib import metadata as importlib_metadata
except ImportError:
# Backwards compatibility - importlib.metadata was added in Python 3.8
import importlib_metadata

# Make sure deprecation warnings are shown by default
warnings.filterwarnings("default", category=DeprecationWarning)

Expand Down
58 changes: 39 additions & 19 deletions core/src/toga/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,41 @@ def __init__(self, handler):
self.native = handler


async def long_running_task(generator, cleanup):
async def long_running_task(interface, generator, cleanup):
"""Run a generator as an asynchronous coroutine."""
try:
while True:
delay = next(generator)
await asyncio.sleep(delay)
except StopIteration:
if cleanup:
cleanup()
try:
while True:
delay = next(generator)
if delay:
await asyncio.sleep(delay)
except StopIteration as e:
result = e.value
except Exception as e:
print("Error in long running handler:", e, file=sys.stderr)
traceback.print_exc()
else:
if cleanup:
try:
cleanup(interface, result)
except Exception as e:
print("Error in long running handler cleanup:", e, file=sys.stderr)
traceback.print_exc()


async def handler_with_cleanup(handler, cleanup, interface, *args, **kwargs):
try:
result = await handler(interface, *args, **kwargs)
if cleanup:
cleanup(interface, result)
except Exception as e:
print("Error in async handler:", e, file=sys.stderr)
traceback.print_exc()
else:
if cleanup:
try:
cleanup(interface, result)
except Exception as e:
print("Error in async handler cleanup:", e, file=sys.stderr)
traceback.print_exc()


def wrapped_handler(interface, handler, cleanup=None):
Expand Down Expand Up @@ -62,17 +75,24 @@ def _handler(widget, *args, **kwargs):
handler_with_cleanup(handler, cleanup, interface, *args, **kwargs)
)
else:
result = handler(interface, *args, **kwargs)
if inspect.isgenerator(result):
asyncio.ensure_future(long_running_task(result, cleanup))
try:
result = handler(interface, *args, **kwargs)
except Exception as e:
print("Error in handler:", e, file=sys.stderr)
traceback.print_exc()
else:
try:
if cleanup:
cleanup(interface, result)
return result
except Exception as e:
print("Error in handler:", e, file=sys.stderr)
traceback.print_exc()
if inspect.isgenerator(result):
asyncio.ensure_future(
long_running_task(interface, result, cleanup)
)
else:
try:
if cleanup:
cleanup(interface, result)
return result
except Exception as e:
print("Error in handler cleanup:", e, file=sys.stderr)
traceback.print_exc()

_handler._raw = handler

Expand Down
5 changes: 0 additions & 5 deletions core/tests/test_handler.py

This file was deleted.

Loading

0 comments on commit e07153a

Please sign in to comment.