From 1f3923a999e3b4430ea76727e07fb062b24d6a61 Mon Sep 17 00:00:00 2001 From: LeeW Date: Mon, 6 May 2019 12:08:28 -0400 Subject: [PATCH] Inherit "methods" in MethodView * Current behavior: If a base class inherits MethodView and child class inherits without overwriting "methods". The "methods" defined in base class would be ignored * Fix: Inherit all the "methods" defined in base classes if "methods" variable is not overwritten --- CHANGES.rst | 5 ++++- flask/views.py | 4 ++++ tests/test_views.py | 21 +++++++++++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 930fd7e8..20cb934e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -21,12 +21,15 @@ Unreleased - :func:`send_file` supports :class:`~io.BytesIO` partial content. (`#2957`_) - :func:`open_resource` accepts the "rt" file mode. This still does - the same thing as "r". (:issue:`3163`) + the same thing as "r". :issue:`3163` +- The :attr:`MethodView.methods` attribute set in a base class is used + by subclasses. :issue:`3138` .. _#2935: https://github.com/pallets/flask/issues/2935 .. _#2957: https://github.com/pallets/flask/issues/2957 .. _#2994: https://github.com/pallets/flask/pull/2994 .. _#3059: https://github.com/pallets/flask/pull/3059 +.. _#3179: https://github.com/pallets/flask/pull/3179 Version 1.0.3 diff --git a/flask/views.py b/flask/views.py index debd19e7..0a4f4688 100644 --- a/flask/views.py +++ b/flask/views.py @@ -120,6 +120,10 @@ class MethodViewType(type): if "methods" not in d: methods = set() + for base in bases: + if getattr(base, "methods", None): + methods.update(base.methods) + for key in http_method_funcs: if hasattr(cls, key): methods.add(key.upper()) diff --git a/tests/test_views.py b/tests/test_views.py index 27240e1d..7c8610fc 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -10,12 +10,11 @@ """ import pytest +from werkzeug.http import parse_set_header import flask import flask.views -from werkzeug.http import parse_set_header - def common_test(app): c = app.test_client() @@ -199,6 +198,24 @@ def test_endpoint_override(app): common_test(app) +def test_methods_var_inheritance(app, client): + class BaseView(flask.views.MethodView): + methods = ["GET", "PROPFIND"] + + class ChildView(BaseView): + def get(self): + return "GET" + + def propfind(self): + return "PROPFIND" + + app.add_url_rule("/", view_func=ChildView.as_view("index")) + + assert client.get("/").data == b"GET" + assert client.open("/", method="PROPFIND").data == b"PROPFIND" + assert ChildView.methods == {"PROPFIND", "GET"} + + def test_multiple_inheritance(app, client): class GetView(flask.views.MethodView): def get(self):