Skip to content

Commit 3b8337e

Browse files
authored
Chore: set minimal python version to 3.10 (#286)
Since some advanced types operations introduced in mkdocs>=1.5 are not entirely supported by Python 3.8 and 3.9, let's switch to 3.10 as minimal version: Logs with failing error in #285 (https://github.com/Guts/mkdocs-rss-plugin/actions/runs/9450849461/job/26030426819?pr=285): > FAILED tests/test_build.py::TestBuildRss::test_simple_build_custom_output_basename - TypeError: Subscripted generics cannot be used with class and instance checks ```python /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/plugins.py:96: in load_config return self.config.validate() /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/base.py:231: in validate run_failed, run_warnings = self._validate() /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/base.py:188: in _validate self[key] = config_option.validate(value) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/base.py:55: in validate return self.run_validation(value) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/config_options.py:110: in run_validation failed, warnings = config.validate() /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/base.py:231: in validate run_failed, run_warnings = self._validate() /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/base.py:188: in _validate self[key] = config_option.validate(value) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/config_options.py:186: in validate return self.run_validation(value) /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/mkdocs/config/config_options.py:344: in run_validation if not isinstance(value, self._type): /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/typing.py:769: in __instancecheck__ return self.__subclasscheck__(type(obj)) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ```
2 parents a7e02a5 + 8ec6164 commit 3b8337e

File tree

9 files changed

+66
-62
lines changed

9 files changed

+66
-62
lines changed

.github/workflows/lint-and-tests.yml

-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ jobs:
2222
fail-fast: false
2323
matrix:
2424
python-version:
25-
- "3.8"
26-
- "3.9"
2725
- "3.10"
2826
- "3.11"
2927
- "3.12"

.pre-commit-config.yaml

+22-12
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
# See https://pre-commit.com for more information
2-
# See https://pre-commit.com/hooks.html for more hooks
3-
exclude: "node_modules|migrations|.venv|.direnv|tests/dev/|tests/fixtures/"
1+
exclude: ".venv|.direnv|tests/dev/|tests/fixtures/"
42
fail_fast: false
53
repos:
64
- repo: https://github.com/pre-commit/pre-commit-hooks
75
rev: v4.6.0
86
hooks:
97
- id: check-added-large-files
10-
args: ["--maxkb=500"]
8+
args:
9+
- --maxkb=500
1110
- id: check-ast
1211
- id: check-builtin-literals
1312
- id: check-case-conflict
1413
- id: check-json
1514
- id: check-toml
1615
- id: check-yaml
17-
args: [--unsafe]
16+
args:
17+
- --unsafe
1818
- id: detect-private-key
1919
- id: end-of-file-fixer
2020
- id: fix-byte-order-marker
2121
- id: fix-encoding-pragma
22-
args: [--remove]
22+
args:
23+
- --remove
2324
- id: trailing-whitespace
24-
args: [--markdown-linebreak-ext=md]
25+
args:
26+
- --markdown-linebreak-ext=md
2527

2628
- repo: https://github.com/pre-commit/pygrep-hooks
2729
rev: v1.10.0
@@ -33,32 +35,40 @@ repos:
3335
hooks:
3436
- id: pyupgrade
3537
args:
36-
- "--py38-plus"
38+
- "--py310-plus"
3739

3840
- repo: https://github.com/astral-sh/ruff-pre-commit
3941
rev: "v0.4.7"
4042
hooks:
4143
- id: ruff
42-
args: ["--fix-only", "--target-version=py38"]
44+
args:
45+
- --fix-only
46+
- --target-version=py310
4347

4448
- repo: https://github.com/pycqa/isort
4549
rev: 5.13.2
4650
hooks:
4751
- id: isort
48-
args: ["--profile", "black", "--filter-files"]
52+
args:
53+
- --profile
54+
- black
55+
- --filter-files
4956

5057
- repo: https://github.com/psf/black
5158
rev: 24.4.2
5259
hooks:
5360
- id: black
54-
args: ["--target-version=py38"]
61+
args:
62+
- --target-version=py310
5563

5664
- repo: https://github.com/pycqa/flake8
5765
rev: 7.0.0
5866
hooks:
5967
- id: flake8
6068
language: python
61-
args: ["--config=setup.cfg", "--select=E9,F63,F7,F82"]
69+
args:
70+
- --config=setup.cfg
71+
- --select=E9,F63,F7,F82
6272

6373
ci:
6474
autofix_prs: true

mkdocs_rss_plugin/integrations/theme_material_social_plugin.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
# standard library
88
from pathlib import Path
9-
from typing import Optional
109

1110
# 3rd party
1211
from mkdocs.config.config_options import Config
@@ -174,7 +173,7 @@ def get_social_cards_dir(self, mkdocs_config: Config) -> str:
174173
return social_plugin_cfg.config.cards_dir
175174

176175
def get_social_card_build_path_for_page(
177-
self, mkdocs_page: Page, mkdocs_site_dir: Optional[str] = None
176+
self, mkdocs_page: Page, mkdocs_site_dir: str | None = None
178177
) -> Path:
179178
"""Get social card URL for a specific page in documentation.
180179
@@ -197,7 +196,7 @@ def get_social_card_build_path_for_page(
197196
def get_social_card_url_for_page(
198197
self,
199198
mkdocs_page: Page,
200-
mkdocs_site_url: Optional[str] = None,
199+
mkdocs_site_url: str | None = None,
201200
) -> str:
202201
"""Get social card URL for a specific page in documentation.
203202

mkdocs_rss_plugin/models.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# standard
88
from datetime import datetime
99
from pathlib import Path
10-
from typing import NamedTuple, Optional
10+
from typing import NamedTuple
1111

1212

1313
# ############################################################################
@@ -16,14 +16,14 @@
1616
class PageInformation(NamedTuple):
1717
"""Data type to set and get page information in order to produce the RSS feed."""
1818

19-
abs_path: Optional[Path] = None
20-
categories: Optional[list] = None
21-
authors: Optional[tuple] = None
22-
created: Optional[datetime] = None
23-
description: Optional[str] = None
24-
guid: Optional[str] = None
25-
image: Optional[str] = None
26-
title: Optional[str] = None
27-
updated: Optional[datetime] = None
28-
url_comments: Optional[str] = None
29-
url_full: Optional[str] = None
19+
abs_path: Path | None = None
20+
categories: list | None = None
21+
authors: tuple | None = None
22+
created: datetime | None = None
23+
description: str | None = None
24+
guid: str | None = None
25+
image: str | None = None
26+
title: str | None = None
27+
updated: datetime | None = None
28+
url_comments: str | None = None
29+
url_full: str | None = None

mkdocs_rss_plugin/plugin.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from email.utils import formatdate
1212
from pathlib import Path
1313
from re import compile
14-
from typing import Optional
1514

1615
# 3rd party
1716
from jinja2 import Environment, FileSystemLoader, select_autoescape
@@ -58,9 +57,9 @@ def __init__(self):
5857
"""Instanciation."""
5958
# dates source
6059
self.src_date_created = self.src_date_updated = "git"
61-
self.meta_datetime_format: Optional[str] = None
60+
self.meta_datetime_format: str | None = None
6261
self.meta_default_timezone: str = "UTC"
63-
self.meta_default_time: Optional[datetime.time] = None
62+
self.meta_default_time: datetime.time | None = None
6463
# pages storage
6564
self.pages_to_filter: list = []
6665
# prepare output feeds
@@ -208,7 +207,7 @@ def on_config(self, config: config_options.Config) -> dict:
208207
@event_priority(priority=-75)
209208
def on_page_content(
210209
self, html: str, page: Page, config: config_options.Config, files
211-
) -> Optional[str]:
210+
) -> str | None:
212211
"""The page_content event is called after the Markdown text is rendered
213212
to HTML (but before being passed to a template) and can be used to alter
214213
the HTML body of the page.
@@ -297,7 +296,7 @@ def on_page_content(
297296
)
298297
)
299298

300-
def on_post_build(self, config: config_options.Config) -> Optional[dict]:
299+
def on_post_build(self, config: config_options.Config) -> dict | None:
301300
"""The post_build event does not alter any variables. \
302301
Use this event to call post-build scripts. \
303302
See: <https://www.mkdocs.org/user-guide/plugins/#on_post_build>

