Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Python 3.13 and drop EOL 3.8 #3435

Merged
merged 3 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ jobs:
strategy:
matrix:
os: [ubuntu, macos, windows]
python: ["3.10", "3.11", "3.12"]
python: ["3.10", "3.11", "3.12", "3.13"]
include:
- os: ubuntu
python: "3.8"
- os: ubuntu
python: "3.9"

Expand Down
12 changes: 6 additions & 6 deletions pelican/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import re
from datetime import timezone
from html import unescape
from typing import Any, Dict, Optional, Set, Tuple
from typing import Any, Optional
from urllib.parse import ParseResult, unquote, urljoin, urlparse, urlunparse

try:
Expand Down Expand Up @@ -47,7 +47,7 @@ class Content:
"""

default_template: Optional[str] = None
mandatory_properties: Tuple[str, ...] = ()
mandatory_properties: tuple[str, ...] = ()

@deprecated_attribute(old="filename", new="source_path", since=(3, 2, 0))
def filename():
Expand All @@ -56,10 +56,10 @@ def filename():
def __init__(
self,
content: str,
metadata: Optional[Dict[str, Any]] = None,
metadata: Optional[dict[str, Any]] = None,
settings: Optional[Settings] = None,
source_path: Optional[str] = None,
context: Optional[Dict[Any, Any]] = None,
context: Optional[dict[Any, Any]] = None,
):
if metadata is None:
metadata = {}
Expand Down Expand Up @@ -226,7 +226,7 @@ def is_valid(self) -> bool:
)

@property
def url_format(self) -> Dict[str, Any]:
def url_format(self) -> dict[str, Any]:
"""Returns the URL, formatted with the proper values"""
metadata = copy.copy(self.metadata)
path = self.metadata.get("path", self.get_relative_source_path())
Expand Down Expand Up @@ -397,7 +397,7 @@ def _update_content(self, content: str, siteurl: str) -> str:
hrefs = self._get_intrasite_link_regex()
return hrefs.sub(lambda m: self._link_replacer(siteurl, m), content)

def get_static_links(self) -> Set[str]:
def get_static_links(self) -> set[str]:
static_links = set()
hrefs = self._get_intrasite_link_regex()
for m in hrefs.finditer(self._content):
Expand Down
8 changes: 4 additions & 4 deletions pelican/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from functools import partial
from itertools import chain, groupby
from operator import attrgetter
from typing import List, Optional, Set
from typing import Optional

from jinja2 import (
BaseLoader,
Expand Down Expand Up @@ -158,8 +158,8 @@ def _include_path(self, path, extensions=None):
return False

def get_files(
self, paths, exclude: Optional[List[str]] = None, extensions=None
) -> Set[str]:
self, paths, exclude: Optional[list[str]] = None, extensions=None
) -> set[str]:
"""Return a list of files to use, based on rules

:param paths: the list pf paths to search (relative to self.path)
Expand Down Expand Up @@ -253,7 +253,7 @@ def __str__(self):
# return the name of the class for logging purposes
return self.__class__.__name__

