Skip to content

Commit 53c0a6b

Browse files
authored
Restore Python 3.10 support (#80)
* Restore Python 3.10 support with version-specific Sphinx 8 handling - Add Python 3.10 support back (removed in v1.1.0, EOL October 2026) - Update test matrix to 11 environments (exclude py313-sphinx6 due to deprecation warnings) - Implement version-specific Sphinx 8 constraints in tox.ini: * Python 3.10 limited to Sphinx 8.1.x (max 8.1.3) * Python 3.11+ uses Sphinx 8.2+ (Sphinx 8.2.0+ requires Python >=3.11) - Add version detection logic to test files for fixture selection - Create .sphinx8.1 fixtures for Python 3.10/Sphinx 8.1.x compatibility - Update CI workflow to include Python 3.10 in test matrix - Document changes in CHANGELOG.md with version limitations * Update codecov to use Python 3.12 and Sphinx 8 * Use tokenless codecov upload for public repository - Remove token requirement (codecov-action@v4 supports tokenless uploads for public repos) - Set fail_ci_if_error to false to prevent CI failures if codecov has issues - Keep codecov running on all events including PRs * Prepare v1.1.1 release - Update version to 1.1.1 in __init__.py - Finalize CHANGELOG with v1.1.1 entry - Add comprehensive v1.1.1 release notes - Update releases documentation index This patch release restores Python 3.10 support with full test coverage across Python 3.10-3.13 and Sphinx 6-8.
1 parent 73aee15 commit 53c0a6b

File tree

58 files changed

+1159
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1159
-20
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ jobs:
2323
runs-on: ubuntu-latest
2424
strategy:
2525
matrix:
26-
python-version: ["3.11", "3.12", "3.13"]
26+
python-version: ["3.10", "3.11", "3.12", "3.13"]
2727
sphinx-version: ["6", "7", "8"]
28+
exclude:
29+
# Python 3.13 with Sphinx 6 generates many deprecation warnings
30+
# from Sphinx's use of deprecated datetime methods. Unlikely combination.
31+
- python-version: "3.13"
32+
sphinx-version: "6"
2833
steps:
2934
- uses: actions/checkout@v4
3035
- name: Set up Python ${{ matrix.python-version }}
@@ -42,24 +47,23 @@ jobs:
4247
- name: Create cov
4348
run: coverage xml
4449
- name: Upload to Codecov
45-
if: false && (matrix.python-version == '3.11' && matrix.sphinx-version == '8')
50+
if: matrix.python-version == '3.12' && matrix.sphinx-version == '8'
4651
uses: codecov/codecov-action@v4
4752
with:
48-
name: sphinx-exercise-pytest-py3.11-sphinx8
49-
token: "${{ secrets.CODECOV_TOKEN }}"
53+
name: sphinx-exercise-pytest-py3.12-sphinx8
5054
flags: pytests
5155
file: ./coverage.xml
52-
fail_ci_if_error: true
56+
fail_ci_if_error: false
5357

5458
docs:
5559
name: Documentation build
5660
runs-on: ubuntu-latest
5761
steps:
5862
- uses: actions/checkout@v4
59-
- name: Set up Python 3.11
63+
- name: Set up Python 3.10
6064
uses: actions/setup-python@v4
6165
with:
62-
python-version: "3.11"
66+
python-version: "3.10"
6367
- name: Install dependencies
6468
run: |
6569
python -m pip install --upgrade pip
@@ -78,10 +82,10 @@ jobs:
7882
steps:
7983
- name: Checkout source
8084
uses: actions/checkout@v4
81-
- name: Set up Python 3.11
85+
- name: Set up Python 3.10
8286
uses: actions/setup-python@v4
8387
with:
84-
python-version: "3.11"
88+
python-version: "3.10"
8589
- name: Build package
8690
run: |
8791
pip install wheel build

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [Unreleased]
4+
5+
## [v1.1.1](https://github.com/executablebooks/sphinx-exercise/tree/v1.1.1) (2025-10-23)
6+
7+
### Improved 👌
8+
9+
- **Restored Python 3.10 support** - Re-added compatibility with Python 3.10 as it remains actively supported until October 2026
10+
- Updated test matrix to include Python 3.10 with Sphinx 6, 7, and 8
11+
- Test matrix now covers 11 combinations (excludes Python 3.13 + Sphinx 6 due to deprecation warnings)
12+
- **Note**: Python 3.10 is limited to Sphinx 8.1.x (max 8.1.3) due to Sphinx 8.2+ requiring Python >=3.11. This is handled automatically in the test configuration.
13+
- Updated codecov integration to use Python 3.12 + Sphinx 8 baseline
14+
- Configured tokenless codecov uploads for public repository
15+
316
## [v1.1.0](https://github.com/executablebooks/sphinx-exercise/tree/v1.1.0) (2025-10-22)
417

518
### New ✨

docs/source/releases/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This section contains detailed release notes for sphinx-exercise versions.
55
```{toctree}
66
:maxdepth: 1
77
8+
v1.1.1
89
v1.1.0
910
```
1011

docs/source/releases/v1.1.1.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Release v1.1.1
2+
3+
**Release Date**: October 23, 2025
4+
5+
This is a patch release that restores Python 3.10 compatibility while maintaining support for newer Python versions.
6+
7+
## 👌 Improvements
8+
9+
### Python 3.10 Support Restored
10+
11+
Python 3.10 support has been re-added to the project. Python 3.10 remains actively supported until October 2026, making it an important version to maintain compatibility with.
12+
13+
**Key details:**
14+
- Python 3.10 is now fully supported alongside Python 3.11, 3.12, and 3.13
15+
- All existing features work identically across all supported Python versions
16+
- Comprehensive test coverage ensures compatibility
17+
18+
### Technical Implementation
19+
20+
**Version-Specific Sphinx Constraints:**
21+
- Python 3.10 is limited to **Sphinx 8.1.x** (maximum 8.1.3)
22+
- Python 3.11+ continues to use **Sphinx 8.2+** as normal
23+
- This constraint exists because Sphinx 8.2.0+ requires Python >=3.11
24+
25+
The test infrastructure automatically handles these version-specific requirements, ensuring correct behavior across all combinations.
26+
27+
### Test Matrix Updates
28+
29+
**Supported Combinations:**
30+
- Python 3.10, 3.11, 3.12: Sphinx 6, 7, 8
31+
- Python 3.13: Sphinx 7, 8
32+
33+
**Total: 11 test environments** (excludes Python 3.13 + Sphinx 6)
34+
35+
Python 3.13 + Sphinx 6 was excluded because Sphinx 6.2.1 generates 1870+ deprecation warnings on Python 3.13 due to its use of deprecated `datetime.utcfromtimestamp()`. This is an unlikely real-world combination.
36+
37+
### CI/CD Improvements
38+
39+
- Updated GitHub Actions CI matrix to include Python 3.10
40+
- Configured codecov to use Python 3.12 + Sphinx 8 as baseline
41+
- Implemented tokenless codecov uploads for public repository
42+
- Added version-specific test fixtures for Sphinx 8.1 vs 8.2+ compatibility
43+
44+
## 📦 Installation
45+
46+
Install or upgrade via pip:
47+
48+
```bash
49+
pip install --upgrade sphinx-exercise
50+
```
51+
52+
## 🔄 Migration Notes
53+
54+
**If you're upgrading from v1.1.0:**
55+
- No breaking changes
56+
- No action required
57+
- Python 3.10 users can now upgrade safely
58+
59+
**If you're on Python 3.10:**
60+
- You can now use sphinx-exercise v1.1.1
61+
- Sphinx 8 support is limited to 8.1.x on Python 3.10
62+
- All features work identically to newer Python versions
63+
64+
## 🐛 Bug Fixes
65+
66+
- Fixed test fixtures to handle Sphinx 8.1.x vs 8.2+ XML output differences
67+
- Ensured consistent test behavior across all Python/Sphinx combinations
68+
69+
## 📝 Full Changelog
70+
71+
For complete details, see the [CHANGELOG.md](https://github.com/executablebooks/sphinx-exercise/blob/main/CHANGELOG.md).
72+
73+
## 🙏 Acknowledgments
74+
75+
Thank you to all contributors and users who reported the need for Python 3.10 support!

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ dynamic = ["version"]
88
description = "A Sphinx extension for producing exercises and solutions."
99
readme = "README.md"
1010
license = { file = "LICENSE" }
11-
requires-python = ">=3.11"
11+
requires-python = ">=3.10"
1212
authors = [
1313
{ name = "QuantEcon", email = "[email protected]" },
1414
]
@@ -22,6 +22,7 @@ classifiers = [
2222
"Natural Language :: English",
2323
"Operating System :: OS Independent",
2424
"Programming Language :: Python",
25+
"Programming Language :: Python :: 3.10",
2526
"Programming Language :: Python :: 3.11",
2627
"Programming Language :: Python :: 3.12",
2728
"Programming Language :: Python :: 3.13",

sphinx_exercise/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
:license: MIT, see LICENSE for details.
88
"""
99

10-
__version__ = "1.1.0"
10+
__version__ = "1.1.1"
1111

1212
from pathlib import Path
1313
from typing import Any, Dict, Set, Union, cast

tests/test_exercise_references.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
import pytest
33
import sphinx
44

5-
SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}"
5+
# Sphinx 8.1.x (Python 3.10 only) has different XML output than 8.2+
6+
# Use .sphinx8.1 for 8.1.x, .sphinx8 for 8.2+ (the standard)
7+
if sphinx.version_info[0] == 8 and sphinx.version_info[1] == 1:
8+
SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}.{sphinx.version_info[1]}"
9+
else:
10+
SPHINX_VERSION = f".sphinx{sphinx.version_info[0]}"
611

712

813
@pytest.mark.sphinx("html", testroot="mybook")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<p>This is a reference <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">Exercise 1</span></a>.</p>
2+
<p>This is a second reference <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some text 1</span></a>.</p>
3+
<p>This is a third reference <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some text 1</span></a>.</p>
4+
<p>This is a fourth reference <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some text Exercise</span></a>.</p>
5+
<p class="topless"><a href="_enum_numref_title.html" title="previous chapter">_enum_numref_title</a></p>
6+
<p class="topless"><a href="_unenum_mathtitle_label.html" title="next chapter">_unenum_mathtitle_label</a></p>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<p>This is a reference <a class="reference internal" href="_enum_notitle_label.html#text-exc-notitle"><span class="std std-numref">Exercise 2</span></a>.</p>
2+
<p>This is a second reference <a class="reference internal" href="_enum_notitle_label.html#text-exc-notitle"><span class="std std-numref">some text 2</span></a>.</p>
3+
<p>This is a third reference <a class="reference internal" href="_enum_notitle_label.html#text-exc-notitle"><span class="std std-numref">some text 2</span></a>.</p>
4+
<p>This is a fourth reference <a class="reference internal" href="_enum_notitle_label.html#text-exc-notitle"><span class="std std-numref">some text Exercise</span></a>.</p>
5+
<p class="topless"><a href="_enum_ref_mathtitle.html" title="previous chapter">_enum_ref_mathtitle</a></p>
6+
<p class="topless"><a href="_enum_numref_title.html" title="next chapter">_enum_numref_title</a></p>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<p>This reference does not include math <a class="reference internal" href="_enum_title_class_label.html#test-exc-label"><span class="std std-numref">some 3 text %s test Exercise</span></a>.</p>
2+
<p>This reference does not include math <a class="reference internal" href="_enum_title_class_label.html#test-exc-label"><span class="std std-numref">some 3 text %s test</span></a>.</p>
3+
<p>This reference does not include math <a class="reference internal" href="_enum_title_class_label.html#test-exc-label"><span class="std std-numref">some Exercise text %s test</span></a>.</p>
4+
<p>This reference does not include math <a class="reference internal" href="_enum_title_class_label.html#test-exc-label"><span class="std std-numref">some Exercise text 3 test</span></a>.</p>
5+
<p>This reference does not include math <a class="reference internal" href="_enum_title_class_label.html#test-exc-label"><span class="std std-numref">some 3 text test</span></a>.</p>
6+
<p>This reference includes math <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some 1 text %s test Exercise</span></a>.</p>
7+
<p>This reference includes math <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some 1 text %s test</span></a>.</p>
8+
<p>This reference includes math <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some Exercise text %s test</span></a>.</p>
9+
<p>This reference includes math <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some Exercise text 1 test</span></a>.</p>
10+
<p>This reference includes math <a class="reference internal" href="_enum_mathtitle_label.html#test-exc-label-math"><span class="std std-numref">some 1 text test</span></a>.</p>
11+
<p class="topless"><a href="_unenum_numref_mathtitle.html" title="previous chapter">_unenum_numref_mathtitle</a></p>
12+
<p class="topless"><a href="_enum_duplicate_label.html" title="next chapter">_enum_duplicate_label</a></p>

0 commit comments

Comments
 (0)