Skip to content

_Result is unnecessary? #260

@bluetech

Description

@bluetech

In #257, @maxnikulin brought up an idea which seems very natural but hasn't occurred to me beforehand. I think it will at least be interesting to discuss it on its own.

Background

_Result is used in hookwrappers as follows (using imaginary type annotations for clarity):

from typing import Generator, TypeVar

T = TypeVar("T")
E = TypeVar("E")

@hookimpl(hookwrapper=True)
def my_hook() -> Generator[None, _Result[T, E], None]:
    # ... Some setup code ...

    result = yield

    try:
        value = result.get_result()
    except Exception as exc:
        # ... Use exc ...
    else:
        # ... Use value ...

    # ... Some teardown code ...

The result has three use cases:

  1. Fetch the return value[s] of the hook, if it didn't raise.
  2. Fetch the exception of the hook, if it did raise.
  3. Override (force) the return value/exception to some other return value.

Idea

Python coroutines already provide a way to distinguish between a successful yield (-> coroutine.send(value)) and a throwing yield (-> coroutine.throw(exc)). So in the above, the _Result indirection could have been dispensed with:

@hookimpl(imaginary_hookwrapper=True)
def my_hook() -> Generator[None, T, None]:
    # ... Some setup code ...

    try:
        value = yield
    except Exception as exc:
        # ... Use exc ...
    else:
        # ... Use value ...

    # ... Some teardown code ...

This handles use cases 1 & 2. Regarding use case 3 (forcing a result), use the coroutine return value:

@hookimpl(imaginary_hookwrapper=True)
def my_hook() -> Generator[None, T, T]:
    # ... Some setup code ...

    try:
        value = yield
    except Exception as exc:
        # ... Use exc ...
    else:
        # ... Use value ...

    # ... Some teardown code ...

    return new_value

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions