Added Deprecation Warnings for CoreAPI (#7519)

* Added Deprecation Warnings for CoreAPI

* Bumped removal to DRF315

* Update rest_framework/__init__.py

* Update rest_framework/filters.py

* Update rest_framework/filters.py

* Update tests/schemas/test_coreapi.py

* Update rest_framework/filters.py

* Update rest_framework/filters.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update rest_framework/pagination.py

* Update rest_framework/pagination.py

* Update rest_framework/pagination.py

* Update rest_framework/pagination.py

* Update rest_framework/schemas/coreapi.py

* Update rest_framework/schemas/coreapi.py

* Update rest_framework/schemas/coreapi.py

* Update rest_framework/schemas/coreapi.py

* Update rest_framework/schemas/coreapi.py

* Update tests/schemas/test_coreapi.py

* Update setup.cfg

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update tests/schemas/test_coreapi.py

* Update rest_framework/pagination.py

---------

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
This commit is contained in:
David Smith 2023-06-13 07:55:22 +01:00 committed by GitHub
parent 833313496c
commit a16dbfd110
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 3 deletions

View File

@ -31,3 +31,7 @@ if django.VERSION < (3, 2):
class RemovedInDRF315Warning(DeprecationWarning): class RemovedInDRF315Warning(DeprecationWarning):
pass pass
class RemovedInDRF317Warning(PendingDeprecationWarning):
pass

View File

@ -3,6 +3,7 @@ Provides generic filtering backends that can be used to filter the results
returned by list views. returned by list views.
""" """
import operator import operator
import warnings
from functools import reduce from functools import reduce
from django.core.exceptions import ImproperlyConfigured 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.encoding import force_str
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import RemovedInDRF317Warning
from rest_framework.compat import coreapi, coreschema, distinct from rest_framework.compat import coreapi, coreschema, distinct
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@ -29,6 +31,8 @@ class BaseFilterBackend:
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
return [] return []
@ -146,6 +150,8 @@ class SearchFilter(BaseFilterBackend):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
return [ return [
coreapi.Field( coreapi.Field(
@ -306,6 +312,8 @@ class OrderingFilter(BaseFilterBackend):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
return [ return [
coreapi.Field( coreapi.Field(

View File

@ -4,6 +4,8 @@ be used for paginated responses.
""" """
import contextlib import contextlib
import warnings
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from collections import namedtuple from collections import namedtuple
from urllib import parse from urllib import parse
@ -15,6 +17,7 @@ from django.template import loader
from django.utils.encoding import force_str from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import RemovedInDRF317Warning
from rest_framework.compat import coreapi, coreschema from rest_framework.compat import coreapi, coreschema
from rest_framework.exceptions import NotFound from rest_framework.exceptions import NotFound
from rest_framework.response import Response from rest_framework.response import Response
@ -152,6 +155,8 @@ class BasePagination:
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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 [] return []
def get_schema_operation_parameters(self, view): def get_schema_operation_parameters(self, view):
@ -311,6 +316,8 @@ class PageNumberPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
fields = [ fields = [
coreapi.Field( coreapi.Field(
@ -525,6 +532,8 @@ class LimitOffsetPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
return [ return [
coreapi.Field( coreapi.Field(
@ -930,6 +939,8 @@ class CursorPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' 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()`' assert coreschema is not None, 'coreschema must be installed to use `get_schema_fields()`'
fields = [ fields = [
coreapi.Field( coreapi.Field(

View File

@ -5,7 +5,7 @@ from urllib import parse
from django.db import models from django.db import models
from django.utils.encoding import force_str 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.compat import coreapi, coreschema, uritemplate
from rest_framework.settings import api_settings 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): def __init__(self, title=None, url=None, description=None, patterns=None, urlconf=None, version=None):
assert coreapi, '`coreapi` must be installed for schema support.' 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.' assert coreschema, '`coreschema` must be installed for schema support.'
super().__init__(title, url, description, patterns, urlconf) 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` will be added to auto-generated fields, overwriting on `Field.name`
""" """
super().__init__() 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: if manual_fields is None:
manual_fields = [] manual_fields = []
self._manual_fields = manual_fields self._manual_fields = manual_fields
@ -592,6 +597,9 @@ class ManualSchema(ViewInspector):
* `description`: String description for view. Optional. * `description`: String description for view. Optional.
""" """
super().__init__() 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" assert all(isinstance(f, coreapi.Field) for f in fields), "`fields` must be a list of coreapi.Field instances"
self._fields = fields self._fields = fields
self._description = description self._description = description
@ -613,4 +621,6 @@ class ManualSchema(ViewInspector):
def is_enabled(): def is_enabled():
"""Is CoreAPI Mode 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) return issubclass(api_settings.DEFAULT_SCHEMA_CLASS, AutoSchema)

View File

@ -3,6 +3,8 @@ license_files = LICENSE.md
[tool:pytest] [tool:pytest]
addopts=--tb=short --strict-markers -ra addopts=--tb=short --strict-markers -ra
testspath = tests
filterwarnings = ignore:CoreAPI compatibility is deprecated*:rest_framework.RemovedInDRF317Warning
[flake8] [flake8]
ignore = E501,W503,W504 ignore = E501,W503,W504

View File

@ -7,16 +7,24 @@ from django.test import TestCase, override_settings
from django.urls import include, path from django.urls import include, path
from rest_framework import ( 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.compat import coreapi, coreschema
from rest_framework.decorators import action, api_view, schema 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.request import Request
from rest_framework.routers import DefaultRouter, SimpleRouter from rest_framework.routers import DefaultRouter, SimpleRouter
from rest_framework.schemas import ( from rest_framework.schemas import (
AutoSchema, ManualSchema, SchemaGenerator, get_schema_view 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.generators import EndpointEnumerator
from rest_framework.schemas.utils import is_list_view from rest_framework.schemas.utils import is_list_view
from rest_framework.test import APIClient, APIRequestFactory from rest_framework.test import APIClient, APIRequestFactory
@ -1433,3 +1441,46 @@ def test_schema_handles_exception():
response.render() response.render()
assert response.status_code == 403 assert response.status_code == 403
assert b"You do not have permission to perform this action." in response.content 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()