mkdocs_rss_plugin/util.py

+13-16
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
# standard library
88
import logging
99
import ssl
10-
import sys
10+
from collections.abc import Iterable
1111
from datetime import date, datetime
1212
from email.utils import format_datetime
1313
from mimetypes import guess_type
1414
from pathlib import Path
15-
from typing import Any, Iterable, Optional, Tuple, Union
15+
from typing import Any
1616
from urllib import request
1717
from urllib.error import HTTPError, URLError
1818
from urllib.parse import urlencode, urlparse, urlunparse
@@ -33,10 +33,7 @@
3333
)
3434

3535
# conditional imports
36-
if sys.version_info < (3, 9):
37-
from mkdocs_rss_plugin.timezoner_pre39 import set_datetime_zoneinfo
38-
else:
39-
from mkdocs_rss_plugin.timezoner_py39 import set_datetime_zoneinfo
36+
from mkdocs_rss_plugin.timezoner_py39 import set_datetime_zoneinfo
4037

4138
# ############################################################################
4239
# ########## Globals #############
@@ -58,9 +55,9 @@ def __init__(
5855
self,
5956
path: str = ".",
6057
use_git: bool = True,
61-
integration_material_social_cards: Optional[
58+
integration_material_social_cards: None | (
6259
IntegrationMaterialSocialCards
63-
] = None,
60+
) = None,
6461
):
6562
"""Class hosting the plugin logic.
6663
@@ -139,7 +136,7 @@ def build_url(self, base_url: str, path: str, args_dict: dict = None) -> str:
139136
url_parts[4] = urlencode(args_dict)
140137
return urlunparse(url_parts)
141138

142-
def get_value_from_dot_key(self, data: dict, dot_key: Union[str, bool]) -> Any:
139+
def get_value_from_dot_key(self, data: dict, dot_key: str | bool) -> Any:
143140
"""
144141
Retrieves a value from a dictionary using a dot notation key.
145142
@@ -168,8 +165,8 @@ def get_file_dates(
168165
source_date_update: str = "git",
169166
meta_datetime_format: str = "%Y-%m-%d %H:%M",
170167
meta_default_timezone: str = "UTC",
171-
meta_default_time: Optional[datetime] = None,
172-
) -> Tuple[datetime, datetime]:
168+
meta_default_time: datetime | None = None,
169+
) -> tuple[datetime, datetime]:
173170
"""Extract creation and update dates from page metadata (yaml frontmatter) or
174171
git log for given file.
175172
@@ -325,7 +322,7 @@ def get_file_dates(
325322
get_build_datetime(),
326323
)
327324

328-
def get_authors_from_meta(self, in_page: Page) -> Optional[Tuple[str]]:
325+
def get_authors_from_meta(self, in_page: Page) -> tuple[str] | None:
329326
"""Returns authors from page meta. It handles 'author' and 'authors' for keys, \
330327
str and iterable as values types.
331328
@@ -508,7 +505,7 @@ def get_description_or_abstract(
508505
)
509506
return ""
510507

