Make Fetcher Protocol generic on the media type#163
Merged
Conversation
Parameterize `Fetcher` on the media subtype it handles so
subclass-specific implementations (currently `TVMaze`, future fetchers
for other media types) can declare narrower `fetch` signatures without
failing type checks.
The previous declaration:
class Fetcher(Protocol):
def fetch(self, media: Media) -> None: ...
required every implementation to accept any `Media`. `TVMaze.fetch`
narrows to `TV`, which means it does not satisfy the protocol; passing
a generic `Media` to `TVMaze.fetch` would be a type error. `mypy` was
(correctly) flagging this with a `[arg-type]` error at the
`PROCESSOR_FACTORIES` `dict` literal.
The new declaration uses Python 3.12 generic class syntax:
class Fetcher[M: Media](Protocol):
def fetch(self, media: M) -> None: ...
`Processor` and `ProcessorFactory` are parameterized to match, so the
type relationship between a factory's `media_type` and its `fetcher` is
now expressed in the type system instead of being implicit. The
heterogeneous `PROCESSOR_FACTORIES` `dict` uses `ProcessorFactory[Any]`
as its value type.
Internally, `Processor.process` now returns `M` instead of `Media`
(callers see a narrower type at no cost) and the local annotation on
`media` was tightened from `Media` to `M` so the narrowing carries
through to `self.fetcher.fetch(media)`.
Resolve #161.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Parameterize
Fetcheron the media subtype it handles so subclass-specific implementations (currentlyTVMaze, future fetchers for other media types) can declare narrowerfetchsignatures without failing type checks.The previous declaration:
required every implementation to accept any
Media.TVMaze.fetchnarrows toTV, which means it does not satisfy the protocol; passing a genericMediatoTVMaze.fetchwould be a type error.mypywas (correctly) flagging this with a[arg-type]error at thePROCESSOR_FACTORIESdictliteral.The new declaration uses Python 3.12 generic class syntax:
ProcessorandProcessorFactoryare parameterized to match, so the type relationship between a factory'smedia_typeand itsfetcheris now expressed in the type system instead of being implicit. The heterogeneousPROCESSOR_FACTORIESdictusesProcessorFactory[Any]as its value type.Internally,
Processor.processnow returnsMinstead ofMedia(callers see a narrower type at no cost) and the local annotation onmediawas tightened fromMediatoMso the narrowing carries through toself.fetcher.fetch(media).Resolve #161.