tornado
tornado copied to clipboard
web: Type SUPPORTED_METHODS so it can be overridden.
Its default type is Tuple[str, str, str, str, str, str, str], which can only be overridden by a tuple of the exact same length. Which is not terribly useful for its stated purpose.
Type it as a Collection[str], which should support folks overriding it as any number of reasonable things, as it is only used by way of if request.method not in self.SUPPORTED_METHODS.
Mypy reveals some implicit reliances on it being a Tuple:
tornado/web.py:1795: error: Item "None" of "Optional[str]" has no attribute "lower" [union-attr]
tornado/test/web_test.py:2190: error: Unsupported left operand type for + ("Collection[str]") [operator]
tornado/test/httpclient_test.py:124: error: Unsupported left operand type for + ("Collection[str]") [operator]
(The first error is a result of Mypy permitting type narrowing of the left operand of in when the right operand is a Tuple but not when it’s a Collection.)
We could remove these reliances, or keep them and use Tuple[str, ...] (the literal ellipsis makes this a variable-length tuple type).
It ideally should be a set, since it's primarily used for an in query. However, that would be a non-backwards-compatible change, since subclasses in the wild which are doing RequestHandler.SUPPORTED_METHODS + ("OTHER",) would break.
Maintainers, do you have a preference between Tuple[str, ...] or the backwards-incompatible Set[str]?
I prefer to keep this as a tuple. Logically it should have been a set, but whether it's a set or a tuple the interface of modifying SUPPORTED_METHODS is awkward and there should be a different way to declare a method to be HTTP-accessible. (perhaps either a decorator, or an overridable check_http_method(name) which defaults to name in self.SUPPORTED_METHODS). I'd rather keep the tuple in place and eventually move to a better solution than to force a backwards-incompatible change to move from a tuple to a set if that's not the long-term solution.
I'll make the change to Tuple[str, ...].