Skip to content

Commit

Permalink
Ruff: Stricter linting rules (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
tony committed Jul 4, 2023
2 parents e424edc + eec8afe commit dcb995a
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pytest-doctest-docutils:

### Infrastructure

- Ruff (additional linting rules): Added in #20
- CI: docutils testgrid (#16)
- CI speedups (#13)

Expand Down
9 changes: 5 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,7 @@
}


def linkcode_resolve(
domain: str, info: t.Dict[str, str]
) -> t.Union[None, str]: # NOQA: C901
def linkcode_resolve(domain: str, info: t.Dict[str, str]) -> t.Union[None, str]:
"""
Determine the URL corresponding to Python object
Expand Down Expand Up @@ -250,7 +248,10 @@ def remove_tabs_js(app: "Sphinx", exc: Exception) -> None:
# Fix for sphinx-inline-tabs#18
if app.builder.format == "html" and not exc:
tabs_js = Path(app.builder.outdir) / "_static" / "tabs.js"
tabs_js.unlink(missing_ok=True)
try:
tabs_js.unlink() # When python 3.7 deprecated, use missing_ok=True
except FileNotFoundError:
pass


def setup(app: "Sphinx") -> None:
Expand Down
32 changes: 32 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,38 @@ files = [
"tests/",
]

[tool.ruff]
target-version = "py37"
select = [
"E", # pycodestyle
"F", # pyflakes
"I", # isort
"UP", # pyupgrade
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"Q", # flake8-quotes
"PTH", # flake8-use-pathlib
"ERA", # eradicate
"SIM", # flake8-simplify
"TRY", # Trycertatops
"PERF", # Perflint
"RUF" # Ruff-specific rules
]

[tool.ruff.isort]
known-first-party = [
"src",
"doctest_document",
"docutils_compat",
"gp_libs",
"linkify_issues",
"pytest_doctest_docutils"
]
combine-as-imports = true

[tool.ruff.per-file-ignores]
"*/__init__.py" = ["F401"]

[build-system]
requires = ["poetry_core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
31 changes: 16 additions & 15 deletions src/doctest_docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ def run(self) -> t.List[Node]:


class TestsetupDirective(TestDirective):
option_spec: OptionSpec = {"skipif": directives.unchanged_required}
option_spec: t.ClassVar[OptionSpec] = {"skipif": directives.unchanged_required}


class TestcleanupDirective(TestDirective):
option_spec: OptionSpec = {"skipif": directives.unchanged_required}
option_spec: t.ClassVar[OptionSpec] = {"skipif": directives.unchanged_required}


class DoctestDirective(TestDirective):
option_spec: OptionSpec = {
option_spec: t.ClassVar[OptionSpec] = {
"hide": directives.flag,
"no-trim-doctest-flags": directives.flag,
"options": directives.unchanged,
Expand Down Expand Up @@ -230,7 +230,7 @@ def find(
if name is None:
raise ValueError(
"DocTestFinder.find: name must be given "
"when string.__name__ doesn't exist: %r" % (type(string),)
"when string.__name__ doesn't exist: {!r}".format(type(string))
)

# No access to a loader, so assume it's a normal
Expand All @@ -240,10 +240,7 @@ def find(
source_lines = None

# Initialize globals, and merge in extraglobs.
if globs is None:
globs = {}
else:
globs = globs.copy()
globs = {} if globs is None else globs.copy()
if extraglobs is not None:
globs.update(extraglobs)
if "__name__" not in globs:
Expand Down Expand Up @@ -346,7 +343,7 @@ def condition(node: Node) -> bool:
test_name = node.get("groups")
if isinstance(test_name, list):
test_name = test_name[0]
if test_name is None or "default" == test_name:
if test_name is None or test_name == "default":
test_name = f"{name}[{idx}]"
logger.debug(f"() node: {test_name}")
test = self._get_test(
Expand Down Expand Up @@ -377,6 +374,13 @@ def _get_test(
return self._parser.get_doctest(string, globs, name, filename, lineno)


class TestDocutilsPackageRelativeError(Exception):
def __init__(self) -> None:
return super().__init__(
"Package may only be specified for module-relative paths."
)


def testdocutils(
filename: str,
module_relative: bool = True,
Expand All @@ -398,7 +402,7 @@ def testdocutils(
global master

if package and not module_relative:
raise ValueError("Package may only be specified for module-" "relative paths.")
raise TestDocutilsPackageRelativeError()

# Keep the absolute file paths. This is needed for Include directies to work.
# The absolute path will be applied to source_path when creating the docutils doc.
Expand All @@ -408,13 +412,10 @@ def testdocutils(

# If no name was given, then use the file's name.
if name is None:
name = os.path.basename(filename)
name = pathlib.Path(filename).stem

# Assemble the globals.
if globs is None:
globs = {}
else:
globs = globs.copy()
globs = {} if globs is None else globs.copy()
if extraglobs is not None:
globs.update(extraglobs)
if "__name__" not in globs:
Expand Down
9 changes: 2 additions & 7 deletions src/pytest_doctest_docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
from pathlib import Path
from typing import TYPE_CHECKING, Any, Iterable, Optional, Tuple, Type

import pytest

import _pytest
import pytest
from _pytest import outcomes
from _pytest.outcomes import OutcomeException

from doctest_docutils import DocutilsDocTestFinder, setup

if TYPE_CHECKING:
Expand Down Expand Up @@ -97,10 +95,7 @@ def _is_doctest(config: pytest.Config, path: Path, parent: pytest.Collector) ->
if path.suffix in (".rst", ".md") and parent.session.isinitpath(path):
return True
globs = config.getoption("doctestglob") or ["*.rst", "*.md"]
for glob in globs:
if path.match(path_pattern=glob):
return True
return False
return any(path.match(path_pattern=glob) for glob in globs)


def _init_runner_class() -> Type["doctest.DocTestRunner"]:
Expand Down
1 change: 0 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import typing as t

import pytest

from sphinx.testing.path import path as sphinx_path

pytest_plugins = ["sphinx.testing.fixtures", "pytester"]
Expand Down
12 changes: 7 additions & 5 deletions tests/test_doctest_docutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import textwrap
import typing as t

import pytest

import doctest_docutils
import pytest

FixtureFileDict = t.Dict[str, str]

Expand Down Expand Up @@ -185,6 +184,11 @@ class DocTestFinderFixture(t.NamedTuple):
]


class FilePathModeNotImplemented(Exception):
def __init__(self, file_path_mode: str) -> None:
return super().__init__(f"No file_path_mode supported for {file_path_mode}")


@pytest.mark.parametrize(
DocTestFinderFixture._fields, FIXTURES, ids=[f.test_id for f in FIXTURES]
)
Expand All @@ -204,9 +208,8 @@ def test_DocutilsDocTestFinder(
if file_path_mode == "absolute":
first_test_filename = str(tests_path / first_test_filename)
elif file_path_mode != "relative":
raise NotImplementedError(f"No file_path_mode supported for {file_path_mode}")
raise FilePathModeNotImplemented(file_path_mode)

# Setup: Files
tests_path.mkdir()
for file_name, text in files.items():
rst_file = tests_path / file_name
Expand All @@ -215,7 +218,6 @@ def test_DocutilsDocTestFinder(
encoding="utf-8",
)

# Setup: Environment
if file_path_mode == "relative":
monkeypatch.chdir(tests_path)

Expand Down
1 change: 0 additions & 1 deletion tests/test_linkify_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import typing as t

import pytest

from sphinx.testing.util import SphinxTestApp

if t.TYPE_CHECKING:
Expand Down
9 changes: 4 additions & 5 deletions tests/test_pytest_doctest_docutils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import textwrap
import typing as t

import pytest

import _pytest.pytester
import pytest

FixtureFileDict = t.Dict[str, str]

Expand Down Expand Up @@ -216,7 +215,7 @@ def test_pluginDocutilsDocTestFinder(
first_test_key = list(files.keys())[0]
first_test_filename = str(tests_path / first_test_key)

# Setup: Files
# Setup Files
tests_path.mkdir()
for file_name, text in files.items():
rst_file = tests_path / file_name
Expand Down Expand Up @@ -284,7 +283,7 @@ def hello(statement: str) -> None:
first_test_key = list(files.keys())[0]
first_test_filename = str(tests_path / first_test_key)

# Setup: Files
# Setup Files
tests_path.mkdir()
for file_name, text in files.items():
rst_file = tests_path / file_name
Expand Down Expand Up @@ -376,7 +375,7 @@ def add(a: int, b: int) -> int:
first_test_key = list(files.keys())[0]
first_test_filename = str(tests_path / first_test_key)

# Setup: Files
# Setup Files
tests_path.mkdir()
for file_name, text in files.items():
md_file = tests_path / file_name
Expand Down

0 comments on commit dcb995a

Please sign in to comment.