diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index cc24ce46c..da7b88dfa 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -31,3 +31,7 @@ if django.VERSION < (3, 2): class RemovedInDRF315Warning(DeprecationWarning): pass + + +class RemovedInDRF317Warning(PendingDeprecationWarning): + pass diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 1ffd9edc0..17e6975eb 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -3,6 +3,7 @@ Provides generic filtering backends that can be used to filter the results returned by list views. """ import operator +import warnings from functools import reduce from django.core.exceptions import ImproperlyConfigured @@ -12,6 +13,7 @@ from django.template import loader from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ +from rest_framework import RemovedInDRF317Warning from rest_framework.compat import coreapi, coreschema, distinct from rest_framework.settings import api_settings @@ -29,6 +31,8 @@ class BaseFilterBackend: def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' return [] @@ -146,6 +150,8 @@ class SearchFilter(BaseFilterBackend): def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' return [ coreapi.Field( @@ -306,6 +312,8 @@ class OrderingFilter(BaseFilterBackend): def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' return [ coreapi.Field( diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index af508bef6..ce8778547 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -4,6 +4,8 @@ be used for paginated responses. """ import contextlib +import warnings + from base64 import b64decode, b64encode from collections import namedtuple from urllib import parse @@ -15,6 +17,7 @@ from django.template import loader from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ +from rest_framework import RemovedInDRF317Warning from rest_framework.compat import coreapi, coreschema from rest_framework.exceptions import NotFound from rest_framework.response import Response @@ -152,6 +155,8 @@ class BasePagination: def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) return [] def get_schema_operation_parameters(self, view): @@ -311,6 +316,8 @@ class PageNumberPagination(BasePagination): def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' fields = [ coreapi.Field( @@ -525,6 +532,8 @@ class LimitOffsetPagination(BasePagination): def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' return [ coreapi.Field( @@ -930,6 +939,8 @@ class CursorPagination(BasePagination): def get_schema_fields(self, view): assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`' fields = [ coreapi.Field( diff --git a/rest_framework/schemas/coreapi.py b/rest_framework/schemas/coreapi.py index 0713e0cb8..582aba196 100644 --- a/rest_framework/schemas/coreapi.py +++ b/rest_framework/schemas/coreapi.py @@ -5,7 +5,7 @@ from urllib import parse from django.db import models from django.utils.encoding import force_str -from rest_framework import exceptions, serializers +from rest_framework import RemovedInDRF317Warning, exceptions, serializers from rest_framework.compat import coreapi, coreschema, uritemplate from rest_framework.settings import api_settings @@ -118,6 +118,8 @@ class SchemaGenerator(BaseSchemaGenerator): def __init__(self, title=None, url=None, description=None, patterns=None, urlconf=None, version=None): assert coreapi, '`coreapi` must be installed for schema support.' + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) assert coreschema, '`coreschema` must be installed for schema support.' super().__init__(title, url, description, patterns, urlconf) @@ -351,6 +353,9 @@ class AutoSchema(ViewInspector): will be added to auto-generated fields, overwriting on `Field.name` """ super().__init__() + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) + if manual_fields is None: manual_fields = [] self._manual_fields = manual_fields @@ -592,6 +597,9 @@ class ManualSchema(ViewInspector): * `description`: String description for view. Optional. """ super().__init__() + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) + assert all(isinstance(f, coreapi.Field) for f in fields), "`fields` must be a list of coreapi.Field instances" self._fields = fields self._description = description @@ -613,4 +621,6 @@ class ManualSchema(ViewInspector): def is_enabled(): """Is CoreAPI Mode enabled?""" + if coreapi is not None: + warnings.warn('CoreAPI compatibility is deprecated and will be removed in DRF 3.17', RemovedInDRF317Warning) return issubclass(api_settings.DEFAULT_SCHEMA_CLASS, AutoSchema) diff --git a/setup.cfg b/setup.cfg index 294e9afdd..487d99db9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,8 @@ license_files = LICENSE.md [tool:pytest] addopts=--tb=short --strict-markers -ra +testspath = tests +filterwarnings = ignore:CoreAPI compatibility is deprecated*:rest_framework.RemovedInDRF317Warning [flake8] ignore = E501,W503,W504 diff --git a/tests/schemas/test_coreapi.py b/tests/schemas/test_coreapi.py index eddc5243e..98fd46f9f 100644 --- a/tests/schemas/test_coreapi.py +++ b/tests/schemas/test_coreapi.py @@ -7,16 +7,24 @@ from django.test import TestCase, override_settings from django.urls import include, path from rest_framework import ( - filters, generics, pagination, permissions, serializers + RemovedInDRF317Warning, filters, generics, pagination, permissions, + serializers ) from rest_framework.compat import coreapi, coreschema from rest_framework.decorators import action, api_view, schema +from rest_framework.filters import ( + BaseFilterBackend, OrderingFilter, SearchFilter +) +from rest_framework.pagination import ( + BasePagination, CursorPagination, LimitOffsetPagination, + PageNumberPagination +) from rest_framework.request import Request from rest_framework.routers import DefaultRouter, SimpleRouter from rest_framework.schemas import ( AutoSchema, ManualSchema, SchemaGenerator, get_schema_view ) -from rest_framework.schemas.coreapi import field_to_schema +from rest_framework.schemas.coreapi import field_to_schema, is_enabled from rest_framework.schemas.generators import EndpointEnumerator from rest_framework.schemas.utils import is_list_view from rest_framework.test import APIClient, APIRequestFactory @@ -1433,3 +1441,46 @@ def test_schema_handles_exception(): response.render() assert response.status_code == 403 assert b"You do not have permission to perform this action." in response.content + + +@pytest.mark.skipif(not coreapi, reason='coreapi is not installed') +def test_coreapi_deprecation(): + with pytest.warns(RemovedInDRF317Warning): + SchemaGenerator() + + with pytest.warns(RemovedInDRF317Warning): + AutoSchema() + + with pytest.warns(RemovedInDRF317Warning): + ManualSchema({}) + + with pytest.warns(RemovedInDRF317Warning): + deprecated_filter = OrderingFilter() + deprecated_filter.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + deprecated_filter = BaseFilterBackend() + deprecated_filter.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + deprecated_filter = SearchFilter() + deprecated_filter.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + paginator = BasePagination() + paginator.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + paginator = PageNumberPagination() + paginator.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + paginator = LimitOffsetPagination() + paginator.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + paginator = CursorPagination() + paginator.get_schema_fields({}) + + with pytest.warns(RemovedInDRF317Warning): + is_enabled()