Skip to content

Commit

Permalink
Use pathlib in the tests (#13051)
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner authored Oct 25, 2024
1 parent 63a4175 commit 71c0fcf
Show file tree
Hide file tree
Showing 17 changed files with 59 additions and 65 deletions.
16 changes: 11 additions & 5 deletions sphinx/directives/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util._lines import parse_line_num_spec
from sphinx.util._pathlib import _StrPath
from sphinx.util.docutils import SphinxDirective

if TYPE_CHECKING:
import os

from docutils.nodes import Element, Node

from sphinx.application import Sphinx
Expand Down Expand Up @@ -197,8 +200,10 @@ class LiteralIncludeReader:
('diff', 'end-at'),
]

def __init__(self, filename: str, options: dict[str, Any], config: Config) -> None:
self.filename = filename
def __init__(
self, filename: str | os.PathLike[str], options: dict[str, Any], config: Config
) -> None:
self.filename = _StrPath(filename)
self.options = options
self.encoding = options.get('encoding', config.source_encoding)
self.lineno_start = self.options.get('lineno-start', 1)
Expand All @@ -212,8 +217,9 @@ def parse_options(self) -> None:
raise ValueError(msg)

def read_file(
self, filename: str, location: tuple[str, int] | None = None
self, filename: str | os.PathLike[str], location: tuple[str, int] | None = None
) -> list[str]:
filename = _StrPath(filename)
try:
with open(filename, encoding=self.encoding, errors='strict') as f:
text = f.read()
Expand All @@ -222,11 +228,11 @@ def read_file(

return text.splitlines(True)
except OSError as exc:
msg = __('Include file %r not found or reading it failed') % filename
msg = __("Include file '%s' not found or reading it failed") % filename
raise OSError(msg) from exc
except UnicodeError as exc:
msg = __(
'Encoding %r used for reading included file %r seems to '
"Encoding %r used for reading included file '%s' seems to "
'be wrong, try giving an :encoding: option'
) % (self.encoding, filename)
raise UnicodeError(msg) from exc
Expand Down
15 changes: 10 additions & 5 deletions sphinx/pycode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

from __future__ import annotations

import os
import tokenize
from importlib import import_module
from os import path
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Literal

from sphinx.errors import PycodeError
from sphinx.pycode.parser import Parser
from sphinx.util._pathlib import _StrPath

if TYPE_CHECKING:
from inspect import Signature
Expand All @@ -23,7 +25,7 @@ class ModuleAnalyzer:
tags: dict[str, tuple[str, int, int]]

# cache for analyzer objects -- caches both by module and file name
cache: dict[tuple[str, str], Any] = {}
cache: dict[tuple[Literal['file', 'module'], str | _StrPath], Any] = {}

@staticmethod
def get_module_source(modname: str) -> tuple[str | None, str | None]:
Expand Down Expand Up @@ -81,8 +83,9 @@ def for_string(

@classmethod
def for_file(
cls: type[ModuleAnalyzer], filename: str, modname: str
cls: type[ModuleAnalyzer], filename: str | os.PathLike[str], modname: str
) -> ModuleAnalyzer:
filename = _StrPath(filename)
if ('file', filename) in cls.cache:
return cls.cache['file', filename]
try:
Expand Down Expand Up @@ -114,9 +117,11 @@ def for_module(cls: type[ModuleAnalyzer], modname: str) -> ModuleAnalyzer:
cls.cache['module', modname] = obj
return obj

def __init__(self, source: str, modname: str, srcname: str) -> None:
def __init__(
self, source: str, modname: str, srcname: str | os.PathLike[str]
) -> None:
self.modname = modname # name of the module
self.srcname = srcname # name of the source file
self.srcname = str(srcname) # name of the source file

# cache the source code as well
self.code = source
Expand Down
8 changes: 3 additions & 5 deletions tests/roots/test-apidoc-toc/mypackage/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#!/usr/bin/env python3

import os
from pathlib import Path

import mod_resource
import mod_something

if __name__ == "__main__":
print(f"Hello, world! -> something returns: {mod_something.something()}")

res_path = \
os.path.join(os.path.dirname(mod_resource.__file__), 'resource.txt')
with open(res_path, encoding='utf-8') as f:
text = f.read()
res_path = Path(mod_resource.__file__).parent / 'resource.txt'
text = res_path.read_text(encoding='utf-8')
print(f"From mod_resource:resource.txt -> {text}")
5 changes: 0 additions & 5 deletions tests/roots/test-theming/test_theme/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
import os


def get_path():
return os.path.dirname(os.path.abspath(__file__))
4 changes: 2 additions & 2 deletions tests/test_builders/test_build_epub.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ def test_run_epubcheck(app):
if not runnable(['java', '-version']):
pytest.skip('Unable to run Java; skipping test')

epubcheck = os.environ.get('EPUBCHECK_PATH', '/usr/share/java/epubcheck.jar')
if not os.path.exists(epubcheck):
epubcheck = Path(os.environ.get('EPUBCHECK_PATH', '/usr/share/java/epubcheck.jar'))
if not epubcheck.exists():
pytest.skip('Could not find epubcheck; skipping test')

try:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_builders/test_build_gettext.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Test the build process with gettext builder with the test root."""

import gettext
import os
import re
import subprocess
from contextlib import chdir
from pathlib import Path
from subprocess import CalledProcessError

import pytest
Expand Down Expand Up @@ -94,7 +94,7 @@ def test_msgfmt(app):
'msgfmt',
'en_US.po',
'-o',
os.path.join('en', 'LC_MESSAGES', 'test_root.mo'),
Path('en', 'LC_MESSAGES', 'test_root.mo'),
]
subprocess.run(args, capture_output=True, check=True)
except OSError:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_command_line.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

import os.path
import sys
from pathlib import Path
from typing import Any

import pytest
Expand Down Expand Up @@ -52,8 +52,8 @@
EXPECTED_MAKE_MODE = {
'builder': 'html',
'sourcedir': 'source_dir',
'outputdir': os.path.join('build_dir', 'html'),
'doctreedir': os.path.join('build_dir', 'doctrees'),
'outputdir': str(Path('build_dir', 'html')),
'doctreedir': str(Path('build_dir', 'doctrees')),
'filenames': ['filename1', 'filename2'],
'freshenv': True,
'noconfig': True,
Expand Down
9 changes: 4 additions & 5 deletions tests/test_directives/test_directive_code.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Test the code-block directive."""

import os.path

import pytest
from docutils import nodes

Expand Down Expand Up @@ -257,12 +255,13 @@ def test_LiteralIncludeReader_tabwidth_dedent(testroot):


def test_LiteralIncludeReader_diff(testroot, literal_inc_path):
options = {'diff': testroot / 'literal-diff.inc'}
literal_diff_path = testroot / 'literal-diff.inc'
options = {'diff': literal_diff_path}
reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG)
content, lines = reader.read()
assert content == (
'--- ' + os.path.join(testroot, 'literal-diff.inc') + '\n'
'+++ ' + os.path.join(testroot, 'literal.inc') + '\n'
f'--- {literal_diff_path}\n'
f'+++ {literal_inc_path}\n'
'@@ -6,8 +6,8 @@\n'
' pass\n'
' \n'
Expand Down
5 changes: 2 additions & 3 deletions tests/test_environment/test_environment.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Test the BuildEnvironment class."""

import os
import shutil
from pathlib import Path

Expand Down Expand Up @@ -41,8 +40,8 @@ def test_config_status(make_app, app_params):

# incremental build (config entry changed)
app3 = make_app(*args, confoverrides={'root_doc': 'indexx'}, **kwargs)
fname = os.path.join(app3.srcdir, 'index.rst')
assert os.path.isfile(fname)
fname = app3.srcdir / 'index.rst'
assert fname.is_file()
shutil.move(fname, fname[:-4] + 'x.rst')
assert app3.env.config_status == CONFIG_CHANGED
app3.build()
Expand Down
3 changes: 1 addition & 2 deletions tests/test_extensions/test_ext_apidoc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Test the sphinx.apidoc module."""

import os.path
from collections import namedtuple
from pathlib import Path

Expand Down Expand Up @@ -732,7 +731,7 @@ def test_no_duplicates(rootdir, tmp_path):
apidoc_main(['-o', str(outdir), '-T', str(package), '--implicit-namespaces'])

# Ensure the module has been documented
assert os.path.isfile(outdir / 'fish_licence.rst')
assert (outdir / 'fish_licence.rst').is_file()

# Ensure the submodule only appears once
text = (outdir / 'fish_licence.rst').read_text(encoding='utf-8')
Expand Down
4 changes: 3 additions & 1 deletion tests/test_extensions/test_ext_autodoc_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import platform
import sys
from collections.abc import Iterator
from contextlib import contextmanager
from pathlib import Path

import pytest

Expand All @@ -19,7 +21,7 @@


@contextmanager
def overwrite_file(path, content):
def overwrite_file(path: Path, content: str) -> Iterator[None]:
current_content = path.read_bytes() if path.exists() else None
try:
path.write_text(content, encoding='utf-8')
Expand Down
4 changes: 2 additions & 2 deletions tests/test_extensions/test_ext_inheritance_diagram.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Test sphinx.ext.inheritance_diagram extension."""

import os
import re
import sys
import zlib
from pathlib import Path

import pytest

Expand All @@ -26,7 +26,7 @@ def test_inheritance_diagram(app):
def new_run(self):
result = orig_run(self)
node = result[0]
source = os.path.basename(node.document.current_source).replace('.rst', '')
source = Path(node.document.current_source).stem
graphs[source] = node['graph']
return result

Expand Down
1 change: 0 additions & 1 deletion tests/test_intl/test_intl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""

import os
import os.path
import re
import shutil
import time
Expand Down
6 changes: 3 additions & 3 deletions tests/test_pycode/test_pycode.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""Test pycode."""

import os
import sys
from pathlib import Path

import pytest

import sphinx
from sphinx.errors import PycodeError
from sphinx.pycode import ModuleAnalyzer

SPHINX_MODULE_PATH = os.path.splitext(sphinx.__file__)[0] + '.py'
SPHINX_MODULE_PATH = Path(sphinx.__file__).resolve().with_suffix('.py')


def test_ModuleAnalyzer_get_module_source():
Expand Down Expand Up @@ -40,7 +40,7 @@ def test_ModuleAnalyzer_for_file():
def test_ModuleAnalyzer_for_module(rootdir):
analyzer = ModuleAnalyzer.for_module('sphinx')
assert analyzer.modname == 'sphinx'
assert analyzer.srcname in {SPHINX_MODULE_PATH, os.path.abspath(SPHINX_MODULE_PATH)}
assert analyzer.srcname == str(SPHINX_MODULE_PATH)

saved_path = sys.path.copy()
sys.path.insert(0, str(rootdir / 'test-pycode'))
Expand Down
6 changes: 1 addition & 5 deletions tests/test_quickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import time
from collections.abc import Callable
from io import StringIO
from os import path
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -260,10 +259,7 @@ def test_extensions(tmp_path):
def test_exits_when_existing_confpy(monkeypatch):
# The code detects existing conf.py with path.is_file()
# so we mock it as True with pytest's monkeypatch
def mock_isfile(path):
return True

monkeypatch.setattr(path, 'isfile', mock_isfile)
monkeypatch.setattr('os.path.isfile', lambda path: True)

qs.term_input = mock_input({
'Please enter a new root path (or just Enter to exit)': '',
Expand Down
16 changes: 6 additions & 10 deletions tests/test_util/test_util.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
"""Tests util functions."""

import os
import tempfile

from sphinx.util.osutil import ensuredir


def test_ensuredir():
with tempfile.TemporaryDirectory() as tmp_path:
# Does not raise an exception for an existing directory.
ensuredir(tmp_path)
def test_ensuredir(tmp_path):
# Does not raise an exception for an existing directory.
ensuredir(tmp_path)

path = os.path.join(tmp_path, 'a', 'b', 'c')
ensuredir(path)
assert os.path.isdir(path)
path = tmp_path / 'a' / 'b' / 'c'
ensuredir(path)
assert path.is_dir()
12 changes: 6 additions & 6 deletions tests/test_util/test_util_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import codecs
import os
import os.path
from pathlib import Path

import pytest
from docutils import nodes

from sphinx.util import logging, osutil
from sphinx.util import logging
from sphinx.util.console import colorize, strip_colors
from sphinx.util.logging import is_suppressed_warning, prefixed_warnings
from sphinx.util.parallel import ParallelTasks
Expand Down Expand Up @@ -360,15 +360,15 @@ def test_get_node_location_abspath():
# Ensure that node locations are reported as an absolute path,
# even if the source attribute is a relative path.

relative_filename = os.path.join('relative', 'path.txt')
absolute_filename = osutil.abspath(relative_filename)
relative_filename = Path('relative', 'path.txt')
absolute_filename = relative_filename.resolve()

n = nodes.Node()
n.source = relative_filename
n.source = str(relative_filename)

location = logging.get_node_location(n)

assert location == absolute_filename + ':'
assert location == f'{absolute_filename}:'


@pytest.mark.sphinx('html', testroot='root', confoverrides={'show_warning_types': True})
Expand Down

0 comments on commit 71c0fcf

Please sign in to comment.