-
Notifications
You must be signed in to change notification settings - Fork 9
MAINT: Update test suite for Python 3.11-3.13 and Sphinx 6-8 compatibility #79
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
Conversation
- Update pyproject.toml: require Python >=3.11, Sphinx >=6.1, matplotlib >=3.8 - Update tox.ini: add 9 test environments (py311/312/313 × sphinx6/7/8) - Fix deprecation warnings: - Use os.path.splitext() instead of string operations (RemovedInSphinx90Warning) - Update sphinx.util.console import path - Implement Sphinx-version-specific regression fixtures: - Generate separate .sphinx6/.sphinx7/.sphinx8 fixtures for HTML and XML - Track actual Sphinx output differences without filtering - Add ipykernel process ID normalization for test stability - All 110 tests pass across all 9 Python/Sphinx combinations
- Update CHANGELOG.md with v1.0.0 and v1.0.1 release information - Fix deprecated matplotlib.axes.Axes.cohere() API usage in test files - Change from positional args to keyword args (NFFT=, Fs=) - Eliminates MatplotlibDeprecationWarning from test output - Regenerate Sphinx 8 test fixtures to reflect corrected test code - All 110 tests passing with only external myst_nb warnings remaining
- Change from myst-nb~=1.0.0 to myst-nb>=1.1.0 - myst-nb v1.1.0+ uses Node.findall() instead of deprecated Node.traverse() - Eliminates PendingDeprecationWarning and RemovedInSphinx90Warning - All 110 tests pass with ZERO warnings
- Update fixtures to reflect myst-nb >=1.1.0 output (no warnings) - Remove MatplotlibDeprecationWarning from fixture files
- Similar to myst-nb update, the ~=8.0.0 constraint was locking pytest to 8.0.x - Latest pytest is 8.4.2 with bug fixes and improvements - All 110 tests passing with pytest 8.4.2
- Fix E402: Move sphinx.locale import to top of file in nodes.py - Add newline at end of MANIFEST.in - Apply ruff-format line wrapping for long lines
Matplotlib generates platform/version-specific content hashes for images. This causes test failures when comparing fixtures generated on different platforms (macOS vs Linux) or with different package versions. Solution: Add regex pattern to FileRegression to normalize all matplotlib image hashes to 'IMAGEHASH.png', making tests platform-independent. Fixes CI test failures in test_gateddirective.py.
Match CI test matrix to tox configuration: - Python versions: 3.11, 3.12, 3.13 - Sphinx versions: 6, 7, 8 - Total: 9 test combinations This ensures CI tests the same environments as local tox testing, providing better coverage and catching version-specific issues.
The function strip_escape_sequences was removed from sphinx.util.console in later versions. Add try/except import with fallback implementation. Also update tox.ini to properly install Sphinx version-specific dependencies by explicitly listing all testing dependencies in deps rather than using the 'testing' extra which includes a broad Sphinx version range. Fixes CI failure on Python 3.13 + Sphinx 6 combination.
Use constrain_package_deps and use_frozen_constraints to ensure that the Sphinx version specified in tox deps takes precedence over the package's own dependency declaration (sphinx>=6.1). This creates a constraints file that locks the Sphinx version during package dependency installation, preventing pip from upgrading to the latest version. Verified working: - py311-sphinx6: Sphinx 6.2.1 - py311-sphinx7: Sphinx 7.4.7 - py311-sphinx8: Sphinx 8.2.3
Now that constrain_package_deps is working correctly, we can use the 'testing' extras from pyproject.toml instead of manually listing all dependencies. This is more maintainable - when testing dependencies change in pyproject.toml, they automatically apply to tox without needing to update both files. The constraints mechanism ensures Sphinx version from deps still takes precedence over the package's sphinx>=6.1,<9 requirement.
The sphinx.testing.path.path object in Sphinx <7.2 doesn't have an .absolute() method. The path is already absolute, so we can use it directly without calling .absolute(). This fixes the AttributeError: 'path' object has no attribute 'absolute' error that was causing all 110 tests to fail on Sphinx 6. The version check ensures Sphinx 7.2+ continues to use pathlib.Path with .absolute() as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR modernizes the test suite to support Python 3.11-3.13 and Sphinx 6-8, eliminating deprecation warnings and updating dependencies for better compatibility.
- Updates Python support from 3.9-3.10 to 3.11-3.13
- Updates Sphinx support from 5-7 to 6.1-8
- Implements version-specific test fixtures to handle Sphinx output differences
- Fixes deprecated API usage in Sphinx and matplotlib
Reviewed Changes
Copilot reviewed 154 out of 155 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Updates Python version requirements (3.11+), Sphinx constraints (6.1-8), and dependency version ranges |
| tox.ini | Configures test matrix for 3 Python versions × 3 Sphinx versions (9 environments) |
| .github/workflows/ci.yml | Updates CI matrix to test Python 3.11-3.13 with Sphinx 6-8 |
| tests/conftest.py | Adds regex patterns for normalizing image hashes and process IDs in test fixtures |
| tests/test_*.py | Adds SPHINX_VERSION fixture support and version-specific test file extensions |
| tests/test_gateddirective.py | Adds fallback for deprecated strip_escape_sequences function |
| tests/books/test-gateddirective/*.md | Updates matplotlib cohere() calls to use keyword arguments |
| sphinx_exercise/*.py | Minor code formatting improvements and import organization |
| tests/test_/.sphinx{6,7,8}.{html,xml} | Adds version-specific test fixtures for Sphinx 6, 7, and 8 |
| CHANGELOG.md | Documents v1.0.0 and v1.0.1 releases |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
sphinx_exercise/directive.py
Outdated
| :licences: see LICENSE for details | ||
| """ | ||
|
|
||
| import os |
Copilot
AI
Oct 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The os import is added but only used for os.path.splitext(). Consider using pathlib.Path instead for consistency with modern Python practices, or document why os.path is preferred here.
sphinx_exercise/post_transforms.py
Outdated
| docname = self.env.docname # for builder such as JupyterBuilder that don't support current_docname | ||
| docpath = self.env.doc2path(docname) | ||
| path = docpath[: docpath.rfind(".")] | ||
| path = os.path.splitext(docpath)[0] |
Copilot
AI
Oct 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] While os.path.splitext() works correctly, the previous implementation using string slicing with rfind(".") would fail on paths without extensions. This change is an improvement, but consider using pathlib.Path(docpath).stem for a more robust solution.
Use pathlib.Path.with_suffix('') instead of os.path.splitext()[0] for
better consistency with modern Python practices. This removes the os
import which was only used for this single operation.
Modernize all remaining os.path operations to use pathlib.Path for
consistency:
- sphinx_exercise/__init__.py: Use Path for package/locale directory
- sphinx_exercise/post_transforms.py: Use Path.with_suffix('')
- sphinx_exercise/translations/_convert.py: Use Path.resolve()
This completes the migration to pathlib throughout the codebase,
keeping only os.sep in tests where it's appropriate for path
separator normalization.
|
Hi, I maintain the conda forge recipe for this package and conda forge builds for all non-end-of-life Python versions in general. Python 3.10 still has a year of life left. If you can support Python 3.10, that is helpful for downstream users. |
Thanks @moorepants -- appreciate the info. I'll try to get a |
Summary
Modernizes the test suite to support Python 3.11-3.13 and Sphinx 6-8, eliminating all deprecation warnings and updating dependency constraints.
Changes
Python & Sphinx Support
Deprecation Fixes
Node.traverse()→Node.findall()(Sphinx 8 deprecation)Path→os.fspath(Path)for path handlingcohere()positional → keyword argumentsDependency Updates
~=1.0.0→>=1.1.0(enables v1.3.0 with deprecation fixes)~=8.0.0→>=8.0(enables v8.4.2 with improvements)>=3.7→>=3.8Test Infrastructure
.sphinx6,.sphinx7,.sphinx8)SPHINX_VERSIONfixture in conftest.pyDocumentation
Test Results
✅ All 110 tests passing across 9 environments
✅ Zero warnings from all sources (sphinx, myst-nb, matplotlib, pytest)