We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Precise Type Hints with Literals and Generics step 18 of 26
Catch a Renamed Method with @override
A teammate renames a method in a base class, or misspells it in a subclass. The subclass method no longer replaces the base one, and Python reports no error:
class Notifier:
def deliver(self, message: str) -> bool:
return False
class EmailNotifier(Notifier):
def delivr(self, message: str) -> bool:
return 0 < len(message) <= 100
EmailNotifier().deliver("hi") # False: the base method still runs
Put @override (from typing) on the subclass method. It tells mypy that
this method must replace a method of the same name in a base class. mypy then
reports the typo:
Method "delivr" is marked as an override, but no base method was found with this name
mypy checks that the two signatures are compatible for every method that
replaces a base method, with or without @override. At runtime, @override
changes nothing.
What to write
The starter's Notifier is an abstract base class. Its deliver is an
@abstractmethod, so a subclass must implement it before you can create an
instance.
- Rename
EmailNotifier.delivrtodeliver, and put@overrideon it. - Write
SmsNotifier(Notifier)with an@overridedelivermethod. EmailNotifier.deliver(message)returnsTruewhen0 < len(message) <= 100, andFalseotherwise.SmsNotifier.deliver(message)returnsTruewhen0 < len(message) <= 20, andFalseotherwise.- Count characters with
len. Do not trim the message, so" "has length 1. The methods send nothing. dispatch(notifiers: Sequence[Notifier], message: str) -> list[bool]calls each notifier'sdeliveronce, in order, and returns the results in the same order. Repeated notifiers each get a result. If a notifier raises, let the exception propagate.
What solve returns
solve(kinds: list[str], message: str) -> tuple[list[bool], int, list[str]]
reads kinds in order. For each exact "email" or "sms", it creates that
notifier. It does not change case or trim, so "EMAIL" is not "email".
Every other kind goes into a skipped list, in order and with duplicates.
It returns a tuple of three values:
- The
dispatchresults for the notifiers it created. - How many results are
True.sum(results)counts them. - The skipped kinds.
assert solve(["email", "sms"], "hello") == ([True, True], 2, [])
assert solve(["sms", "email"], "x" * 21) == ([False, True], 1, [])
assert solve(["EMAIL", "email", "push", "push"], " ") == ([True], 1, ["EMAIL", "push", "push"])
assert solve([], "hello") == ([], 0, [])
Going further
mypy --enable-error-code explicit-override also reports any overriding
method that lacks @override. The site's grader does not turn it on, but you
can run it locally to check that both deliver methods have the decorator.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.