From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C4F4D158089 for ; Tue, 10 Oct 2023 10:25:09 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 01A382BC013; Tue, 10 Oct 2023 10:25:09 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id CC7D32BC013 for ; Tue, 10 Oct 2023 10:25:08 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 0D6B5335C2E for ; Tue, 10 Oct 2023 10:25:08 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 8993C99B for ; Tue, 10 Oct 2023 10:25:06 +0000 (UTC) From: "David Roman" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "David Roman" Message-ID: <1696933478.45dcc17b9a0fa35c9b6cbbb82488c9e086d837cf.davidroman@gentoo> Subject: [gentoo-commits] repo/proj/guru:dev commit in: dev-python/flask-restx/, dev-python/flask-restx/files/ X-VCS-Repository: repo/proj/guru X-VCS-Files: dev-python/flask-restx/files/flask-restx-fix-flask-compat.patch dev-python/flask-restx/flask-restx-1.1.0-r1.ebuild X-VCS-Directories: dev-python/flask-restx/files/ dev-python/flask-restx/ X-VCS-Committer: davidroman X-VCS-Committer-Name: David Roman X-VCS-Revision: 45dcc17b9a0fa35c9b6cbbb82488c9e086d837cf X-VCS-Branch: dev Date: Tue, 10 Oct 2023 10:25:06 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 7eec5691-e9db-439d-9a3d-a9816a4669ad X-Archives-Hash: c633180d77c44eee209b4feef9c17c40 commit: 45dcc17b9a0fa35c9b6cbbb82488c9e086d837cf Author: David Roman gmail com> AuthorDate: Tue Oct 10 10:24:38 2023 +0000 Commit: David Roman gmail com> CommitDate: Tue Oct 10 10:24:38 2023 +0000 URL: https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=45dcc17b dev-python/flask-restx: fix compatibility with flask 3.0.0 Closes: https://bugs.gentoo.org/915523 Signed-off-by: David Roman gmail.com> .../files/flask-restx-fix-flask-compat.patch | 150 +++++++++++++++++++++ dev-python/flask-restx/flask-restx-1.1.0-r1.ebuild | 50 +++++++ 2 files changed, 200 insertions(+) diff --git a/dev-python/flask-restx/files/flask-restx-fix-flask-compat.patch b/dev-python/flask-restx/files/flask-restx-fix-flask-compat.patch new file mode 100644 index 0000000000..a91a0f3e7f --- /dev/null +++ b/dev-python/flask-restx/files/flask-restx-fix-flask-compat.patch @@ -0,0 +1,150 @@ +diff --git a/flask_restx/api.py b/flask_restx/api.py +index 5996dd59..bd0413dd 100644 +--- a/flask_restx/api.py ++++ b/flask_restx/api.py +@@ -14,10 +14,6 @@ + from flask import url_for, request, current_app + from flask import make_response as original_flask_make_response + +-try: +- from flask.helpers import _endpoint_from_view_func +-except ImportError: +- from flask.scaffold import _endpoint_from_view_func + from flask.signals import got_request_exception + + from jsonschema import RefResolver +@@ -45,10 +41,13 @@ + from .postman import PostmanCollectionV1 + from .resource import Resource + from .swagger import Swagger +-from .utils import default_id, camel_to_dash, unpack ++from .utils import default_id, camel_to_dash, unpack, import_check_view_func + from .representations import output_json + from ._http import HTTPStatus + ++endpoint_from_view_func = import_check_view_func() ++ ++ + RE_RULES = re.compile("(<.*>)") + + # List headers that should never be handled by Flask-RESTX +@@ -850,7 +849,7 @@ def _blueprint_setup_add_url_rule_patch( + rule = blueprint_setup.url_prefix + rule + options.setdefault("subdomain", blueprint_setup.subdomain) + if endpoint is None: +- endpoint = _endpoint_from_view_func(view_func) ++ endpoint = endpoint_from_view_func(view_func) + defaults = blueprint_setup.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) +diff --git a/flask_restx/utils.py b/flask_restx/utils.py +index 809a29b3..35dec2ae 100644 +--- a/flask_restx/utils.py ++++ b/flask_restx/utils.py +@@ -1,4 +1,6 @@ + import re ++import warnings ++import typing + + from collections import OrderedDict + from copy import deepcopy +@@ -20,6 +22,10 @@ + ) + + ++class FlaskCompatibilityWarning(DeprecationWarning): ++ pass ++ ++ + def merge(first, second): + """ + Recursively merges two dictionaries. +@@ -118,3 +124,43 @@ def unpack(response, default_code=HTTPStatus.OK): + return data, code or default_code, headers + else: + raise ValueError("Too many response values") ++ ++ ++def to_view_name(view_func: typing.Callable) -> str: ++ """Helper that returns the default endpoint for a given ++ function. This always is the function name. ++ ++ Note: copy of simple flask internal helper ++ """ ++ assert view_func is not None, "expected view func if endpoint is not provided." ++ return view_func.__name__ ++ ++ ++def import_check_view_func(): ++ """ ++ Resolve import flask _endpoint_from_view_func. ++ ++ Show warning if function cannot be found and provide copy of last known implementation. ++ ++ Note: This helper method exists because reoccurring problem with flask function, but ++ actual method body remaining the same in each flask version. ++ """ ++ import importlib.metadata ++ ++ flask_version = importlib.metadata.version("flask").split(".") ++ try: ++ if flask_version[0] == "1": ++ from flask.helpers import _endpoint_from_view_func ++ elif flask_version[0] == "2": ++ from flask.scaffold import _endpoint_from_view_func ++ elif flask_version[0] == "3": ++ from flask.sansio.scaffold import _endpoint_from_view_func ++ else: ++ warnings.simplefilter("once", FlaskCompatibilityWarning) ++ _endpoint_from_view_func = None ++ except ImportError: ++ warnings.simplefilter("once", FlaskCompatibilityWarning) ++ _endpoint_from_view_func = None ++ if _endpoint_from_view_func is None: ++ _endpoint_from_view_func = to_view_name ++ return _endpoint_from_view_func +diff --git a/tests/test_utils.py b/tests/test_utils.py +index d98d68d0..fe3a1adb 100644 +--- a/tests/test_utils.py ++++ b/tests/test_utils.py +@@ -98,3 +98,17 @@ def test_value_headers_default_code(self): + def test_too_many_values(self): + with pytest.raises(ValueError): + utils.unpack((None, None, None, None)) ++ ++ ++class ToViewNameTest(object): ++ def test_none(self): ++ with pytest.raises(AssertionError): ++ _ = utils.to_view_name(None) ++ ++ def test_name(self): ++ assert self.test_none == self.test_none.__name__ ++ ++ ++class ImportCheckViewFuncTest(object): ++ def test_callable(self): ++ assert callable(utils.import_check_view_func()) + +From 13ac54e4ba513c01ec8e4a23b4e88b7b555cf2f1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Trval?= +Date: Fri, 6 Oct 2023 15:46:13 +0200 +Subject: [PATCH 2/2] modify: include new import_check_view_func in + utils.__all__ to keep nice static checks + +--- + flask_restx/utils.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/flask_restx/utils.py b/flask_restx/utils.py +index 35dec2ae..367527a5 100644 +--- a/flask_restx/utils.py ++++ b/flask_restx/utils.py +@@ -19,6 +19,7 @@ + "not_none", + "not_none_sorted", + "unpack", ++ "import_check_view_func", + ) + + diff --git a/dev-python/flask-restx/flask-restx-1.1.0-r1.ebuild b/dev-python/flask-restx/flask-restx-1.1.0-r1.ebuild new file mode 100644 index 0000000000..291db010e6 --- /dev/null +++ b/dev-python/flask-restx/flask-restx-1.1.0-r1.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2022 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +DISTUTILS_USE_PEP517=setuptools +PYTHON_COMPAT=( python3_{11,12}) +inherit distutils-r1 + +DESCRIPTION="Framework API development with Flask" +HOMEPAGE="https://flask-restx.readthedocs.io" +SRC_URI="https://github.com/python-restx/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="BSD" +SLOT="0" +KEYWORDS="~amd64" +IUSE="test" + +PATCHES=( "${FILESDI}/${PN}-fix-flask-compat.patch" ) + +RDEPEND=" + dev-python/aniso8601[${PYTHON_USEDEP}] + dev-python/flask[${PYTHON_USEDEP}] + dev-python/jsonschema[${PYTHON_USEDEP}] + dev-python/pytz[${PYTHON_USEDEP}] + dev-python/six[${PYTHON_USEDEP}] + dev-python/werkzeug[${PYTHON_USEDEP}] +" + +DEPEND="${RDEPEND} + test? ( + dev-python/blinker[${PYTHON_USEDEP}] + dev-python/Faker[${PYTHON_USEDEP}] + dev-python/pytest-flask[${PYTHON_USEDEP}] + dev-python/pytest-mock[${PYTHON_USEDEP}] + dev-python/tzlocal[${PYTHON_USEDEP}] + ) +" + +distutils_enable_tests pytest + +python_test() { + skip_tests=" \ + not ReqParseTest and \ + not EmailTest and \ + not URLTest and \ + not LoggingTest" + + epytest tests/test_*.py -k "${skip_tests}" +}