def _check_disabled_readers(self, paths, exclude: Optional[List[str]]) -> None:
def _check_disabled_readers(self, paths, exclude: Optional[list[str]]) -> None:
"""Log warnings for files that would have been processed by disabled readers."""
for fil in self.get_files(
paths, exclude=exclude, extensions=self.readers.disabled_extensions
Expand Down
6 changes: 3 additions & 3 deletions pelican/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from os.path import isabs
from pathlib import Path
from types import ModuleType
from typing import Any, Dict, Optional
from typing import Any, Optional

from pelican.log import LimitFilter

Expand All @@ -24,7 +24,7 @@ def load_source(name: str, path: str) -> ModuleType:

logger = logging.getLogger(__name__)

Settings = Dict[str, Any]
Settings = dict[str, Any]

DEFAULT_THEME = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "themes", "notmyidea"
Expand Down Expand Up @@ -613,7 +613,7 @@ def configure_settings(settings: Settings) -> Settings:
]:
if key in settings and not isinstance(settings[key], types):
value = settings.pop(key)
logger.warn(
logger.warning(
"Detected misconfigured %s (%s), falling back to the default (%s)",
key,
value,
Expand Down
16 changes: 3 additions & 13 deletions pelican/tests/test_generators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import sys
from shutil import copy, rmtree
from tempfile import mkdtemp
from unittest.mock import MagicMock
Expand Down Expand Up @@ -1528,18 +1527,9 @@ def test_invalid_symlink_is_overwritten(self):
self.generator.generate_context()
self.generator.generate_output(None)
self.assertTrue(os.path.islink(self.endfile))

# os.path.realpath is broken on Windows before python3.8 for symlinks.
# This is a (ugly) workaround.
# see: https://bugs.python.org/issue9949
if os.name == "nt" and sys.version_info < (3, 8):

def get_real_path(path):
return os.readlink(path) if os.path.islink(path) else path
else:
get_real_path = os.path.realpath

self.assertEqual(get_real_path(self.endfile), get_real_path(self.startfile))
self.assertEqual(
os.path.realpath(self.endfile), os.path.realpath(self.startfile)
)

def test_delete_existing_file_before_mkdir(self):
with open(self.startfile, "w") as f:
Expand Down
2 changes: 1 addition & 1 deletion pelican/tools/pelican_quickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import argparse
import locale
import os
from typing import Mapping
from collections.abc import Mapping

from jinja2 import Environment, FileSystemLoader

Expand Down
11 changes: 4 additions & 7 deletions pelican/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import sys
import traceback
import urllib
from collections.abc import Hashable
from collections.abc import Collection, Generator, Hashable, Iterable, Sequence
from contextlib import contextmanager
from functools import partial
from html import entities
Expand All @@ -22,10 +22,6 @@
TYPE_CHECKING,
Any,
Callable,
Collection,
Generator,
Iterable,
Sequence,
)

import dateutil.parser
Expand Down Expand Up @@ -133,8 +129,9 @@ def __init__(self) -> None:
def __call__(self, date: datetime.datetime, date_format: str) -> str:
# on OSX, encoding from LC_CTYPE determines the unicode output in PY3
# make sure it's same as LC_TIME
with temporary_locale(self.locale, locale.LC_TIME), temporary_locale(
self.locale, locale.LC_CTYPE
with (
temporary_locale(self.locale, locale.LC_TIME),
temporary_locale(self.locale, locale.LC_CTYPE),
):
formatted = strftime(date, date_format)

Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ classifiers = [
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Content Management System",
"Topic :: Internet :: WWW/HTTP :: Site Management",
Expand All @@ -27,7 +27,7 @@ classifiers = [
"Topic :: Text Processing :: Markup :: HTML",
"Topic :: Text Processing :: Markup :: reStructuredText",
]
requires-python = ">=3.8.1,<4.0"
requires-python = ">=3.9,<4.0"
dependencies = [
"blinker>=1.7.0",
"docutils>=0.20.1",
Expand All @@ -38,7 +38,6 @@ dependencies = [
"python-dateutil>=2.8.2",
"rich>=13.6.0",
"unidecode>=1.3.7",
"backports-zoneinfo>=0.2.1; python_version < \"3.9\"",
"watchfiles>=0.21.0",
"tzdata; sys_platform == 'win32'",
]
Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[tox]
envlist = py{3.8,3.9,3.10,3.11,3.12},docs
envlist = py{3.9,3.10,3.11,3.12,3.13},docs

[testenv]
basepython =
py3.8: python3.8
py3.9: python3.9
py3.10: python3.10
py3.11: python3.11
py3.12: python3.12
py3.13: python3.13
passenv = *
usedevelop=True
deps =
Expand Down
Loading