diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 48b6e7202b..796bc3b330 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,8 +14,6 @@ jobs: strategy: matrix: python-version: - - '3.6' - - '3.7' - '3.8' - '3.9' - '3.10' @@ -36,18 +34,9 @@ jobs: - name: Install dependencies run: python -m pip install --upgrade codecov tox - - name: Install tox-py - if: ${{ matrix.python-version == '3.6' }} - run: python -m pip install --upgrade tox-py - - name: Run tox targets for ${{ matrix.python-version }} - if: ${{ matrix.python-version != '3.6' }} run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .) - - name: Run tox targets for ${{ matrix.python-version }} - if: ${{ matrix.python-version == '3.6' }} - run: tox --py current - - name: Run extra tox targets if: ${{ matrix.python-version == '3.9' }} run: | diff --git a/README.md b/README.md index c2975a418f..b55c525014 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ There is a live example API for testing purposes, [available here][sandbox]. # Requirements -* Python 3.6+ +* Python 3.8+ * Django 4.2, 4.1, 4.0, 3.2, 3.1, 3.0 We **highly recommend** and only officially support the latest patch release of diff --git a/docs/index.md b/docs/index.md index 81a5563133..406596367a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -85,7 +85,7 @@ continued development by **[signing up for a paid plan][funding]**. REST framework requires the following: -* Python (3.6, 3.7, 3.8, 3.9, 3.10, 3.11) +* Python (3.8, 3.9, 3.10, 3.11) * Django (3.0, 3.1, 3.2, 4.0, 4.1, 4.2) We **highly recommend** and only officially support the latest patch release of diff --git a/setup.py b/setup.py index 6afd5e05e7..a1d74529f2 100755 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ from setuptools import find_packages, setup CURRENT_PYTHON = sys.version_info[:2] -REQUIRED_PYTHON = (3, 6) +REQUIRED_PYTHON = (3, 8) # This check and everything above must remain compatible with Python 2.7. if CURRENT_PYTHON < REQUIRED_PYTHON: @@ -84,7 +84,7 @@ def get_version(package): packages=find_packages(exclude=['tests*']), include_package_data=True, install_requires=["django>=3.0", 'backports.zoneinfo;python_version<"3.9"'], - python_requires=">=3.6", + python_requires=">=3.8", zip_safe=False, classifiers=[ 'Development Status :: 5 - Production/Stable', @@ -101,8 +101,6 @@ def get_version(package): 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', diff --git a/tests/test_fields.py b/tests/test_fields.py index 7006d473c2..54d2d284a3 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -640,10 +640,6 @@ def test_parent_binding(self): class TestTyping(TestCase): - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_field_is_subscriptable(self): assert serializers.Field is serializers.Field["foo"] diff --git a/tests/test_generics.py b/tests/test_generics.py index 9990389c94..8748e8f170 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -1,5 +1,3 @@ -import sys - import pytest from django.db import models from django.http import Http404 @@ -703,23 +701,11 @@ def list(self, request): class TestTyping(TestCase): - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_genericview_is_subscriptable(self): assert generics.GenericAPIView is generics.GenericAPIView["foo"] - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_listview_is_subscriptable(self): assert generics.ListAPIView is generics.ListAPIView["foo"] - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_instanceview_is_subscriptable(self): assert generics.RetrieveAPIView is generics.RetrieveAPIView["foo"] diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 20d0319fcb..b48c9f9036 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -8,7 +8,6 @@ import datetime import decimal import json # noqa -import sys import tempfile import django @@ -398,10 +397,6 @@ class Meta: fields = '__all__' expected = dedent(""" - TestSerializer(): - id = IntegerField(label='ID', read_only=True) - duration_field = DurationField(max_value=datetime.timedelta(3), min_value=datetime.timedelta(1)) - """) if sys.version_info < (3, 7) else dedent(""" TestSerializer(): id = IntegerField(label='ID', read_only=True) duration_field = DurationField(max_value=datetime.timedelta(days=3), min_value=datetime.timedelta(days=1)) diff --git a/tests/test_request.py b/tests/test_request.py index e37aa7dda1..7fd876622c 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -3,7 +3,6 @@ """ import copy import os.path -import sys import tempfile import pytest @@ -356,9 +355,5 @@ def test_deepcopy_works(self): class TestTyping(TestCase): - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_request_is_subscriptable(self): assert Request is Request["foo"] diff --git a/tests/test_response.py b/tests/test_response.py index cab19a1eb8..a5b8e8398b 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,6 +1,3 @@ -import sys - -import pytest from django.test import TestCase, override_settings from django.urls import include, path, re_path @@ -289,9 +286,5 @@ def test_form_has_label_and_help_text(self): class TestTyping(TestCase): - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_response_is_subscriptable(self): assert Response is Response["foo"] diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 39d9238ef9..92bf7fb458 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -206,10 +206,6 @@ class ExampleSerializer(serializers.Serializer): exceptions.ErrorDetail(string='Raised error', code='invalid') ]} - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_serializer_is_subscriptable(self): assert serializers.Serializer is serializers.Serializer["foo"] diff --git a/tests/test_serializer_lists.py b/tests/test_serializer_lists.py index 4070de7a51..42ebf4771e 100644 --- a/tests/test_serializer_lists.py +++ b/tests/test_serializer_lists.py @@ -1,5 +1,3 @@ -import sys - import pytest from django.http import QueryDict from django.utils.datastructures import MultiValueDict @@ -60,10 +58,6 @@ def test_validate_html_input(self): assert serializer.is_valid() assert serializer.validated_data == expected_output - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason="subscriptable classes requires Python 3.7 or higher", - ) def test_list_serializer_is_subscriptable(self): assert serializers.ListSerializer is serializers.ListSerializer["foo"] diff --git a/tox.ini b/tox.ini index 2b8733d7df..15309ed144 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist = - {py36,py37,py38,py39}-django30 - {py36,py37,py38,py39}-django31 - {py36,py37,py38,py39,py310}-django32 + {py38,py39}-django30 + {py38,py39}-django31 + {py38,py39,py310}-django32 {py38,py39,py310}-{django40,django41,django42,djangomain} {py311}-{django41,django42,djangomain} base