Skip to content

Event field types include None but (maybe) shouldn't #1298

Closed
@timoffex

Description

@timoffex

With the new 4.2.0 release that adds the py.typed marker, mypy is reporting that my Event handling code should be ready for None values. For instance,

if isinstance(event, h2.events.RequestReceived):
    stream = HTTP2StreamHandler(
        self._state,
        event.stream_id, # mypy: incompatible type "int | None"; expected "int"
        event.headers,   # mypy: incompatible type "list[HeaderTuple] | None"; expected "Iterable[HeaderTuple]"
    )

I can expect these fields to always be set, right? I could add assert statements like this:

if isinstance(event, h2.events.RequestReceived):
    assert event.stream_id is not None
    assert event.headers is not None
    stream = HTTP2StreamHandler(
        self._state,
        event.stream_id,
        event.headers,
    )

But it's clunky to make users do this.

I see that Event objects are constructed incrementally, so their fields can be None temporarily in h2 code, but I wish the types could reflect what I should expect as a user. What would you think of something like this?

class RequestReceived(Event):
    stream_id: int
    headers: list[HeaderTuple]

    def __init__(self) -> None:
        self.stream_ended: StreamEnded | None = None
        self.priority_updated: PriorityUpdated | None = None

It would work as long as h2 itself does not access stream_id / headers before setting them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions