From dbebe867b46d76c80b71afbbf6ed97138ac65b3d Mon Sep 17 00:00:00 2001 From: dorian-adams Date: Thu, 24 Oct 2024 21:24:20 -0400 Subject: [PATCH 1/2] BREAK: Drop Support for python2 Closes #62 --- CONTRIBUTING.md | 1 - django_check_seo/apps.py | 2 - django_check_seo/checks/site.py | 2 +- .../checks_list/check_description.py | 2 - django_check_seo/checks_list/check_h1.py | 3 - django_check_seo/checks_list/check_h2.py | 3 - .../checks_list/check_keyword_url.py | 11 +-- django_check_seo/checks_list/launch_checks.py | 26 +------ launch_tests.sh | 76 +++---------------- tests/test_content_words_number.py | 3 +- tests/test_description.py | 10 +-- tests/test_h1.py | 12 +-- tests/test_h2.py | 17 ++--- tests/test_images.py | 5 +- tests/test_keyword_present_first_paragraph.py | 21 +++-- tests/test_keyword_url.py | 3 - tests/test_keywords.py | 3 +- tests/test_links.py | 8 +- tests/test_title.py | 13 ++-- tests/test_url.py | 3 +- 20 files changed, 59 insertions(+), 165 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c21c54f..ffd7b7c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,6 @@ You can help by picking an issue, or choosing to add a new test/feature (create 2. Install pre-commit & unit tests dependencies. ```bash python3 -m pip install pre-commit python3-venv - python2 -m pip install virtualenv ``` 3. Install pre-commit hooks. diff --git a/django_check_seo/apps.py b/django_check_seo/apps.py index 8be5c71..985b666 100644 --- a/django_check_seo/apps.py +++ b/django_check_seo/apps.py @@ -1,5 +1,3 @@ -# -*- coding:utf-8 -*- - # Third party from django.apps import AppConfig diff --git a/django_check_seo/checks/site.py b/django_check_seo/checks/site.py index ae79ae1..9f0e4b2 100644 --- a/django_check_seo/checks/site.py +++ b/django_check_seo/checks/site.py @@ -33,7 +33,7 @@ def __init__(self, soup, full_url): if settings.DJANGO_CHECK_SEO_EXCLUDE_CONTENT != "": # iterate through each body (should be only 1) for body in self.content: - # and remove selecte blocks + # and remove selected blocks for node in body.select(settings.DJANGO_CHECK_SEO_EXCLUDE_CONTENT): node.extract() diff --git a/django_check_seo/checks_list/check_description.py b/django_check_seo/checks_list/check_description.py index 68370bb..1fb9e00 100644 --- a/django_check_seo/checks_list/check_description.py +++ b/django_check_seo/checks_list/check_description.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - # Standard Library import re diff --git a/django_check_seo/checks_list/check_h1.py b/django_check_seo/checks_list/check_h1.py index 98131b2..af0283d 100644 --- a/django_check_seo/checks_list/check_h1.py +++ b/django_check_seo/checks_list/check_h1.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - # Standard Library import re diff --git a/django_check_seo/checks_list/check_h2.py b/django_check_seo/checks_list/check_h2.py index 26a514a..05dee1f 100644 --- a/django_check_seo/checks_list/check_h2.py +++ b/django_check_seo/checks_list/check_h2.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - # Standard Library import re diff --git a/django_check_seo/checks_list/check_keyword_url.py b/django_check_seo/checks_list/check_keyword_url.py index 5095f95..25cc1a9 100644 --- a/django_check_seo/checks_list/check_keyword_url.py +++ b/django_check_seo/checks_list/check_keyword_url.py @@ -1,9 +1,6 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - # Standard Library import re -import sys +from urllib.parse import urlparse # pragma: no cover import unidecode from django.conf import settings @@ -14,12 +11,6 @@ # Local application / specific library imports from ..checks import custom_list -# hacky trick to add python2 compatibility to a python3 project after python2 eol -if sys.version_info.major == 2: - from urlparse import urlparse # pragma: no cover -else: - from urllib.parse import urlparse # pragma: no cover - def importance(): """Scripts with higher importance will be executed first. diff --git a/django_check_seo/checks_list/launch_checks.py b/django_check_seo/checks_list/launch_checks.py index b8dacfb..f8a0122 100644 --- a/django_check_seo/checks_list/launch_checks.py +++ b/django_check_seo/checks_list/launch_checks.py @@ -4,12 +4,6 @@ from . import * # noqa: F403,F401 -# hacky thing aiming to add python2 compatibility after eol of python2 -try: - ModuleNotFoundError -except NameError: - ModuleNotFoundError = ImportError - try: from checks_list import * # noqa: F403,F401 @@ -28,27 +22,11 @@ def launch_checks(site): modules_order = [] - # hacky trick to add python2 compatibility to a python3 project after python2 eol - python_2_compatibility_array = [ - "django_check_seo.checks_list.launch_checks", - "django_check_seo.checks_list.glob", - "django_check_seo.checks_list.re", - "django_check_seo.checks_list.bs4", - "django_check_seo.checks_list.sys", - "django_check_seo.checks_list.os", - "django_check_seo.checks_list.importlib", - "django_check_seo.checks_list.urlparse", - "django_check_seo.checks_list.django", - "django_check_seo.checks_list.unidecode", - "django_check_seo.checks_list.__future__", - ] + # TODO: CHECK AND VERIFY THAT ALL MODULES ARE STILL BEING IMPORTED # only get modules in ...checks.* for module_name in sys.modules: - if ( - "django_check_seo.checks_list." in module_name - and module_name not in python_2_compatibility_array - ) or (module_name.startswith("checks_list.")): + if module_name.startswith("checks_list."): module = importlib.import_module(module_name) get_module_order = getattr(module, "importance") diff --git a/launch_tests.sh b/launch_tests.sh index 024f3ab..880558c 100755 --- a/launch_tests.sh +++ b/launch_tests.sh @@ -2,16 +2,12 @@ # django-check-seo super test-launching script # -# requires python3-venv & python2 virtualenv +# requires python3-venv # # Usage: -# ./launch_tests.sh activate venv2 & venv3 (or create them & activate them), -# launch tests, deactivate venv2 & venv3 -# ./launch_tests.sh 2 activate venv2 (or create it & activate it), +# ./launch_tests.sh activate venv2 (or create it & activate it), # launch tests, deactivate venv2 -# ./launch_tests.sh 3 activate venv3 (or create it & activate it), -# launch tests, deactivate venv3 -# ./launch_tests.sh remove remove folders "venv2" & "venv3" +# ./launch_tests.sh remove remove folders for "venv2" # ./launch_tests.sh help display this text function remove { @@ -27,17 +23,6 @@ function remove { echo -e "\e[1;32m✅ nothing to remove\e[0m" fi - if [[ -d "venv3" ]]; then - - echo -e "\e[1;32m✅ test venv3 found\e[0m" - echo -e "\e[2m➡ removing venv3...\e[0m" - rm -r venv3 - echo -e "\e[1;32m✅ test venv3 removed successfully\e[0m" - else - echo -e "\e[1;31m❌ test venv3 not found\e[0m" - echo -e "\e[1;32m✅ nothing to remove\e[0m" - fi - } function display_help { @@ -45,10 +30,8 @@ function display_help { echo -e "django-check-seo super test-launching script" echo echo -e "Usage:" - echo -e " ./launch_tests.sh \e[2mactivate venv2 & venv3 (or create them & activate them), launch tests, deactivate venv2 & venv3\e[0m" - echo -e " ./launch_tests.sh 2 \e[2mactivate venv2 (or create it & activate it), launch tests, deactivate venv2\e[0m" - echo -e " ./launch_tests.sh 3 \e[2mactivate venv3 (or create it & activate it), launch tests, deactivate venv3\e[0m" - echo -e " ./launch_tests.sh remove \e[2mremove folders \"venv2\" & \"venv3\"\e[0m" + echo -e " ./launch_tests.sh \e[2mactivate venv2 & (or create it & activate it), launch tests, deactivate venv2\e[0m" + echo -e " ./launch_tests.sh remove \e[2mremove folders \"venv2\"\e[0m" echo -e " ./launch_tests.sh help \e[2mdisplay this text\e[0m" } @@ -63,29 +46,11 @@ function create_and_launch_venv2 { } -function create_and_launch_venv3 { - - if [[ -d "venv3" ]]; then - launch_venv3_tests - else - create_venv3 - fi - -} - function launch_venv2_tests { echo -e "\e[1;32m✅ test venv2 found\e[0m" echo -e "\e[2m➡ launching tests...\e[0m" - . venv2/bin/activate && python2 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate - -} - -function launch_venv3_tests { - - echo -e "\e[1;32m✅ test venv3 found\e[0m" - echo -e "\e[2m➡ launching tests...\e[0m" - . venv3/bin/activate && python3 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate + . venv2/bin/activate && python3 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate } @@ -93,21 +58,10 @@ function create_venv2 { echo -e "\e[1;31m❌ test venv2 not found\e[0m" echo -e "\e[2m➡ creating venv2...\e[0m" - python2 -m virtualenv -p python2.7 venv2 1>/dev/null && . venv2/bin/activate && python2 -m pip install "django<3" bs4 lxml "easy-thumbnails==2.3" "djangocms-page-meta==0.8.5" requests pytest pytest-django pytest-cov 1>/dev/null && deactivate + python3 -m venv venv2 1>/dev/null && . venv2/bin/activate && python3 -m pip install django bs4 lxml djangocms-page-meta requests Unidecode pytest pytest-django pytest-cov 1>/dev/null && deactivate echo -e "\e[1;32m✅ venv2 created successfully\e[0m" echo -e "\e[2m➡ launching tests...\e[0m" - . venv2/bin/activate && python2 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate - -} - -function create_venv3 { - - echo -e "\e[1;31m❌ test venv3 not found\e[0m" - echo -e "\e[2m➡ creating venv3...\e[0m" - python3 -m venv venv3 1>/dev/null && . venv3/bin/activate && python3 -m pip install django bs4 lxml djangocms-page-meta requests pytest pytest-django pytest-cov 1>/dev/null && deactivate - echo -e "\e[1;32m✅ venv3 created successfully\e[0m" - echo -e "\e[2m➡ launching tests...\e[0m" - . venv3/bin/activate && python3 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate + . venv2/bin/activate && python3 -m pytest -s --cov-config=.coveragerc --cov=django_check_seo --cov-report term-missing && deactivate } @@ -124,15 +78,9 @@ elif [[ $1 == "help" ]]; then exit 1 -elif [[ $1 == "2" ]]; then - - create_and_launch_venv2 - - exit $? - elif [[ $1 == "3" ]]; then - create_and_launch_venv3 + create_and_launch_venv2 exit $? @@ -153,11 +101,7 @@ create_and_launch_venv2 exit1=$? -create_and_launch_venv3 - -exit2=$? - -if [ "$exit1" -eq "0" ] && [ "$exit2" -eq "0" ] +if [ "$exit1" -eq "0" ] then exit 0 else diff --git a/tests/test_content_words_number.py b/tests/test_content_words_number.py index 7e56328..a505aa2 100644 --- a/tests/test_content_words_number.py +++ b/tests/test_content_words_number.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. import re from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ diff --git a/tests/test_description.py b/tests/test_description.py index 77a46b2..b00c525 100644 --- a/tests/test_description.py +++ b/tests/test_description.py @@ -1,8 +1,7 @@ -# coding: utf-8 - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -145,8 +144,7 @@ def test_description_1_nokw_too_long_161(): def test_description_1_kw(): - from django_check_seo.checks_list import check_keywords - from django_check_seo.checks_list import check_description + from django_check_seo.checks_list import check_description, check_keywords site = init() @@ -167,8 +165,7 @@ def test_description_1_kw(): def test_description_1_kws(): - from django_check_seo.checks_list import check_keywords - from django_check_seo.checks_list import check_description + from django_check_seo.checks_list import check_description, check_keywords site = init() @@ -214,6 +211,7 @@ def test_description_1_length(): def test_description_2(): import copy + from django_check_seo.checks_list import check_description site = init() diff --git a/tests/test_h1.py b/tests/test_h1.py index 3604a68..d974fdf 100644 --- a/tests/test_h1.py +++ b/tests/test_h1.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -122,8 +121,7 @@ def test_h1_1_nokw_image(): def test_h1_1_kw(): - from django_check_seo.checks_list import check_h1 - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_h1, check_keywords site = init() @@ -144,8 +142,7 @@ def test_h1_1_kw(): def test_h1_1_kws(): - from django_check_seo.checks_list import check_h1 - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_h1, check_keywords site = init() site.soup.find("h1").string = "Title of the page description" @@ -169,8 +166,7 @@ def test_h1_1_kws(): def test_h1_1_kw_strange1(): - from django_check_seo.checks_list import check_h1 - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_h1, check_keywords site = init() site.soup.select('meta[name="keywords"]')[0]["content"] = "@letics" diff --git a/tests/test_h2.py b/tests/test_h2.py index aecea5a..a14f382 100644 --- a/tests/test_h2.py +++ b/tests/test_h2.py @@ -1,8 +1,7 @@ -# coding: utf-8 - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -118,8 +117,7 @@ def test_h2_1_nokw_image(): def test_h2_1_kw(): - from django_check_seo.checks_list import check_h2 - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_h2, check_keywords site = init() @@ -142,8 +140,8 @@ def test_h2_1_kw(): def test_h2_2_kw(): import copy - from django_check_seo.checks_list import check_h2 - from django_check_seo.checks_list import check_keywords + + from django_check_seo.checks_list import check_h2, check_keywords site = init() @@ -169,8 +167,7 @@ def test_h2_2_kw(): def test_h2_1_kws(): - from django_check_seo.checks_list import check_h2 - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_h2, check_keywords site = init() @@ -191,8 +188,8 @@ def test_h2_1_kws(): def test_h2_2_kws(): import copy - from django_check_seo.checks_list import check_h2 - from django_check_seo.checks_list import check_keywords + + from django_check_seo.checks_list import check_h2, check_keywords site = init() diff --git a/tests/test_images.py b/tests/test_images.py index 1fff575..9a94b8b 100644 --- a/tests/test_images.py +++ b/tests/test_images.py @@ -1,8 +1,7 @@ -# coding: utf-8 - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -58,6 +57,7 @@ def test_image_okay(): def test_images_okay(): import copy + from django_check_seo.checks_list import check_images site = init() @@ -98,6 +98,7 @@ def test_image_missing(): def test_images_missing(): import copy + from django_check_seo.checks_list import check_images site = init() diff --git a/tests/test_keyword_present_first_paragraph.py b/tests/test_keyword_present_first_paragraph.py index 7c99d43..408961b 100644 --- a/tests/test_keyword_present_first_paragraph.py +++ b/tests/test_keyword_present_first_paragraph.py @@ -1,10 +1,9 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. import re from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -61,8 +60,10 @@ def test_url_importance(): def test_keyword_present_first_paragraph_kw(): - from django_check_seo.checks_list import check_keywords - from django_check_seo.checks_list import keyword_present_first_paragraph + from django_check_seo.checks_list import ( + check_keywords, + keyword_present_first_paragraph, + ) site = init() check_keywords.run(site) @@ -83,8 +84,10 @@ def test_keyword_present_first_paragraph_kw(): def test_keyword_present_first_paragraph_nokw(): - from django_check_seo.checks_list import check_keywords - from django_check_seo.checks_list import keyword_present_first_paragraph + from django_check_seo.checks_list import ( + check_keywords, + keyword_present_first_paragraph, + ) site = init() site.soup.find("p").string = "There is no keyword inside first 50 words." @@ -102,8 +105,10 @@ def test_keyword_present_first_paragraph_nokw(): def test_keyword_present_first_paragraph_kws(): - from django_check_seo.checks_list import check_keywords - from django_check_seo.checks_list import keyword_present_first_paragraph + from django_check_seo.checks_list import ( + check_keywords, + keyword_present_first_paragraph, + ) site = init() site.soup.find( diff --git a/tests/test_keyword_url.py b/tests/test_keyword_url.py index 4ae2217..84ccf20 100644 --- a/tests/test_keyword_url.py +++ b/tests/test_keyword_url.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - from bs4 import BeautifulSoup from django_check_seo.checks import site diff --git a/tests/test_keywords.py b/tests/test_keywords.py index c288238..fba63ec 100644 --- a/tests/test_keywords.py +++ b/tests/test_keywords.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ diff --git a/tests/test_links.py b/tests/test_links.py index d0b47fe..711e5c8 100644 --- a/tests/test_links.py +++ b/tests/test_links.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -53,6 +52,7 @@ def test_link_importance(): def test_links_internal_noexternal(monkeypatch): from django.contrib.sites.models import Site + from django_check_seo.checks_list import check_links site = init() @@ -84,6 +84,7 @@ def test_links_internal_noexternal(monkeypatch): def test_links_nointernal_external(monkeypatch): from django.contrib.sites.models import Site + from django_check_seo.checks_list import check_links site = init() @@ -118,6 +119,7 @@ def test_links_nointernal_external(monkeypatch): def test_links_internal_img(monkeypatch): from django.contrib.sites.models import Site + from django_check_seo.checks_list import check_links site = init() @@ -143,6 +145,7 @@ def test_links_internal_img(monkeypatch): def test_links_internal_img_no_alt_tag(monkeypatch): from django.contrib.sites.models import Site + from django_check_seo.checks_list import check_links site = init() @@ -168,6 +171,7 @@ def test_links_internal_img_no_alt_tag(monkeypatch): def test_links_internal_empty(monkeypatch): from django.contrib.sites.models import Site + from django_check_seo.checks_list import check_links site = init() diff --git a/tests/test_title.py b/tests/test_title.py index 623db79..d756add 100644 --- a/tests/test_title.py +++ b/tests/test_title.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ @@ -125,6 +124,7 @@ def test_title_okay(): def test_titles(): import copy + from django_check_seo.checks_list import check_title site = init() @@ -144,8 +144,7 @@ def test_titles(): def test_title_nokw(): - from django_check_seo.checks_list import check_title - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_keywords, check_title site = init() check_keywords.run(site) @@ -166,8 +165,7 @@ def test_title_nokw(): def test_title_kw(): - from django_check_seo.checks_list import check_title - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_keywords, check_title site = init() check_keywords.run(site) @@ -187,8 +185,7 @@ def test_title_kw(): def test_title_kws(): - from django_check_seo.checks_list import check_title - from django_check_seo.checks_list import check_keywords + from django_check_seo.checks_list import check_keywords, check_title site = init() check_keywords.run(site) diff --git a/tests/test_url.py b/tests/test_url.py index d3e7c13..61b847c 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -1,8 +1,7 @@ -# -*- coding: utf-8 -*- - # Use ./launch_tests.sh to launch these tests. from bs4 import BeautifulSoup + from django_check_seo.checks import site html_content = """ From 2ecfb8e8661c1c05a96308e88be19c1a0d36a0c8 Mon Sep 17 00:00:00 2001 From: dorian-adams Date: Fri, 25 Oct 2024 02:52:26 -0400 Subject: [PATCH 2/2] Update setup for Python3+ Support Add `python_requires=">=3.7" to setup.py so that pip can automatically install a compatible version of the app for users who no longer meet the new requirements. --- setup.cfg | 4 ---- setup.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/setup.cfg b/setup.cfg index e6bcefe..e619f81 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,10 +13,6 @@ classifiers = Intended Audience :: Developers License :: OSI Approved :: GNU General Public License v3 (GPLv3) Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Topic :: Internet :: WWW/HTTP diff --git a/setup.py b/setup.py index 607a8c5..7079b58 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ # Third party from setuptools import setup -setup() +setup(python_requires=">=3.7")