511-
def get_image(self, in_page: Page, base_url: str) -> Optional[Tuple[str, str, int]]:
508+
def get_image(self, in_page: Page, base_url: str) -> tuple[str, str, int] | None:
512509
"""Get page's image from page meta or social cards and returns properties.
513510
514511
Args:
@@ -610,7 +607,7 @@ def get_remote_image_length(
610607
http_method: str = "HEAD",
611608
attempt: int = 0,
612609
ssl_context: ssl.SSLContext = None,
613-
) -> Optional[int]:
610+
) -> int | None:
614611
"""Retrieve length for remote images (starting with 'http' \
615612
in meta.image or meta.illustration). \
616613
It tries to perform a HEAD request and get the length from the headers. \
@@ -662,7 +659,7 @@ def get_remote_image_length(
662659
return int(img_length)
663660

664661
@staticmethod
665-
def get_site_url(mkdocs_config: Config) -> Optional[str]:
662+
def get_site_url(mkdocs_config: Config) -> str | None:
666663
"""Extract site URL from MkDocs configuration and enforce the behavior to ensure \
667664
returning a str with length > 0 or None. If exists, it adds an ending slash.
668665
@@ -688,7 +685,7 @@ def get_site_url(mkdocs_config: Config) -> Optional[str]:
688685

689686
return site_url
690687

691-
def guess_locale(self, mkdocs_config: Config) -> Optional[str]:
688+
def guess_locale(self, mkdocs_config: Config) -> str | None:
692689
"""Extract language code from MkDocs or Theme configuration.
693690
694691
:param mkdocs_config: configuration object

setup.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
# standard library
88
from pathlib import Path
9-
from typing import List, Union
109

1110
# 3rd party
1211
from setuptools import find_packages, setup
@@ -26,7 +25,7 @@
2625
# ##################################
2726

2827

29-
def load_requirements(requirements_files: Union[Path, List[Path]]) -> list:
28+
def load_requirements(requirements_files: Path | list[Path]) -> list:
3029
"""Helper to load requirements list from a path or a list of paths.
3130
3231
Args:
@@ -79,7 +78,7 @@ def load_requirements(requirements_files: Union[Path, List[Path]]) -> list:
7978
# run
8079
entry_points={"mkdocs.plugins": ["rss = mkdocs_rss_plugin.plugin:GitRssPlugin"]},
8180
# dependencies
82-
python_requires=">=3.8, <4",
81+
python_requires=">=3.10, <4",
8382
extras_require={
8483
# tooling
8584
"dev": load_requirements(HERE / "requirements/development.txt"),
@@ -93,8 +92,6 @@ def load_requirements(requirements_files: Union[Path, List[Path]]) -> list:
9392
"Intended Audience :: Developers",
9493
"Intended Audience :: Information Technology",
9594
"Programming Language :: Python :: 3",
96-
"Programming Language :: Python :: 3.8",
97-
"Programming Language :: Python :: 3.9",
9895
"Programming Language :: Python :: 3.10",
9996
"Programming Language :: Python :: 3.11",
10097
"Programming Language :: Python :: 3.12",

sonar-project.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ sonar.projectKey=Guts_mkdocs-rss-plugin
66
# only=main
77

88
# Python versions
9-
sonar.python.version=3.8, 3.9, 3.10, 3.11, 3.12
9+
sonar.python.version=3.10, 3.11, 3.12
1010

1111
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
1212
sonar.sources=mkdocs_rss_plugin

tests/test_build.py

+10-6
Original file line numberDiff line numberDiff line change
@@ -699,16 +699,20 @@ def test_json_feed_validation(self):
699699
self.assertIsNone(cli_result.exception)
700700

701701
# created items
702-
with Path(tmpdirname).joinpath(OUTPUT_JSON_FEED_CREATED).open(
703-
"r", encoding="UTF-8"
704-
) as in_json:
702+
with (
703+
Path(tmpdirname)
704+
.joinpath(OUTPUT_JSON_FEED_CREATED)
705+
.open("r", encoding="UTF-8") as in_json
706+
):
705707
json_feed_created_data = json.load(in_json)
706708
jsonfeed.Feed.parse(json_feed_created_data)
707709

708710
# updated items
709-
with Path(tmpdirname).joinpath(OUTPUT_JSON_FEED_UPDATED).open(
710-
"r", encoding="UTF-8"
711-
) as in_json:
711+
with (
712+
Path(tmpdirname)
713+
.joinpath(OUTPUT_JSON_FEED_UPDATED)
714+
.open("r", encoding="UTF-8") as in_json
715+
):
712716
json_feed_updated_data = json.load(in_json)
713717
jsonfeed.Feed.parse(json_feed_updated_data)
714718

0 commit comments

Comments
 (0)